Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
Latest 1 from a total of 1 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x60806040 | 14710660 | 827 days ago | IN | 0 ETH | 0.1313389 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
LoanTokenLogicStandard
Compiler Version
v0.5.17+commit.d19bba13
Contract Source Code (Solidity Standard Json-Input format)
/** * Copyright 2017-2022, OokiDao. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity 0.5.17; pragma experimental ABIEncoderV2; import "AdvancedToken.sol"; import "StorageExtension.sol"; import "IBZx.sol"; import "IPriceFeeds.sol"; contract LoanTokenLogicStandard is AdvancedToken, StorageExtension { using SafeMath for uint256; using SignedSafeMath for int256; //// CONSTANTS //// uint256 public constant VERSION = 7; address internal constant arbitraryCaller = 0x000F400e6818158D541C3EBE45FE3AA0d47372FF; // mainnet //address internal constant arbitraryCaller = 0x81e7dddFAD37E6FAb0eccE95f0B508fd40996e6d; // bsc // address internal constant arbitraryCaller = 0x81e7dddFAD37E6FAb0eccE95f0B508fd40996e6d; // polygon // address internal constant arbitraryCaller = 0x01207468F48822f8535BC96D1Cf18EddDE4A2392; // arbitrum address public constant bZxContract = 0xD8Ee69652E4e4838f2531732a46d1f7F584F0b7f; // mainnet address public constant wethToken = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2; // mainnet //address public constant bZxContract = 0x5cfba2639a3db0D9Cc264Aa27B2E6d134EeA486a; // kovan //address public constant wethToken = 0xd0A1E359811322d97991E03f863a0C30C2cF029C; // kovan //address public constant bZxContract = 0xD154eE4982b83a87b0649E5a7DDA1514812aFE1f; // bsc //address public constant wethToken = 0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c; // bsc // address public constant bZxContract = 0x059D60a9CEfBc70b9Ea9FFBb9a041581B1dFA6a8; // polygon // address public constant wethToken = 0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270; // polygon // address public constant bZxContract = 0x37407F3178ffE07a6cF5C847F8f680FEcf319FAB; // arbitrum // address public constant wethToken = 0x82aF49447D8a07e3bd95BD0d56f35241523fBab1; // arbitrum bytes32 internal constant iToken_ProfitSoFar = 0x37aa2b7d583612f016e4a4de4292cb015139b3d7762663d06a53964912ea2fb6; // keccak256("iToken_ProfitSoFar") bytes32 internal constant iToken_LowerAdminAddress = 0x7ad06df6a0af6bd602d90db766e0d5f253b45187c3717a0f9026ea8b10ff0d4b; // keccak256("iToken_LowerAdminAddress") bytes32 internal constant iToken_LowerAdminContract = 0x34b31cff1dbd8374124bd4505521fc29cab0f9554a5386ba7d784a4e611c7e31; // keccak256("iToken_LowerAdminContract") constructor() public { renounceOwnership(); } function() external payable { require(msg.sender == wethToken, "fallback not allowed"); } /* Public functions */ function mint( address receiver, uint256 depositAmount) external nonReentrant pausable returns (uint256) // mintAmount { return _mintToken( receiver, depositAmount ); } function burn( address receiver, uint256 burnAmount) external nonReentrant pausable returns (uint256 loanAmountPaid) { loanAmountPaid = _burnToken( burnAmount ); if (loanAmountPaid != 0) { _safeTransfer(loanTokenAddress, receiver, loanAmountPaid, "5"); } } function flashBorrow( uint256 borrowAmount, address borrower, address target, string calldata signature, bytes calldata data) external payable nonReentrant pausable returns (bytes memory) { require(borrowAmount != 0, "38"); _settleInterest(0); // save before balances uint256 beforeEtherBalance = address(this).balance.sub(msg.value); uint256 beforeAssetsBalance = _underlyingBalance() .add(_totalAssetBorrowStored()); // lock totalAssetSupply for duration of flash loan _flTotalAssetSupply = beforeAssetsBalance; // transfer assets to calling contract _safeTransfer(loanTokenAddress, borrower, borrowAmount, "39"); emit FlashBorrow(borrower, target, loanTokenAddress, borrowAmount); bytes memory callData; if (bytes(signature).length == 0) { callData = data; } else { callData = abi.encodePacked(bytes4(keccak256(bytes(signature))), data); } // arbitrary call (bool success, bytes memory returnData) = arbitraryCaller.call.value(msg.value)( abi.encodeWithSelector( 0xde064e0d, // sendCall(address,bytes) target, callData ) ); require(success, "call failed"); // unlock totalAssetSupply _flTotalAssetSupply = 0; // pay flash borrow fees IBZx(bZxContract).payFlashBorrowFees( borrower, borrowAmount, flashBorrowFeePercent ); // verifies return of flash loan require( address(this).balance >= beforeEtherBalance && _underlyingBalance() .add(_totalAssetBorrowStored()) >= beforeAssetsBalance, "40" ); return returnData; } function borrow( bytes32 loanId, // 0 if new loan uint256 withdrawAmount, uint256 initialLoanDuration, // duration in seconds uint256 collateralTokenSent, // if 0, loanId must be provided; any ETH sent must equal this value address collateralTokenAddress, // if address(0), this means ETH and ETH must be sent with the call or loanId must be provided address borrower, address receiver, bytes memory /*loanDataBytes*/) // arbitrary order data public payable nonReentrant pausable returns (IBZx.LoanOpenData memory) { return _borrow( loanId, withdrawAmount, initialLoanDuration, collateralTokenSent, collateralTokenAddress, borrower, receiver, "" ); } // Called to borrow and immediately get into a position function marginTrade( bytes32 loanId, // 0 if new loan uint256 leverageAmount, uint256 loanTokenSent, uint256 collateralTokenSent, address collateralTokenAddress, address trader, bytes memory loanDataBytes) // arbitrary order data public payable nonReentrant pausable returns (IBZx.LoanOpenData memory) { return _marginTrade( loanId, leverageAmount, loanTokenSent, collateralTokenSent, collateralTokenAddress, trader, loanDataBytes ); } function transfer( address _to, uint256 _value) external returns (bool) { return _internalTransferFrom( msg.sender, _to, _value, uint256(-1) ); } function transferFrom( address _from, address _to, uint256 _value) external returns (bool) { return _internalTransferFrom( _from, _to, _value, allowed[_from][msg.sender] /*IBZx(bZxContract).isLoanPool(msg.sender) ? uint256(-1) : allowed[_from][msg.sender]*/ ); } function _internalTransferFrom( address _from, address _to, uint256 _value, uint256 _allowanceAmount) internal returns (bool) { if (_allowanceAmount != uint256(-1)) { allowed[_from][msg.sender] = _allowanceAmount.sub(_value, "14"); } require(_to != address(0), "15"); uint256 _balancesFrom = balances[_from]; uint256 _balancesFromNew = _balancesFrom .sub(_value, "16"); balances[_from] = _balancesFromNew; uint256 _balancesTo = balances[_to]; uint256 _balancesToNew = _balancesTo .add(_value); balances[_to] = _balancesToNew; // handle checkpoint update uint256 _currentPrice = tokenPrice(); _updateCheckpoints( _from, _balancesFrom, _balancesFromNew, _currentPrice ); _updateCheckpoints( _to, _balancesTo, _balancesToNew, _currentPrice ); emit Transfer(_from, _to, _value); return true; } function _updateCheckpoints( address _user, uint256 _oldBalance, uint256 _newBalance, uint256 _currentPrice) internal { bytes32 slot = keccak256( abi.encodePacked(_user, iToken_ProfitSoFar) ); int256 _currentProfit; if (_newBalance == 0) { _currentPrice = 0; } else if (_oldBalance != 0) { _currentProfit = _profitOf( slot, _oldBalance, _currentPrice, checkpointPrices_[_user] ); } assembly { sstore(slot, _currentProfit) } checkpointPrices_[_user] = _currentPrice; } /* Public View functions */ function profitOf( address user) public view returns (int256) { bytes32 slot = keccak256( abi.encodePacked(user, iToken_ProfitSoFar) ); return _profitOf( slot, balances[user], tokenPrice(), checkpointPrices_[user] ); } function _profitOf( bytes32 slot, uint256 _balance, uint256 _currentPrice, uint256 _checkpointPrice) internal view returns (int256 profitSoFar) { if (_checkpointPrice == 0) { return 0; } assembly { profitSoFar := sload(slot) } profitSoFar = int256(_currentPrice) .sub(int256(_checkpointPrice)) .mul(int256(_balance)) .div(sWEI_PRECISION) .add(profitSoFar); } function tokenPrice() public view returns (uint256) // price { return _tokenPrice(_totalAssetSupply(totalAssetBorrow())); } function checkpointPrice( address _user) public view returns (uint256) // price { return checkpointPrices_[_user]; } // the current rate being paid by borrowers in active loans function borrowInterestRate() public view returns (uint256) { return _nextBorrowInterestRate( _totalAssetBorrowStored(), 0, poolTWAI() ); } // the minimum rate that new and existing borrowers will pay after the next borrow function nextBorrowInterestRate( uint256 borrowAmount) external view returns (uint256) { return _nextBorrowInterestRate( totalAssetBorrow(), borrowAmount, poolTWAI() ); } // the current rate being received by suppliers function supplyInterestRate() external view returns (uint256) { uint256 assetBorrow = _totalAssetBorrowStored(); return _nextSupplyInterestRate( _nextBorrowInterestRate(assetBorrow, 0, poolTWAI()), assetBorrow, _totalAssetSupply(assetBorrow) ); } // the minimum rate new and existing suppliers will receive after the next supply function nextSupplyInterestRate( int256 supplyAmount) external view returns (uint256) { uint256 assetBorrow = totalAssetBorrow(); uint256 totalSupply = _totalAssetSupply(assetBorrow); if(supplyAmount >= 0) totalSupply = totalSupply.add(uint256(supplyAmount)); else totalSupply = totalSupply.sub(uint256(-supplyAmount)); return _nextSupplyInterestRate( _nextBorrowInterestRate(assetBorrow, 0, poolTWAI()), assetBorrow, totalSupply ); } function totalAssetBorrow() public view returns (uint256) { return IBZx(bZxContract).getTotalPrincipal( address(this), address(0) // loanTokenAddress (depreciated) ); } function _totalAssetBorrowStored() internal view returns (uint256) { return IBZx(bZxContract).getPoolPrincipalStored(address(this)); } function totalAssetSupply() external view returns (uint256) { return _totalAssetSupply(totalAssetBorrow()); } function poolLastInterestRate() public view returns (uint256) { return IBZx(bZxContract).getPoolLastInterestRate(address(this)); } function poolTWAI() public view returns (uint256) { return IBZx(bZxContract).getTWAI(address(this)); } // returns the user's balance of underlying token function assetBalanceOf( address _owner) external view returns (uint256) { return balanceOf(_owner) .mul(tokenPrice()) .div(WEI_PRECISION); } function getDepositAmountForBorrow( uint256 borrowAmount, uint256 initialLoanDuration, // duration in seconds address collateralTokenAddress) // address(0) means ETH external view returns (uint256) // depositAmount { if (borrowAmount != 0) { if (borrowAmount <= _underlyingBalance()) { if (collateralTokenAddress == address(0)) { collateralTokenAddress = wethToken; } return IBZx(bZxContract).getRequiredCollateralByParams( loanParamsIds[uint256(keccak256(abi.encodePacked( collateralTokenAddress, true )))], borrowAmount ).add(10); // some dust to compensate for rounding errors } } } function getBorrowAmountForDeposit( uint256 depositAmount, uint256 initialLoanDuration, // duration in seconds address collateralTokenAddress) // address(0) means ETH external view returns (uint256 borrowAmount) { if (depositAmount != 0) { if (collateralTokenAddress == address(0)) { collateralTokenAddress = wethToken; } borrowAmount = IBZx(bZxContract).getBorrowAmountByParams( loanParamsIds[uint256(keccak256(abi.encodePacked( collateralTokenAddress, true )))], depositAmount ); if (borrowAmount > _underlyingBalance()) { borrowAmount = 0; } } } function getPoolUtilization() external view returns (uint256) { uint256 totalBorrow = totalAssetBorrow(); return _utilizationRate( totalBorrow, _totalAssetSupply(totalBorrow) ); } /* Internal functions */ function _mintToken( address receiver, uint256 depositAmount) internal pausable returns (uint256 mintAmount) { require (depositAmount != 0, "17"); _settleInterest(0); uint256 currentPrice = _tokenPrice(_totalAssetSupply(_totalAssetBorrowStored())); mintAmount = depositAmount .mul(WEI_PRECISION) .div(currentPrice); if (msg.value == 0) { _safeTransferFrom(loanTokenAddress, msg.sender, address(this), depositAmount, "18"); } else { require(msg.value == depositAmount, "18"); IWeth(wethToken).deposit.value(depositAmount)(); } _updateCheckpoints( receiver, balances[receiver], _mint(receiver, mintAmount, depositAmount, currentPrice), // newBalance currentPrice ); } function _burnToken( uint256 burnAmount) internal pausable returns (uint256 loanAmountPaid) { require(burnAmount != 0, "19"); _settleInterest(0); if (burnAmount > balanceOf(msg.sender)) { require(burnAmount == uint256(-1), "32"); burnAmount = balanceOf(msg.sender); } uint256 currentPrice = _tokenPrice(_totalAssetSupply(_totalAssetBorrowStored())); uint256 loanAmountOwed = burnAmount .mul(currentPrice) .div(WEI_PRECISION); uint256 loanAmountAvailableInContract = _underlyingBalance(); loanAmountPaid = loanAmountOwed; require(loanAmountPaid <= loanAmountAvailableInContract, "37"); _updateCheckpoints( msg.sender, balances[msg.sender], _burn(msg.sender, burnAmount, loanAmountPaid, currentPrice), // newBalance currentPrice ); } function _borrow( bytes32 loanId, // 0 if new loan uint256 withdrawAmount, uint256 initialLoanDuration, // duration in seconds uint256 collateralTokenSent, // if 0, loanId must be provided; any ETH sent must equal this value address collateralTokenAddress, // if address(0), this means ETH and ETH must be sent with the call or loanId must be provided address borrower, address receiver, bytes memory /*loanDataBytes*/) // arbitrary order data internal pausable returns (IBZx.LoanOpenData memory) { require(withdrawAmount != 0, "6"); require(msg.value == 0 || msg.value == collateralTokenSent, "7"); require(collateralTokenSent != 0 || loanId != 0, "8"); require(collateralTokenAddress != address(0) || msg.value != 0 || loanId != 0, "9"); // ensures authorized use of existing loan require(loanId == 0 || msg.sender == borrower, "13"); _settleInterest(loanId); if (loanId == 0) { loanId = keccak256(abi.encodePacked( collateralTokenAddress, address(this), msg.sender, borrower, block.timestamp )); } if (collateralTokenAddress == address(0)) { collateralTokenAddress = wethToken; } require(collateralTokenAddress != loanTokenAddress, "10"); address[4] memory sentAddresses; uint256[5] memory sentAmounts; sentAddresses[0] = address(this); // lender sentAddresses[1] = borrower; sentAddresses[2] = receiver; //sentAddresses[3] = address(0); // manager //sentAmounts[0] = 0; // interestRate (found later) //sentAmounts[1] = 0; // borrowAmount (found later) //sentAmounts[2] = 0; // interestInitialAmount (found later) //sentAmounts[3] = 0; // loanTokenSent sentAmounts[4] = collateralTokenSent; sentAmounts[1] = withdrawAmount; sentAmounts[2] = 0; // interestInitialAmount (depreciated) return _borrowOrTrade( loanId, withdrawAmount, 0, // leverageAmount (calculated later) collateralTokenAddress, sentAddresses, sentAmounts, "" // loanDataBytes ); } function _marginTrade( bytes32 loanId, // 0 if new loan uint256 leverageAmount, uint256 loanTokenSent, uint256 collateralTokenSent, address collateralTokenAddress, address trader, bytes memory loanDataBytes) internal pausable returns (IBZx.LoanOpenData memory loanOpenData) { // ensures authorized use of existing loan require(loanId == 0 || msg.sender == trader, "13"); _settleInterest(loanId); if (loanId == 0) { loanId = keccak256(abi.encodePacked( collateralTokenAddress, address(this), msg.sender, trader, block.timestamp )); } if (collateralTokenAddress == address(0)) { collateralTokenAddress = wethToken; } require(collateralTokenAddress != loanTokenAddress, "11"); address[4] memory sentAddresses; uint256[5] memory sentAmounts; sentAddresses[0] = address(this); // lender sentAddresses[1] = trader; sentAddresses[2] = trader; //sentAddresses[3] = address(0); // manager //sentAmounts[0] = 0; // interestRate (found later) //sentAmounts[1] = 0; // borrowAmount (found later) //sentAmounts[2] = 0; // interestInitialAmount (interest is calculated based on fixed-term loan) sentAmounts[3] = loanTokenSent; sentAmounts[4] = collateralTokenSent; uint256 totalDeposit; uint256 collateralToLoanRate; (sentAmounts[1],, totalDeposit, collateralToLoanRate) = _getPreMarginData( // borrowAmount, interestRate, totalDeposit, collateralToLoanRate collateralTokenAddress, collateralTokenSent, loanTokenSent, leverageAmount ); require(totalDeposit != 0, "12"); loanOpenData = _borrowOrTrade( loanId, 0, // withdrawAmount leverageAmount, collateralTokenAddress, sentAddresses, sentAmounts, loanDataBytes ); IBZx(bZxContract).setDepositAmount( loanOpenData.loanId, totalDeposit, totalDeposit .mul(WEI_PRECISION) .div(collateralToLoanRate) ); return loanOpenData; } function _settleInterest( bytes32 loanId) internal { IBZx(bZxContract).settleInterest(loanId); } function _totalDeposit( address collateralTokenAddress, uint256 collateralTokenSent, uint256 loanTokenSent) internal view returns (uint256 totalDeposit, uint256 collateralToLoanRate) { uint256 collateralToLoanPrecision; (collateralToLoanRate, collateralToLoanPrecision) = IPriceFeeds(IBZx(bZxContract).priceFeeds()).queryRate( collateralTokenAddress, loanTokenAddress ); require(collateralToLoanRate != 0 && collateralToLoanPrecision != 0, "20"); collateralToLoanRate = collateralToLoanRate .mul(WEI_PRECISION) .div(collateralToLoanPrecision); totalDeposit = loanTokenSent; if (collateralTokenSent != 0) { totalDeposit = collateralTokenSent .mul(collateralToLoanRate) .div(WEI_PRECISION) .add(totalDeposit); } } // returns newPrincipal function _borrowOrTrade( bytes32 loanId, uint256 withdrawAmount, uint256 leverageAmount, address collateralTokenAddress, address[4] memory sentAddresses, uint256[5] memory sentAmounts, bytes memory loanDataBytes) internal returns (IBZx.LoanOpenData memory) { require (sentAmounts[1] <= _underlyingBalance() && // newPrincipal sentAddresses[1] != address(0), // borrower "24" ); if (sentAddresses[2] == address(0)) { sentAddresses[2] = sentAddresses[1]; // receiver = borrower } // handle transfers prior to adding newPrincipal to loanTokenSent uint256 msgValue = _verifyTransfers( collateralTokenAddress, sentAddresses, sentAmounts, withdrawAmount ); // adding the loan token portion from the lender to loanTokenSent sentAmounts[3] = sentAmounts[3] .add(sentAmounts[1]); // newPrincipal if (withdrawAmount != 0) { // withdrawAmount already sent to the borrower, so we aren't sending it to the protocol sentAmounts[3] = sentAmounts[3] .sub(withdrawAmount); } bool isTorqueLoan = withdrawAmount != 0 ? true : false; bytes32 loanParamsId = loanParamsIds[uint256(keccak256(abi.encodePacked( collateralTokenAddress, isTorqueLoan )))]; // converting to initialMargin if (leverageAmount != 0) { leverageAmount = SafeMath.div(WEI_PRECISION * WEI_PERCENT_PRECISION, leverageAmount); } return IBZx(bZxContract).borrowOrTradeFromPool.value(msgValue)( loanParamsId, loanId, isTorqueLoan, leverageAmount, // initialMargin sentAddresses, sentAmounts, loanDataBytes ); } // sentAddresses[0]: lender // sentAddresses[1]: borrower // sentAddresses[2]: receiver // sentAddresses[3]: manager // sentAmounts[0]: interestRate // sentAmounts[1]: newPrincipal // sentAmounts[2]: interestInitialAmount // sentAmounts[3]: loanTokenSent // sentAmounts[4]: collateralTokenSent function _verifyTransfers( address collateralTokenAddress, address[4] memory sentAddresses, uint256[5] memory sentAmounts, uint256 withdrawalAmount) internal returns (uint256 msgValue) { address _wethToken = wethToken; address _loanTokenAddress = loanTokenAddress; address receiver = sentAddresses[2]; uint256 newPrincipal = sentAmounts[1]; uint256 loanTokenSent = sentAmounts[3]; uint256 collateralTokenSent = sentAmounts[4]; require(_loanTokenAddress != collateralTokenAddress, "26"); msgValue = msg.value; if (withdrawalAmount != 0) { // withdrawOnOpen == true _safeTransfer(_loanTokenAddress, receiver, withdrawalAmount, "27"); if (newPrincipal > withdrawalAmount) { _safeTransfer(_loanTokenAddress, bZxContract, newPrincipal - withdrawalAmount, "27"); } } else { _safeTransfer(_loanTokenAddress, bZxContract, newPrincipal, "27"); } if (collateralTokenSent != 0) { if (collateralTokenAddress == _wethToken && msgValue != 0 && msgValue >= collateralTokenSent) { IWeth(_wethToken).deposit.value(collateralTokenSent)(); _safeTransfer(collateralTokenAddress, bZxContract, collateralTokenSent, "28"); msgValue -= collateralTokenSent; } else { _safeTransferFrom(collateralTokenAddress, msg.sender, bZxContract, collateralTokenSent, "28"); } } if (loanTokenSent != 0) { _safeTransferFrom(_loanTokenAddress, msg.sender, bZxContract, loanTokenSent, "29"); } } function _safeTransfer( address token, address to, uint256 amount, string memory errorMsg) internal { _callOptionalReturn( token, abi.encodeWithSelector(IERC20(token).transfer.selector, to, amount), errorMsg ); } function _safeTransferFrom( address token, address from, address to, uint256 amount, string memory errorMsg) internal { _callOptionalReturn( token, abi.encodeWithSelector(IERC20(token).transferFrom.selector, from, to, amount), errorMsg ); } function _callOptionalReturn( address token, bytes memory data, string memory errorMsg) internal { (bool success, bytes memory returndata) = token.call(data); require(success, errorMsg); if (returndata.length != 0) { require(abi.decode(returndata, (bool)), errorMsg); } } function _underlyingBalance() internal view returns (uint256) { return IERC20(loanTokenAddress).balanceOf(address(this)); } function _nextSupplyInterestRate( uint256 nextBorrowRate, uint256 assetBorrow, uint256 assetSupply) public view returns (uint256) { if (assetBorrow != 0 && assetSupply >= assetBorrow) { return nextBorrowRate .mul(_utilizationRate(assetBorrow, assetSupply)) .mul(SafeMath.sub(WEI_PERCENT_PRECISION, IBZx(bZxContract).lendingFeePercent())) .div(WEI_PERCENT_PRECISION * WEI_PERCENT_PRECISION); } } function _nextBorrowInterestRate( uint256 totalBorrow, uint256 newBorrowNotYetRealized, uint256 lastIR) public view returns (uint256 nextRate) { uint256 utilRate = _utilizationRate( totalBorrow.add(newBorrowNotYetRealized), _totalAssetSupply(totalBorrow) ); //utilRate from 0e18 to 100e18 nextRate = rateHelper.calculateIR(utilRate, lastIR); } /* Internal View functions */ function _tokenPrice( uint256 assetSupply) internal view returns (uint256) { uint256 totalTokenSupply = totalSupply_; return totalTokenSupply != 0 ? assetSupply .mul(WEI_PRECISION) .div(totalTokenSupply) : initialPrice; } function _getPreMarginData( address collateralTokenAddress, uint256 collateralTokenSent, uint256 loanTokenSent, uint256 leverageAmount) internal view returns (uint256 borrowAmount, uint256 interestRate, uint256 totalDeposit, uint256 collateralToLoanRate) { (totalDeposit, collateralToLoanRate) = _totalDeposit( collateralTokenAddress, collateralTokenSent, loanTokenSent ); uint256 initialMargin = SafeMath.div(WEI_PRECISION * WEI_PERCENT_PRECISION, leverageAmount); // assumes that loan and collateral token are the same borrowAmount = totalDeposit .mul(WEI_PERCENT_PRECISION) .div(initialMargin); } function _totalAssetSupply( uint256 totalBorrow) internal view returns (uint256 totalSupply) { totalSupply = _flTotalAssetSupply; // temporary locked totalAssetSupply during a flash loan transaction if (totalSupply == 0) { totalSupply = _underlyingBalance() .add(totalBorrow); } } function _utilizationRate( uint256 assetBorrow, uint256 assetSupply) internal pure returns (uint256) { if (assetSupply != 0) { // U = total_borrow / total_supply return assetBorrow .mul(WEI_PERCENT_PRECISION) .div(assetSupply); } } /* Owner-Only functions */ function updateSettings( address settingsTarget, bytes memory callData) public { if (msg.sender != owner()) { address _lowerAdmin; address _lowerAdminContract; assembly { _lowerAdmin := sload(iToken_LowerAdminAddress) _lowerAdminContract := sload(iToken_LowerAdminContract) } require(msg.sender == _lowerAdmin && settingsTarget == _lowerAdminContract); } address currentTarget = target_; target_ = settingsTarget; (bool result,) = address(this).call(callData); uint256 size; uint256 ptr; assembly { size := returndatasize ptr := mload(0x40) returndatacopy(ptr, 0, size) if eq(result, 0) { revert(ptr, size) } } target_ = currentTarget; assembly { return(ptr, size) } } function updateFlashBorrowFeePercent(uint256 newFeePercent) public onlyOwner { flashBorrowFeePercent = newFeePercent; } } /* pragma solidity 0.5.16; contract ArbitraryCaller { function sendCall( address target, bytes calldata callData) external payable { (bool success,) = target.call.value(msg.value)(callData); assembly { let size := returndatasize() let ptr := mload(0x40) returndatacopy(ptr, 0, size) if eq(success, 0) { revert(ptr, size) } return(ptr, size) } } } */
/** * Copyright 2017-2022, OokiDao. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity 0.5.17; import "AdvancedTokenStorage.sol"; contract AdvancedToken is AdvancedTokenStorage { using SafeMath for uint256; function approve( address _spender, uint256 _value) public returns (bool) { allowed[msg.sender][_spender] = _value; emit Approval(msg.sender, _spender, _value); return true; } function increaseApproval( address _spender, uint256 _addedValue) public returns (bool) { uint256 _allowed = allowed[msg.sender][_spender] .add(_addedValue); allowed[msg.sender][_spender] = _allowed; emit Approval(msg.sender, _spender, _allowed); return true; } function decreaseApproval( address _spender, uint256 _subtractedValue) public returns (bool) { uint256 _allowed = allowed[msg.sender][_spender]; if (_subtractedValue >= _allowed) { _allowed = 0; } else { _allowed -= _subtractedValue; } allowed[msg.sender][_spender] = _allowed; emit Approval(msg.sender, _spender, _allowed); return true; } function _mint( address _to, uint256 _tokenAmount, uint256 _assetAmount, uint256 _price) internal returns (uint256) { require(_to != address(0), "15"); uint256 _balance = balances[_to] .add(_tokenAmount); balances[_to] = _balance; totalSupply_ = totalSupply_ .add(_tokenAmount); emit Mint(_to, _tokenAmount, _assetAmount, _price); emit Transfer(address(0), _to, _tokenAmount); return _balance; } function _burn( address _who, uint256 _tokenAmount, uint256 _assetAmount, uint256 _price) internal returns (uint256) { uint256 _balance = balances[_who].sub(_tokenAmount, "16"); // a rounding error may leave dust behind, so we clear this out if (_balance <= 10) { _tokenAmount = _tokenAmount.add(_balance); _balance = 0; } balances[_who] = _balance; totalSupply_ = totalSupply_.sub(_tokenAmount); emit Burn(_who, _tokenAmount, _assetAmount, _price); emit Transfer(_who, address(0), _tokenAmount); return _balance; } }
/** * Copyright 2017-2022, OokiDao. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity 0.5.17; import "LoanTokenBase.sol"; contract AdvancedTokenStorage is LoanTokenBase { using SafeMath for uint256; event Transfer( address indexed from, address indexed to, uint256 value ); event Approval( address indexed owner, address indexed spender, uint256 value ); event Mint( address indexed minter, uint256 tokenAmount, uint256 assetAmount, uint256 price ); event Burn( address indexed burner, uint256 tokenAmount, uint256 assetAmount, uint256 price ); event FlashBorrow( address borrower, address target, address loanToken, uint256 loanAmount ); mapping(address => uint256) internal balances; mapping (address => mapping (address => uint256)) internal allowed; uint256 internal totalSupply_; function totalSupply() public view returns (uint256) { return totalSupply_; } function balanceOf( address _owner) public view returns (uint256) { return balances[_owner]; } function allowance( address _owner, address _spender) public view returns (uint256) { return allowed[_owner][_spender]; } }
/** * Copyright 2017-2022, OokiDao. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity 0.5.17; import "SafeMath.sol"; import "SignedSafeMath.sol"; import "ReentrancyGuard.sol"; import "Ownable.sol"; import "Address.sol"; import "IWethERC20.sol"; import "PausableGuardian.sol"; contract LoanTokenBase is ReentrancyGuard, Ownable, PausableGuardian { uint256 internal constant WEI_PRECISION = 10**18; uint256 internal constant WEI_PERCENT_PRECISION = 10**20; int256 internal constant sWEI_PRECISION = 10**18; string public name; string public symbol; uint8 public decimals; // uint88 for tight packing -> 8 + 88 + 160 = 256 uint88 internal lastSettleTime_; address public loanTokenAddress; uint256 internal baseRate_UNUSED; uint256 internal rateMultiplier_UNUSED; uint256 internal lowUtilBaseRate_UNUSED; uint256 internal lowUtilRateMultiplier_UNUSED; uint256 internal targetLevel_UNUSED; uint256 internal kinkLevel_UNUSED; uint256 internal maxScaleRate_UNUSED; uint256 internal _flTotalAssetSupply; uint256 internal checkpointSupply_UNUSED; uint256 public initialPrice; mapping (uint256 => bytes32) public loanParamsIds; // mapping of keccak256(collateralToken, isTorqueLoan) to loanParamsId mapping (address => uint256) internal checkpointPrices_; // price of token at last user checkpoint }
pragma solidity ^0.5.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. * * _Available since v2.4.0._ */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { // Solidity only automatically asserts when dividing by 0 require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * - The divisor cannot be zero. * * _Available since v2.4.0._ */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
pragma solidity >=0.5.0 <0.6.0; /** * @title SignedSafeMath * @dev Signed math operations with safety checks that revert on error. */ library SignedSafeMath { int256 constant private _INT256_MIN = -2**255; /** * @dev Returns the multiplication of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(int256 a, int256 b) internal pure returns (int256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } require(!(a == -1 && b == _INT256_MIN), "SignedSafeMath: multiplication overflow"); int256 c = a * b; require(c / a == b, "SignedSafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two signed integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(int256 a, int256 b) internal pure returns (int256) { require(b != 0, "SignedSafeMath: division by zero"); require(!(b == -1 && a == _INT256_MIN), "SignedSafeMath: division overflow"); int256 c = a / b; return c; } /** * @dev Returns the subtraction of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(int256 a, int256 b) internal pure returns (int256) { int256 c = a - b; require((b >= 0 && c <= a) || (b < 0 && c > a), "SignedSafeMath: subtraction overflow"); return c; } /** * @dev Returns the addition of two signed integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(int256 a, int256 b) internal pure returns (int256) { int256 c = a + b; require((b >= 0 && c >= a) || (b < 0 && c < a), "SignedSafeMath: addition overflow"); return c; } }
pragma solidity >=0.5.0 <0.6.0; /** * @title Helps contracts guard against reentrancy attacks. * @author Remco Bloemen <remco@2π.com>, Eenae <[email protected]> * @dev If you mark a function `nonReentrant`, you should also * mark it `external`. */ contract ReentrancyGuard { /// @dev Constant for unlocked guard state - non-zero to prevent extra gas costs. /// See: https://github.com/OpenZeppelin/openzeppelin-solidity/issues/1056 uint256 internal constant REENTRANCY_GUARD_FREE = 1; /// @dev Constant for locked guard state uint256 internal constant REENTRANCY_GUARD_LOCKED = 2; /** * @dev We use a single lock for the whole contract. */ uint256 internal reentrancyLock = REENTRANCY_GUARD_FREE; /** * @dev Prevents a contract from calling itself, directly or indirectly. * If you mark a function `nonReentrant`, you should also * mark it `external`. Calling one `nonReentrant` function from * another is not supported. Instead, you can implement a * `private` function doing the actual work, and an `external` * wrapper marked as `nonReentrant`. */ modifier nonReentrant() { require(reentrancyLock == REENTRANCY_GUARD_FREE, "nonReentrant"); reentrancyLock = REENTRANCY_GUARD_LOCKED; _; reentrancyLock = REENTRANCY_GUARD_FREE; } }
pragma solidity ^0.5.0; import "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. * * 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. */ 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 () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(isOwner(), "Ownable: caller is not the owner"); _; } /** * @dev Returns true if the caller is the current owner. */ function isOwner() public view returns (bool) { return _msgSender() == _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 onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = 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 onlyOwner { _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). */ function _transferOwnership(address newOwner) internal { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
pragma solidity ^0.5.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 GSN 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. */ contract Context { // Empty internal constructor, to prevent people from mistakenly deploying // an instance of this contract, which should be used via inheritance. constructor () internal { } // solhint-disable-previous-line no-empty-blocks function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
pragma solidity ^0.5.5; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // According to EIP-1052, 0x0 is the value returned for not-yet created accounts // and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned // for accounts without code, i.e. `keccak256('')` bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; // solhint-disable-next-line no-inline-assembly assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } /** * @dev Converts an `address` into `address payable`. Note that this is * simply a type cast: the actual underlying value is not changed. * * _Available since v2.4.0._ */ function toPayable(address account) internal pure returns (address payable) { return address(uint160(account)); } /** * @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]. * * _Available since v2.4.0._ */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-call-value (bool success, ) = recipient.call.value(amount)(""); require(success, "Address: unable to send value, recipient may have reverted"); } }
/** * Copyright 2017-2022, OokiDao. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity >=0.5.0 <0.6.0; import "IWeth.sol"; import "IERC20.sol"; contract IWethERC20 is IWeth, IERC20 {}
/** * Copyright 2017-2022, OokiDao. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity >=0.5.0 <0.6.0; interface IWeth { function deposit() external payable; function withdraw(uint256 wad) external; }
pragma solidity ^0.5.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. Does not include * the optional functions; to access them see {ERC20Detailed}. */ interface IERC20 { /** * @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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, uint256 amount) external returns (bool); /** * @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); }
/** * Copyright 2017-2022, OokiDao. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity 0.5.17; import "Ownable.sol"; contract PausableGuardian is Ownable { // keccak256("Pausable_FunctionPause") bytes32 internal constant Pausable_FunctionPause = 0xa7143c84d793a15503da6f19bf9119a2dac94448ca45d77c8bf08f57b2e91047; // keccak256("Pausable_GuardianAddress") bytes32 internal constant Pausable_GuardianAddress = 0x80e6706973d0c59541550537fd6a33b971efad732635e6c3b99fb01006803cdf; modifier pausable { require(!_isPaused(msg.sig), "paused"); _; } modifier onlyGuardian { require(msg.sender == getGuardian() || msg.sender == owner(), "unauthorized"); _; } function _isPaused(bytes4 sig) public view returns (bool isPaused) { bytes32 slot = keccak256(abi.encodePacked(sig, Pausable_FunctionPause)); assembly { isPaused := sload(slot) } } function toggleFunctionPause(bytes4 sig) public onlyGuardian { bytes32 slot = keccak256(abi.encodePacked(sig, Pausable_FunctionPause)); assembly { sstore(slot, 1) } } function toggleFunctionUnPause(bytes4 sig) public onlyGuardian { // only DAO can unpause, and adding guardian temporarily bytes32 slot = keccak256(abi.encodePacked(sig, Pausable_FunctionPause)); assembly { sstore(slot, 0) } } function changeGuardian(address newGuardian) public onlyGuardian { assembly { sstore(Pausable_GuardianAddress, newGuardian) } } function getGuardian() public view returns (address guardian) { assembly { guardian := sload(Pausable_GuardianAddress) } } function pause(bytes4 [] calldata sig) external onlyGuardian { for(uint256 i = 0; i < sig.length; ++i){ toggleFunctionPause(sig[i]); } } function unpause(bytes4 [] calldata sig) external onlyGuardian { for(uint256 i = 0; i < sig.length; ++i){ toggleFunctionUnPause(sig[i]); } } }
/** * Copyright 2017-2022, OokiDao. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity 0.5.17; import "ICurvedInterestRate.sol"; contract StorageExtension { address internal target_; uint256 public flashBorrowFeePercent; // set to 0.03% ICurvedInterestRate rateHelper; }
/** * Copyright 2017-2022, OokiDao. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ // SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.5.0 <0.9.0; interface ICurvedInterestRate { function getInterestRate( uint256 _U, uint256 _a, uint256 _b ) external pure returns (uint256 interestRate); function getAB(uint256 _IR1) external pure returns (uint256 a, uint256 b); function getAB( uint256 _IR1, uint256 _IR2, uint256 _UR1, uint256 _UR2 ) external pure returns (uint256 a, uint256 b); function calculateIR(uint256 _U, uint256 _IR1) external pure returns (uint256 interestRate); }
/** * Copyright 2017-2022, OokiDao. All Rights Reserved. * Licensed under the Apache-2.0 */ // SPDX-License-Identifier: Apache-2.0 pragma solidity >=0.5.0 <0.9.0; pragma experimental ABIEncoderV2; /// @title A proxy interface for The Protocol /// @author bZeroX /// @notice This is just an interface, not to be deployed itself. /// @dev This interface is to be used for the protocol interactions. interface IBZx { ////// Protocol ////// /// @dev adds or replaces existing proxy module /// @param target target proxy module address function replaceContract(address target) external; /// @dev updates all proxy modules addreses and function signatures. /// sigsArr and targetsArr should be of equal length /// @param sigsArr array of function signatures /// @param targetsArr array of target proxy module addresses function setTargets( string[] calldata sigsArr, address[] calldata targetsArr ) external; /// @dev returns protocol module address given a function signature /// @return module address function getTarget(string calldata sig) external view returns (address); ////// Protocol Settings ////// /// @dev sets price feed contract address. The contract on the addres should implement IPriceFeeds interface /// @param newContract module address for the IPriceFeeds implementation function setPriceFeedContract(address newContract) external; /// @dev sets swaps contract address. The contract on the addres should implement ISwapsImpl interface /// @param newContract module address for the ISwapsImpl implementation function setSwapsImplContract(address newContract) external; /// @dev sets loan pool with assets. Accepts two arrays of equal length /// @param pools array of address of pools /// @param assets array of addresses of assets function setLoanPool(address[] calldata pools, address[] calldata assets) external; /// @dev updates list of supported tokens, it can be use also to disable or enable particualr token /// @param addrs array of address of pools /// @param toggles array of addresses of assets /// @param withApprovals resets tokens to unlimited approval with the swaps integration (kyber, etc.) function setSupportedTokens( address[] calldata addrs, bool[] calldata toggles, bool withApprovals ) external; /// @dev sets lending fee with WEI_PERCENT_PRECISION /// @param newValue lending fee percent function setLendingFeePercent(uint256 newValue) external; /// @dev sets trading fee with WEI_PERCENT_PRECISION /// @param newValue trading fee percent function setTradingFeePercent(uint256 newValue) external; /// @dev sets borrowing fee with WEI_PERCENT_PRECISION /// @param newValue borrowing fee percent function setBorrowingFeePercent(uint256 newValue) external; /// @dev sets affiliate fee with WEI_PERCENT_PRECISION /// @param newValue affiliate fee percent function setAffiliateFeePercent(uint256 newValue) external; /// @dev sets liquidation inncetive percent per loan per token. This is the profit percent /// that liquidator gets in the process of liquidating. /// @param loanTokens array list of loan tokens /// @param collateralTokens array list of collateral tokens /// @param amounts array list of liquidation inncetive amount function setLiquidationIncentivePercent( address[] calldata loanTokens, address[] calldata collateralTokens, uint256[] calldata amounts ) external; /// @dev sets max swap rate slippage percent. /// @param newAmount max swap rate slippage percent. function setMaxDisagreement(uint256 newAmount) external; /// TODO function setSourceBufferPercent(uint256 newAmount) external; /// @dev sets maximum supported swap size in ETH /// @param newAmount max swap size in ETH. function setMaxSwapSize(uint256 newAmount) external; /// @dev sets fee controller address /// @param newController address of the new fees controller function setFeesController(address newController) external; /// @dev withdraws lending fees to receiver. Only can be called by feesController address /// @param tokens array of token addresses. /// @param receiver fees receiver address /// @return amounts array of amounts withdrawn function withdrawFees( address[] calldata tokens, address receiver, FeeClaimType feeType ) external returns (uint256[] memory amounts); /* Targets still exist, but functions are decommissioned: /// @dev withdraw protocol token (BZRX) from vesting contract vBZRX /// @param receiver address of BZRX tokens claimed /// @param amount of BZRX token to be claimed. max is claimed if amount is greater than balance. /// @return rewardToken reward token address /// @return withdrawAmount amount function withdrawProtocolToken(address receiver, uint256 amount) external returns (address rewardToken, uint256 withdrawAmount); /// @dev depozit protocol token (BZRX) /// @param amount address of BZRX tokens to deposit function depositProtocolToken(uint256 amount) external; function grantRewards(address[] calldata users, uint256[] calldata amounts) external returns (uint256 totalAmount);*/ // NOTE: this doesn't sanitize inputs -> inaccurate values may be returned if there are duplicate token inputs function queryFees(address[] calldata tokens, FeeClaimType feeType) external view returns (uint256[] memory amountsHeld, uint256[] memory amountsPaid); function priceFeeds() external view returns (address); function swapsImpl() external view returns (address); function logicTargets(bytes4) external view returns (address); function loans(bytes32) external view returns (Loan memory); function loanParams(bytes32) external view returns (LoanParams memory); // we don't use this yet // function lenderOrders(address, bytes32) external returns (Order memory); // function borrowerOrders(address, bytes32) external returns (Order memory); function delegatedManagers(bytes32, address) external view returns (bool); function lenderInterest(address, address) external view returns (LenderInterest memory); function loanInterest(bytes32) external view returns (LoanInterest memory); function feesController() external view returns (address); function lendingFeePercent() external view returns (uint256); function lendingFeeTokensHeld(address) external view returns (uint256); function lendingFeeTokensPaid(address) external view returns (uint256); function borrowingFeePercent() external view returns (uint256); function borrowingFeeTokensHeld(address) external view returns (uint256); function borrowingFeeTokensPaid(address) external view returns (uint256); function protocolTokenHeld() external view returns (uint256); function protocolTokenPaid() external view returns (uint256); function affiliateFeePercent() external view returns (uint256); function liquidationIncentivePercent(address, address) external view returns (uint256); function loanPoolToUnderlying(address) external view returns (address); function underlyingToLoanPool(address) external view returns (address); function supportedTokens(address) external view returns (bool); function maxDisagreement() external view returns (uint256); function sourceBufferPercent() external view returns (uint256); function maxSwapSize() external view returns (uint256); /// @dev get list of loan pools in the system. Ordering is not guaranteed /// @param start start index /// @param count number of pools to return /// @return loanPoolsList array of loan pools function getLoanPoolsList(uint256 start, uint256 count) external view returns (address[] memory loanPoolsList); /// @dev checks whether addreess is a loan pool address /// @return boolean function isLoanPool(address loanPool) external view returns (bool); ////// Loan Settings ////// /// @dev creates new loan param settings /// @param loanParamsList array of LoanParams /// @return loanParamsIdList array of loan ids created function setupLoanParams(LoanParams[] calldata loanParamsList) external returns (bytes32[] memory loanParamsIdList); function setupLoanPoolTWAI(address pool) external; function setTWAISettings(uint32 delta, uint32 secondsAgo) external; /// @dev Deactivates LoanParams for future loans. Active loans using it are unaffected. /// @param loanParamsIdList array of loan ids function disableLoanParams(bytes32[] calldata loanParamsIdList) external; /// @dev gets array of LoanParams by given ids /// @param loanParamsIdList array of loan ids /// @return loanParamsList array of LoanParams function getLoanParams(bytes32[] calldata loanParamsIdList) external view returns (LoanParams[] memory loanParamsList); /// @dev Enumerates LoanParams in the system by owner /// @param owner of the loan params /// @param start number of loans to return /// @param count total number of the items /// @return loanParamsList array of LoanParams function getLoanParamsList( address owner, uint256 start, uint256 count ) external view returns (bytes32[] memory loanParamsList); /// @dev returns total loan principal for token address /// @param lender address /// @param loanToken address /// @return total principal of the loan function getTotalPrincipal(address lender, address loanToken) external view returns (uint256); /// @dev returns total principal for a loan pool that was last settled /// @param pool address /// @return total stored principal of the loan function getPoolPrincipalStored(address pool) external view returns (uint256); /// @dev returns the last interest rate founnd during interest settlement /// @param pool address /// @return the last interset rate function getPoolLastInterestRate(address pool) external view returns (uint256); ////// Loan Openings ////// /// @dev This is THE function that borrows or trades on the protocol /// @param loanParamsId id of the LoanParam created beforehand by setupLoanParams function /// @param loanId id of existing loan, if 0, start a new loan /// @param isTorqueLoan boolean whether it is toreque or non torque loan /// @param initialMargin in WEI_PERCENT_PRECISION /// @param sentAddresses array of size 4: /// lender: must match loan if loanId provided /// borrower: must match loan if loanId provided /// receiver: receiver of funds (address(0) assumes borrower address) /// manager: delegated manager of loan unless address(0) /// @param sentValues array of size 5: /// newRate: new loan interest rate /// newPrincipal: new loan size (borrowAmount + any borrowed interest) /// torqueInterest: new amount of interest to escrow for Torque loan (determines initial loan length) /// loanTokenReceived: total loanToken deposit (amount not sent to borrower in the case of Torque loans) /// collateralTokenReceived: total collateralToken deposit /// @param loanDataBytes required when sending ether /// @return principal of the loan and collateral amount function borrowOrTradeFromPool( bytes32 loanParamsId, bytes32 loanId, bool isTorqueLoan, uint256 initialMargin, address[4] calldata sentAddresses, uint256[5] calldata sentValues, bytes calldata loanDataBytes ) external payable returns (LoanOpenData memory); /// @dev sets/disables/enables the delegated manager for the loan /// @param loanId id of the loan /// @param delegated delegated manager address /// @param toggle boolean set enabled or disabled function setDelegatedManager( bytes32 loanId, address delegated, bool toggle ) external; /// @dev calculates required collateral for simulated position /// @param loanToken address of loan token /// @param collateralToken address of collateral token /// @param newPrincipal principal amount of the loan /// @param marginAmount margin amount of the loan /// @param isTorqueLoan boolean torque or non torque loan /// @return collateralAmountRequired amount required function getRequiredCollateral( address loanToken, address collateralToken, uint256 newPrincipal, uint256 marginAmount, bool isTorqueLoan ) external view returns (uint256 collateralAmountRequired); function getRequiredCollateralByParams( bytes32 loanParamsId, uint256 newPrincipal ) external view returns (uint256 collateralAmountRequired); /// @dev calculates borrow amount for simulated position /// @param loanToken address of loan token /// @param collateralToken address of collateral token /// @param collateralTokenAmount amount of collateral token sent /// @param marginAmount margin amount /// @param isTorqueLoan boolean torque or non torque loan /// @return borrowAmount possible borrow amount function getBorrowAmount( address loanToken, address collateralToken, uint256 collateralTokenAmount, uint256 marginAmount, bool isTorqueLoan ) external view returns (uint256 borrowAmount); function getBorrowAmountByParams( bytes32 loanParamsId, uint256 collateralTokenAmount ) external view returns (uint256 borrowAmount); ////// Loan Closings ////// /// @dev liquidates unhealty loans /// @param loanId id of the loan /// @param receiver address receiving liquidated loan collateral /// @param closeAmount amount to close denominated in loanToken /// @return loanCloseAmount amount of the collateral token of the loan /// @return seizedAmount sezied amount in the collateral token /// @return seizedToken loan token address function liquidate( bytes32 loanId, address receiver, uint256 closeAmount ) external payable returns ( uint256 loanCloseAmount, uint256 seizedAmount, address seizedToken ); /// @dev close position with loan token deposit /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param depositAmount amount of loan token to deposit /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithDeposit( bytes32 loanId, address receiver, uint256 depositAmount // denominated in loanToken ) external payable returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); /// @dev close position with swap /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param swapAmount amount of loan token to swap /// @param returnTokenIsCollateral boolean whether to return tokens is collateral /// @param loanDataBytes custom payload for specifying swap implementation and data to pass /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithSwap( bytes32 loanId, address receiver, uint256 swapAmount, // denominated in collateralToken bool returnTokenIsCollateral, // true: withdraws collateralToken, false: withdraws loanToken bytes calldata loanDataBytes ) external returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); ////// Loan Closings With Gas Token ////// /// @dev liquidates unhealty loans by using Gas token /// @param loanId id of the loan /// @param receiver address receiving liquidated loan collateral /// @param gasTokenUser user address of the GAS token /// @param closeAmount amount to close denominated in loanToken /// @return loanCloseAmount loan close amount /// @return seizedAmount loan token withdraw amount /// @return seizedToken loan token address function liquidateWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 closeAmount // denominated in loanToken ) external payable returns ( uint256 loanCloseAmount, uint256 seizedAmount, address seizedToken ); /// @dev close position with loan token deposit /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param gasTokenUser user address of the GAS token /// @param depositAmount amount of loan token to deposit denominated in loanToken /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithDepositWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 depositAmount ) external payable returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); /// @dev close position with swap /// @param loanId id of the loan /// @param receiver collateral token reciever address /// @param gasTokenUser user address of the GAS token /// @param swapAmount amount of loan token to swap denominated in collateralToken /// @param returnTokenIsCollateral true: withdraws collateralToken, false: withdraws loanToken /// @return loanCloseAmount loan close amount /// @return withdrawAmount loan token withdraw amount /// @return withdrawToken loan token address function closeWithSwapWithGasToken( bytes32 loanId, address receiver, address gasTokenUser, uint256 swapAmount, bool returnTokenIsCollateral, bytes calldata loanDataBytes ) external returns ( uint256 loanCloseAmount, uint256 withdrawAmount, address withdrawToken ); ////// Loan Maintenance ////// /// @dev deposit collateral to existing loan /// @param loanId existing loan id /// @param depositAmount amount to deposit which must match msg.value if ether is sent function depositCollateral(bytes32 loanId, uint256 depositAmount) external payable; /// @dev withdraw collateral from existing loan /// @param loanId existing loan id /// @param receiver address of withdrawn tokens /// @param withdrawAmount amount to withdraw /// @return actualWithdrawAmount actual amount withdrawn function withdrawCollateral( bytes32 loanId, address receiver, uint256 withdrawAmount ) external returns (uint256 actualWithdrawAmount); /// @dev settles accrued interest for all active loans from a loan pool /// @param loanId existing loan id function settleInterest(bytes32 loanId) external; function setDepositAmount( bytes32 loanId, uint256 depositValueAsLoanToken, uint256 depositValueAsCollateralToken ) external; function transferLoan(bytes32 loanId, address newOwner) external; // Decommissioned function, but leave interface to allow remaining claims function claimRewards(address receiver) external returns (uint256 claimAmount); // Decommissioned function, but leave interface to allow remaining claims function rewardsBalanceOf(address user) external view returns (uint256 rewardsBalance); function getInterestModelValues( address pool, bytes32 loanId) external view returns ( uint256 _poolLastUpdateTime, uint256 _poolPrincipalTotal, uint256 _poolInterestTotal, uint256 _poolRatePerTokenStored, uint256 _poolLastInterestRate, uint256 _loanPrincipalTotal, uint256 _loanInterestTotal, uint256 _loanRatePerTokenPaid ); function getTWAI( address pool) external view returns ( uint256 benchmarkRate ); /// @dev gets list of loans of particular user address /// @param user address of the loans /// @param start of the index /// @param count number of loans to return /// @param loanType type of the loan: All(0), Margin(1), NonMargin(2) /// @param isLender whether to list lender loans or borrower loans /// @param unsafeOnly booleat if true return only unsafe loans that are open for liquidation /// @return loansData LoanReturnData array of loans function getUserLoans( address user, uint256 start, uint256 count, LoanType loanType, bool isLender, bool unsafeOnly ) external view returns (LoanReturnData[] memory loansData); function getUserLoansCount(address user, bool isLender) external view returns (uint256); /// @dev gets existing loan /// @param loanId id of existing loan /// @return loanData array of loans function getLoan(bytes32 loanId) external view returns (LoanReturnData memory loanData); /// @dev gets loan principal including interest /// @param loanId id of existing loan /// @return principal function getLoanPrincipal(bytes32 loanId) external view returns (uint256 principal); /// @dev gets loan outstanding interest /// @param loanId id of existing loan /// @return interest function getLoanInterestOutstanding(bytes32 loanId) external view returns (uint256 interest); /// @dev get current active loans in the system /// @param start of the index /// @param count number of loans to return /// @param unsafeOnly boolean if true return unsafe loan only (open for liquidation) function getActiveLoans( uint256 start, uint256 count, bool unsafeOnly ) external view returns (LoanReturnData[] memory loansData); /// @dev get current active loans in the system /// @param start of the index /// @param count number of loans to return /// @param unsafeOnly boolean if true return unsafe loan only (open for liquidation) /// @param isLiquidatable boolean if true return liquidatable loans only function getActiveLoansAdvanced( uint256 start, uint256 count, bool unsafeOnly, bool isLiquidatable ) external view returns (LoanReturnData[] memory loansData); function getActiveLoansCount() external view returns (uint256); ////// Swap External ////// /// @dev swap thru external integration /// @param sourceToken source token address /// @param destToken destintaion token address /// @param receiver address to receive tokens /// @param returnToSender TODO /// @param sourceTokenAmount source token amount /// @param requiredDestTokenAmount destination token amount /// @param swapData TODO /// @return destTokenAmountReceived destination token received /// @return sourceTokenAmountUsed source token amount used function swapExternal( address sourceToken, address destToken, address receiver, address returnToSender, uint256 sourceTokenAmount, uint256 requiredDestTokenAmount, bytes calldata swapData ) external payable returns ( uint256 destTokenAmountReceived, uint256 sourceTokenAmountUsed ); /// @dev swap thru external integration using GAS /// @param sourceToken source token address /// @param destToken destintaion token address /// @param receiver address to receive tokens /// @param returnToSender TODO /// @param gasTokenUser user address of the GAS token /// @param sourceTokenAmount source token amount /// @param requiredDestTokenAmount destination token amount /// @param swapData TODO /// @return destTokenAmountReceived destination token received /// @return sourceTokenAmountUsed source token amount used function swapExternalWithGasToken( address sourceToken, address destToken, address receiver, address returnToSender, address gasTokenUser, uint256 sourceTokenAmount, uint256 requiredDestTokenAmount, bytes calldata swapData ) external payable returns ( uint256 destTokenAmountReceived, uint256 sourceTokenAmountUsed ); /// @dev calculate simulated return of swap /// @param sourceToken source token address /// @param destToken destination token address /// @param sourceTokenAmount source token amount /// @return amoun denominated in destination token function getSwapExpectedReturn( address sourceToken, address destToken, uint256 sourceTokenAmount, bytes calldata swapData ) external view returns (uint256); function owner() external view returns (address); function transferOwnership(address newOwner) external; /// Guardian Interface function _isPaused(bytes4 sig) external view returns (bool isPaused); function toggleFunctionPause(bytes4 sig) external; function toggleFunctionUnPause(bytes4 sig) external; function pause(bytes4 [] calldata sig) external; function unpause(bytes4 [] calldata sig) external; function changeGuardian(address newGuardian) external; function getGuardian() external view returns (address guardian); /// Loan Cleanup Interface function cleanupLoans( address loanToken, bytes32[] calldata loanIds) external payable returns (uint256 totalPrincipalIn); struct LoanParams { bytes32 id; bool active; address owner; address loanToken; address collateralToken; uint256 minInitialMargin; uint256 maintenanceMargin; uint256 maxLoanTerm; } struct LoanOpenData { bytes32 loanId; uint256 principal; uint256 collateral; } enum LoanType { All, Margin, NonMargin } struct LoanReturnData { bytes32 loanId; uint96 endTimestamp; address loanToken; address collateralToken; uint256 principal; uint256 collateral; uint256 interestOwedPerDay; uint256 interestDepositRemaining; uint256 startRate; uint256 startMargin; uint256 maintenanceMargin; uint256 currentMargin; uint256 maxLoanTerm; uint256 maxLiquidatable; uint256 maxSeizable; uint256 depositValueAsLoanToken; uint256 depositValueAsCollateralToken; } enum FeeClaimType { All, Lending, Trading, Borrowing } struct Loan { bytes32 id; // id of the loan bytes32 loanParamsId; // the linked loan params id bytes32 pendingTradesId; // the linked pending trades id uint256 principal; // total borrowed amount outstanding uint256 collateral; // total collateral escrowed for the loan uint256 startTimestamp; // loan start time uint256 endTimestamp; // for active loans, this is the expected loan end time, for in-active loans, is the actual (past) end time uint256 startMargin; // initial margin when the loan opened uint256 startRate; // reference rate when the loan opened for converting collateralToken to loanToken address borrower; // borrower of this loan address lender; // lender of this loan bool active; // if false, the loan has been fully closed } struct LenderInterest { uint256 principalTotal; // total borrowed amount outstanding of asset uint256 owedPerDay; // interest owed per day for all loans of asset uint256 owedTotal; // total interest owed for all loans of asset (assuming they go to full term) uint256 paidTotal; // total interest paid so far for asset uint256 updatedTimestamp; // last update } struct LoanInterest { uint256 owedPerDay; // interest owed per day for loan uint256 depositTotal; // total escrowed interest for loan uint256 updatedTimestamp; // last update } ////// Flash Borrow Fees ////// function payFlashBorrowFees( address user, uint256 borrowAmount, uint256 flashBorrowFeePercent) external; }
/** * Copyright 2017-2022, OokiDao. All Rights Reserved. * Licensed under the Apache License, Version 2.0. */ pragma solidity >=0.5.0 <0.9.0; interface IPriceFeeds { function queryRate( address sourceToken, address destToken) external view returns (uint256 rate, uint256 precision); function queryPrecision( address sourceToken, address destToken) external view returns (uint256 precision); function queryReturn( address sourceToken, address destToken, uint256 sourceAmount) external view returns (uint256 destAmount); function checkPriceDisagreement( address sourceToken, address destToken, uint256 sourceAmount, uint256 destAmount, uint256 maxSlippage) external view returns (uint256 sourceToDestSwapRate); function amountInEth( address Token, uint256 amount) external view returns (uint256 ethAmount); function getMaxDrawdown( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount, uint256 maintenanceMargin) external view returns (uint256); function getCurrentMarginAndCollateralSize( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount) external view returns (uint256 currentMargin, uint256 collateralInEthAmount); function getCurrentMargin( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount) external view returns (uint256 currentMargin, uint256 collateralToLoanRate); function shouldLiquidate( address loanToken, address collateralToken, uint256 loanAmount, uint256 collateralAmount, uint256 maintenanceMargin) external view returns (bool); function getFastGasPrice( address payToken) external view returns (uint256); }
{ "evmVersion": "istanbul", "optimizer": { "enabled": true, "runs": 200 }, "libraries": { "LoanTokenLogicStandard.sol": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"burner","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"borrower","type":"address"},{"indexed":false,"internalType":"address","name":"target","type":"address"},{"indexed":false,"internalType":"address","name":"loanToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"loanAmount","type":"uint256"}],"name":"FlashBorrow","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":true,"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes4","name":"sig","type":"bytes4"}],"name":"_isPaused","outputs":[{"internalType":"bool","name":"isPaused","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"totalBorrow","type":"uint256"},{"internalType":"uint256","name":"newBorrowNotYetRealized","type":"uint256"},{"internalType":"uint256","name":"lastIR","type":"uint256"}],"name":"_nextBorrowInterestRate","outputs":[{"internalType":"uint256","name":"nextRate","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"nextBorrowRate","type":"uint256"},{"internalType":"uint256","name":"assetBorrow","type":"uint256"},{"internalType":"uint256","name":"assetSupply","type":"uint256"}],"name":"_nextSupplyInterestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"assetBalanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"bZxContract","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"loanId","type":"bytes32"},{"internalType":"uint256","name":"withdrawAmount","type":"uint256"},{"internalType":"uint256","name":"initialLoanDuration","type":"uint256"},{"internalType":"uint256","name":"collateralTokenSent","type":"uint256"},{"internalType":"address","name":"collateralTokenAddress","type":"address"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"borrow","outputs":[{"components":[{"internalType":"bytes32","name":"loanId","type":"bytes32"},{"internalType":"uint256","name":"principal","type":"uint256"},{"internalType":"uint256","name":"collateral","type":"uint256"}],"internalType":"struct IBZx.LoanOpenData","name":"","type":"tuple"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"borrowInterestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"burnAmount","type":"uint256"}],"name":"burn","outputs":[{"internalType":"uint256","name":"loanAmountPaid","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newGuardian","type":"address"}],"name":"changeGuardian","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"checkpointPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_subtractedValue","type":"uint256"}],"name":"decreaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"borrowAmount","type":"uint256"},{"internalType":"address","name":"borrower","type":"address"},{"internalType":"address","name":"target","type":"address"},{"internalType":"string","name":"signature","type":"string"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"flashBorrow","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"flashBorrowFeePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"depositAmount","type":"uint256"},{"internalType":"uint256","name":"initialLoanDuration","type":"uint256"},{"internalType":"address","name":"collateralTokenAddress","type":"address"}],"name":"getBorrowAmountForDeposit","outputs":[{"internalType":"uint256","name":"borrowAmount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"borrowAmount","type":"uint256"},{"internalType":"uint256","name":"initialLoanDuration","type":"uint256"},{"internalType":"address","name":"collateralTokenAddress","type":"address"}],"name":"getDepositAmountForBorrow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getGuardian","outputs":[{"internalType":"address","name":"guardian","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getPoolUtilization","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_addedValue","type":"uint256"}],"name":"increaseApproval","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"initialPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"loanParamsIds","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"loanTokenAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"loanId","type":"bytes32"},{"internalType":"uint256","name":"leverageAmount","type":"uint256"},{"internalType":"uint256","name":"loanTokenSent","type":"uint256"},{"internalType":"uint256","name":"collateralTokenSent","type":"uint256"},{"internalType":"address","name":"collateralTokenAddress","type":"address"},{"internalType":"address","name":"trader","type":"address"},{"internalType":"bytes","name":"loanDataBytes","type":"bytes"}],"name":"marginTrade","outputs":[{"components":[{"internalType":"bytes32","name":"loanId","type":"bytes32"},{"internalType":"uint256","name":"principal","type":"uint256"},{"internalType":"uint256","name":"collateral","type":"uint256"}],"internalType":"struct IBZx.LoanOpenData","name":"","type":"tuple"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"depositAmount","type":"uint256"}],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"borrowAmount","type":"uint256"}],"name":"nextBorrowInterestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"int256","name":"supplyAmount","type":"int256"}],"name":"nextSupplyInterestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes4[]","name":"sig","type":"bytes4[]"}],"name":"pause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"poolLastInterestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"poolTWAI","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"profitOf","outputs":[{"internalType":"int256","name":"","type":"int256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"renounceOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"supplyInterestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes4","name":"sig","type":"bytes4"}],"name":"toggleFunctionPause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes4","name":"sig","type":"bytes4"}],"name":"toggleFunctionUnPause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"tokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalAssetBorrow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalAssetSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes4[]","name":"sig","type":"bytes4[]"}],"name":"unpause","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"newFeePercent","type":"uint256"}],"name":"updateFlashBorrowFeePercent","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"settingsTarget","type":"address"},{"internalType":"bytes","name":"callData","type":"bytes"}],"name":"updateSettings","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"wethToken","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405260016000553480156200001657600080fd5b5060006200002c6001600160e01b036200008216565b600180546001600160a01b0319166001600160a01b0383169081179091556040519192509060009060008051602062004ca8833981519152908290a3506200007c6001600160e01b036200008616565b62000187565b3390565b620000996001600160e01b03620000fa16565b620000c15760405162461bcd60e51b8152600401620000b89062000166565b60405180910390fd5b6001546040516000916001600160a01b03169060008051602062004ca8833981519152908390a3600180546001600160a01b0319169055565b6001546000906001600160a01b03166200011c6001600160e01b036200008216565b6001600160a01b031614905090565b60006200013a6020836200017e565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b6020808252810162000178816200012b565b92915050565b90815260200190565b614b1180620001976000396000f3fe60806040526004361061031a5760003560e01c8063715018a6116101ab578063ac544a04116100f7578063dd62ed3e11610095578063f2fde38b1161006f578063f2fde38b146108c1578063f8ddf397146108e1578063f96b660a14610901578063ffa1ad74146109215761031a565b8063dd62ed3e14610861578063eebc508114610881578063ef4e1fe4146108a15761031a565b8063bf7d653b116100d1578063bf7d653b146107f9578063c5bf0e9d1461080e578063c674184f14610821578063d73dd623146108415761031a565b8063ac544a04146107a4578063b9fe1a8f146107c4578063baa7719c146107e45761031a565b80638fb807c5116101645780639dc29fac1161013e5780639dc29fac1461072f578063a75b87d21461074f578063a9059cbb14610764578063ab3d9ffa146107845761031a565b80638fb807c5146106f057806395d89b4114610705578063995363d31461071a5761031a565b8063715018a614610672578063797bf385146106875780637ff9b5961461069c5780638325a1c0146106b15780638da5cb5b146106c65780638f32d59b146106db5761031a565b8063284e2f561161026a57806340c10f1911610223578063631a3ef8116101fd578063631a3ef8146105f257806366188463146106125780636a8cb4c61461063257806370a08231146106525761031a565b806340c10f19146105905780634b57b0be146105b057806354198ce9146105d25761031a565b8063284e2f56146104db5780632ea295fa146104fb5780632fcb4f041461050e578063313ce5671461052e578063323e35b1146105505780633291c11a146105705761031a565b80630ae1dc65116102d757806318160ddd116102b157806318160ddd1461047c5780631d0806ae1461049157806320f6d07c146104a657806323b872dd146104bb5761031a565b80630ae1dc65146104275780630d198dd71461043c57806314dfe7921461045c5761031a565b8063047979301461035857806306b3efd61461038e57806306fdde03146103ae578063095ea7b3146103d057806309ec6b6b146103fd5780630a24cdce14610412575b3373c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2146103565760405162461bcd60e51b815260040161034d906148a8565b60405180910390fd5b005b34801561036457600080fd5b50610378610373366004613ccc565b610936565b604051610385919061467c565b60405180910390f35b34801561039a57600080fd5b506103786103a936600461385f565b610a4b565b3480156103ba57600080fd5b506103c3610a8d565b6040516103859190614717565b3480156103dc57600080fd5b506103f06103eb36600461396a565b610b18565b604051610385919061466e565b34801561040957600080fd5b50610378610b83565b34801561041e57600080fd5b50610378610bb1565b34801561043357600080fd5b50610378610bb7565b34801561044857600080fd5b50610356610457366004613b94565b610c40565b61046f61046a366004613ac2565b610c69565b6040516103859190614938565b34801561048857600080fd5b50610378610ced565b34801561049d57600080fd5b50610378610cf3565b3480156104b257600080fd5b50610378610cf9565b3480156104c757600080fd5b506103f06104d63660046138d5565b610d2f565b3480156104e757600080fd5b506103566104f6366004613922565b610d6a565b61046f6105093660046139fa565b610eb0565b34801561051a57600080fd5b5061035661052936600461385f565b610f45565b34801561053a57600080fd5b50610543610fc4565b6040516103859190614946565b34801561055c57600080fd5b5061035661056b366004613b76565b610fcd565b34801561057c57600080fd5b5061037861058b366004613b94565b61107e565b34801561059c57600080fd5b506103786105ab36600461396a565b611090565b3480156105bc57600080fd5b506105c5611106565b6040516103859190614569565b3480156105de57600080fd5b506103786105ed36600461385f565b61111e565b3480156105fe57600080fd5b5061037861060d366004613ccc565b6111bf565b34801561061e57600080fd5b506103f061062d36600461396a565b6112de565b34801561063e57600080fd5b506103f061064d366004613b76565b611381565b34801561065e57600080fd5b5061037861066d36600461385f565b6113da565b34801561067e57600080fd5b506103566113f5565b34801561069357600080fd5b506105c5611463565b3480156106a857600080fd5b50610378611479565b3480156106bd57600080fd5b50610378611493565b3480156106d257600080fd5b506105c56114aa565b3480156106e757600080fd5b506103f06114b9565b3480156106fc57600080fd5b506103786114df565b34801561071157600080fd5b506103c36114ec565b34801561072657600080fd5b506105c5611547565b34801561073b57600080fd5b5061037861074a36600461396a565b611559565b34801561075b57600080fd5b506105c5611602565b34801561077057600080fd5b506103f061077f36600461396a565b611627565b34801561079057600080fd5b5061035661079f366004613b76565b611637565b3480156107b057600080fd5b506103566107bf36600461399a565b6116e8565b3480156107d057600080fd5b506103786107df366004613b94565b61177f565b3480156107f057600080fd5b50610378611795565b34801561080557600080fd5b506103786117c9565b6103c361081c366004613bee565b6117e8565b34801561082d57600080fd5b5061037861083c366004613b94565b611b49565b34801561084d57600080fd5b506103f061085c36600461396a565b611bb1565b34801561086d57600080fd5b5061037861087c36600461389b565b611c42565b34801561088d57600080fd5b5061037861089c36600461385f565b611c6d565b3480156108ad57600080fd5b506103786108bc366004613d0f565b611c88565b3480156108cd57600080fd5b506103566108dc36600461385f565b611d5b565b3480156108ed57600080fd5b506103566108fc36600461399a565b611d8b565b34801561090d57600080fd5b5061037861091c366004613d0f565b611e1d565b34801561092d57600080fd5b50610378611ec8565b60008315610a44576001600160a01b0382166109645773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291505b600080516020614aaf8339815191526001600160a01b03166365df83f6600f60008560016040516020016109999291906144cb565b6040516020818303038152906040528051906020012060001c815260200190815260200160002054866040518363ffffffff1660e01b81526004016109df9291906146fb565b60206040518083038186803b1580156109f757600080fd5b505afa158015610a0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a2f9190810190613bd0565b9050610a39611ecd565b811115610a44575060005b9392505050565b6000610a85670de0b6b3a7640000610a79610a64611479565b610a6d866113da565b9063ffffffff611f0516565b9063ffffffff611f3f16565b90505b919050565b6002805460408051602060018416156101000260001901909316849004601f81018490048402820184019092528181529291830182828015610b105780601f10610ae557610100808354040283529160200191610b10565b820191906000526020600020905b815481529060010190602001808311610af357829003601f168201915b505050505081565b3360008181526012602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610b7190869061467c565b60405180910390a35060015b92915050565b600080610b8e611f81565b9050610bab610ba182600061091c610bb7565b826108bc84611fb5565b91505090565b60155481565b6040516359418b1560e11b8152600090600080516020614aaf8339815191529063b283162a90610beb903090600401614577565b60206040518083038186803b158015610c0357600080fd5b505afa158015610c17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c3b9190810190613bd0565b905090565b610c486114b9565b610c645760405162461bcd60e51b815260040161034d90614868565b601555565b610c71613683565b600160005414610c935760405162461bcd60e51b815260040161034d906148c8565b6002600081905550610cb06000356001600160e01b031916611381565b15610ccd5760405162461bcd60e51b815260040161034d90614928565b610cdc88888888888888611fc9565b600160005598975050505050505050565b60135490565b600e5481565b60405163250f447f60e11b8152600090600080516020614aaf83398151915290634a1e88fe90610beb9030908590600401614585565b6001600160a01b0383166000908152601260209081526040808320338452909152812054610d62908590859085906121e8565b949350505050565b610d726114aa565b6001600160a01b0316336001600160a01b031614610e03577f7ad06df6a0af6bd602d90db766e0d5f253b45187c3717a0f9026ea8b10ff0d4b547f34b31cff1dbd8374124bd4505521fc29cab0f9554a5386ba7d784a4e611c7e3154336001600160a01b038316148015610df75750806001600160a01b0316846001600160a01b0316145b610e0057600080fd5b50505b601480546001600160a01b038481166001600160a01b03198316179092556040519116906000903090610e3790859061455d565b6000604051808303816000865af19150503d8060008114610e74576040519150601f19603f3d011682016040523d82523d6000602084013e610e79565b606091505b50506040519091503d90816000823e82610e91578181fd5b601480546001600160a01b0319166001600160a01b0386161790558181f35b610eb8613683565b600160005414610eda5760405162461bcd60e51b815260040161034d906148c8565b6002600081905550610ef76000356001600160e01b031916611381565b15610f145760405162461bcd60e51b815260040161034d90614928565b610f338989898989898960405180602001604052806000815250612389565b60016000559998505050505050505050565b610f4d611602565b6001600160a01b0316336001600160a01b03161480610f845750610f6f6114aa565b6001600160a01b0316336001600160a01b0316145b610fa05760405162461bcd60e51b815260040161034d90614848565b7f80e6706973d0c59541550537fd6a33b971efad732635e6c3b99fb01006803cdf55565b60045460ff1681565b610fd5611602565b6001600160a01b0316336001600160a01b0316148061100c5750610ff76114aa565b6001600160a01b0316336001600160a01b0316145b6110285760405162461bcd60e51b815260040161034d90614848565b60405160009061105e9083907fa7143c84d793a15503da6f19bf9119a2dac94448ca45d77c8bf08f57b2e9104790602001614517565b604051602081830303815290604052805190602001209050600081555050565b600f6020526000908152604090205481565b60006001600054146110b45760405162461bcd60e51b815260040161034d906148c8565b60026000819055506110d16000356001600160e01b031916611381565b156110ee5760405162461bcd60e51b815260040161034d90614928565b6110f883836125ae565b90505b600160005592915050565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600080827f37aa2b7d583612f016e4a4de4292cb015139b3d7762663d06a53964912ea2fb660001b6040516020016111579291906144f1565b604051602081830303815290604052805190602001209050610a448160116000866001600160a01b03166001600160a01b03168152602001908152602001600020546111a1611479565b6001600160a01b03871660009081526010602052604090205461273f565b60008315610a44576111cf611ecd565b8411610a44576001600160a01b0382166111fb5773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291505b6112d7600a600080516020614aaf8339815191526001600160a01b03166313814ca4600f60008760016040516020016112359291906144cb565b6040516020818303038152906040528051906020012060001c815260200190815260200160002054886040518363ffffffff1660e01b815260040161127b9291906146fb565b60206040518083038186803b15801561129357600080fd5b505afa1580156112a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112cb9190810190613bd0565b9063ffffffff61279916565b9050610a44565b3360009081526012602090815260408083206001600160a01b038616845290915281205480831061131157506000611315565b8290035b3360008181526012602090815260408083206001600160a01b03891680855292529182902084905590519091907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061136f90859061467c565b60405180910390a35060019392505050565b600080827fa7143c84d793a15503da6f19bf9119a2dac94448ca45d77c8bf08f57b2e9104760001b6040516020016113ba929190614517565b60408051601f198184030181529190528051602090910120549392505050565b6001600160a01b031660009081526011602052604090205490565b6113fd6114b9565b6114195760405162461bcd60e51b815260040161034d90614868565b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b600454600160601b90046001600160a01b031681565b6000610c3b61148e611489610cf9565b611fb5565b6127be565b6000610c3b6114a0611f81565b600061091c610bb7565b6001546001600160a01b031690565b6001546000906001600160a01b03166114d06127ed565b6001600160a01b031614905090565b6000610c3b611489610cf9565b6003805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610b105780601f10610ae557610100808354040283529160200191610b10565b600080516020614aaf83398151915281565b600060016000541461157d5760405162461bcd60e51b815260040161034d906148c8565b600260008190555061159a6000356001600160e01b031916611381565b156115b75760405162461bcd60e51b815260040161034d90614928565b6115c0826127f1565b905080156110fb576110fb6004600c9054906101000a90046001600160a01b03168483604051806040016040528060018152602001603560f81b815250612919565b7f80e6706973d0c59541550537fd6a33b971efad732635e6c3b99fb01006803cdf5490565b6000610a443384846000196121e8565b61163f611602565b6001600160a01b0316336001600160a01b0316148061167657506116616114aa565b6001600160a01b0316336001600160a01b0316145b6116925760405162461bcd60e51b815260040161034d90614848565b6040516000906116c89083907fa7143c84d793a15503da6f19bf9119a2dac94448ca45d77c8bf08f57b2e9104790602001614517565b604051602081830303815290604052805190602001209050600181555050565b6116f0611602565b6001600160a01b0316336001600160a01b0316148061172757506117126114aa565b6001600160a01b0316336001600160a01b0316145b6117435760405162461bcd60e51b815260040161034d90614848565b60005b8181101561177a5761177283838381811061175d57fe5b905060200201602061056b9190810190613b76565b600101611746565b505050565b6000610a8561178c610cf9565b8361091c610bb7565b604051635c3ef8ad60e11b8152600090600080516020614aaf8339815191529063b87df15a90610beb903090600401614577565b6000806117d4610cf9565b9050610bab816117e383611fb5565b612979565b606060016000541461180c5760405162461bcd60e51b815260040161034d906148c8565b60026000819055506118296000356001600160e01b031916611381565b156118465760405162461bcd60e51b815260040161034d90614928565b876118635760405162461bcd60e51b815260040161034d906148d8565b61186d60006129a5565b600061187f473463ffffffff612a0b16565b9050600061189661188e611f81565b6112cb611ecd565b905080600c819055506118da6004600c9054906101000a90046001600160a01b03168a8c60405180604001604052806002815260200161333960f01b815250612919565b7fc688ff9bd4a1c369dd44c5cf64efa9db6652fb6b280aa765cd43f17d256b816e89896004600c9054906101000a90046001600160a01b03168d60405161192494939291906145bb565b60405180910390a16060866119725785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293506119ad92505050565b8787604051611982929190614550565b60405190819003812061199b9188908890602001614533565b60405160208183030381529060405290505b60006060720f400e6818158d541c3ebe45fe3aa0d47372ff6001600160a01b03163463de064e0d8d866040516024016119e7929190614618565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051611a20919061455d565b60006040518083038185875af1925050503d8060008114611a5d576040519150601f19603f3d011682016040523d82523d6000602084013e611a62565b606091505b509150915081611a845760405162461bcd60e51b815260040161034d90614888565b6000600c81905550600080516020614aaf8339815191526001600160a01b031663392544838d8f6015546040518463ffffffff1660e01b8152600401611acc93929190614653565b600060405180830381600087803b158015611ae657600080fd5b505af1158015611afa573d6000803e3d6000fd5b50505050844710158015611b18575083611b1561188e611f81565b10155b611b345760405162461bcd60e51b815260040161034d906147f8565b60016000559c9b505050505050505050505050565b600080611b54610cf9565b90506000611b6182611fb5565b905060008412611b8257611b7b818563ffffffff61279916565b9050611b99565b611b9681600086900363ffffffff612a0b16565b90505b610d62611baa83600061091c610bb7565b8383611c88565b3360009081526012602090815260408083206001600160a01b03861684529091528120548190611be7908463ffffffff61279916565b3360008181526012602090815260408083206001600160a01b038a168085529252918290208490559051929350917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061136f90859061467c565b6001600160a01b03918216600090815260126020908152604080832093909416825291909152205490565b6001600160a01b031660009081526010602052604090205490565b60008215801590611c995750828210155b15610a44576112d768056bc75e2d631000008002610a79611d4168056bc75e2d63100000600080516020614aaf8339815191526001600160a01b0316634699f8466040518163ffffffff1660e01b815260040160206040518083038186803b158015611d0457600080fd5b505afa158015611d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d3c9190810190613bd0565b612a0b565b610a6d611d4e8888612979565b899063ffffffff611f0516565b611d636114b9565b611d7f5760405162461bcd60e51b815260040161034d90614868565b611d8881612a4d565b50565b611d93611602565b6001600160a01b0316336001600160a01b03161480611dca5750611db56114aa565b6001600160a01b0316336001600160a01b0316145b611de65760405162461bcd60e51b815260040161034d90614848565b60005b8181101561177a57611e15838383818110611e0057fe5b905060200201602061079f9190810190613b76565b600101611de9565b600080611e3c611e33868663ffffffff61279916565b6117e387611fb5565b601654604051635e36559360e01b81529192506001600160a01b031690635e36559390611e6f90849087906004016146fb565b60206040518083038186803b158015611e8757600080fd5b505afa158015611e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ebf9190810190613bd0565b95945050505050565b600781565b600480546040516370a0823160e01b8152600092600160601b9092046001600160a01b0316916370a0823191610beb91309101614577565b600082611f1457506000610b7d565b82820282848281611f2157fe5b0414610a445760405162461bcd60e51b815260040161034d90614838565b6000610a4483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612acf565b60405163157b9bb560e11b8152600090600080516020614aaf83398151915290632af7376a90610beb903090600401614577565b600c5480610a8857610a85826112cb611ecd565b611fd1613683565b611fe66000356001600160e01b031916611381565b156120035760405162461bcd60e51b815260040161034d90614928565b8715806120185750336001600160a01b038416145b6120345760405162461bcd60e51b815260040161034d906147c8565b61203d886129a5565b8761207457833033854260405160200161205b959493929190614472565b6040516020818303038152906040528051906020012097505b6001600160a01b03841661209a5773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc293505b6004546001600160a01b03858116600160601b9092041614156120cf5760405162461bcd60e51b815260040161034d906147b8565b6120d76136a7565b6120df6136c5565b3082526001600160a01b0385166020830181905260408301526060810188905260808101879052600080612115888a8c8e612b06565b602087019390935293509091508290506121415760405162461bcd60e51b815260040161034d906147e8565b6121518c60008d8b88888c612b65565b8051909550600080516020614aaf8339815191529063b1bb8225908461218985610a7983670de0b6b3a764000063ffffffff611f0516565b6040518463ffffffff1660e01b81526004016121a793929190614709565b600060405180830381600087803b1580156121c157600080fd5b505af11580156121d5573d6000803e3d6000fd5b5050505050505050979650505050505050565b60006000198214612244576040805180820190915260028152610c4d60f21b602082015261221f908390859063ffffffff612d2f16565b6001600160a01b03861660009081526012602090815260408083203384529091529020555b6001600160a01b03841661226a5760405162461bcd60e51b815260040161034d90614738565b6001600160a01b03851660009081526011602090815260408083205481518083019092526002825261189b60f11b928201929092529091906122b5908390879063ffffffff612d2f16565b6001600160a01b038089166000908152601160205260408082208490559189168152908120549192506122ee828863ffffffff61279916565b6001600160a01b0389166000908152601160205260408120829055909150612314611479565b90506123228a868684612d5b565b61232e89848484612d5b565b886001600160a01b03168a6001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8a604051612371919061467c565b60405180910390a35060019998505050505050505050565b612391613683565b6123a66000356001600160e01b031916611381565b156123c35760405162461bcd60e51b815260040161034d90614928565b876123e05760405162461bcd60e51b815260040161034d906148f8565b3415806123ec57508534145b6124085760405162461bcd60e51b815260040161034d90614778565b8515158061241557508815155b6124315760405162461bcd60e51b815260040161034d90614908565b6001600160a01b03851615158061244757503415155b8061245157508815155b61246d5760405162461bcd60e51b815260040161034d906148b8565b8815806124825750336001600160a01b038516145b61249e5760405162461bcd60e51b815260040161034d906147c8565b6124a7896129a5565b886124de5784303386426040516020016124c5959493929190614472565b6040516020818303038152906040528051906020012098505b6001600160a01b0385166125045773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc294505b6004546001600160a01b03868116600160601b9092041614156125395760405162461bcd60e51b815260040161034d90614728565b6125416136a7565b6125496136c5565b3082526001600160a01b03868116602080850191909152908616604080850191909152608083018a90528282018c90526000838201819052815192830190915280825261259f918d918d918b9087908790612b65565b9b9a5050505050505050505050565b60006125c56000356001600160e01b031916611381565b156125e25760405162461bcd60e51b815260040161034d90614928565b816125ff5760405162461bcd60e51b815260040161034d90614818565b61260960006129a5565b600061261961148e611489611f81565b905061263781610a7985670de0b6b3a764000063ffffffff611f0516565b91503461267f5761267a6004600c9054906101000a90046001600160a01b031633308660405180604001604052806002815260200161062760f31b815250612e11565b612707565b82341461269e5760405162461bcd60e51b815260040161034d90614828565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b1580156126ed57600080fd5b505af1158015612701573d6000803e3d6000fd5b50505050505b6001600160a01b03841660009081526011602052604090205461273890859061273282868887612e35565b84612d5b565b5092915050565b60008161274e57506000610d62565b508354611ebf8161278d670de0b6b3a764000061278188612775898963ffffffff612f5616565b9063ffffffff612f9c16565b9063ffffffff61300716565b9063ffffffff61306b16565b600082820183811015610a445760405162461bcd60e51b815260040161034d90614758565b601354600090806127d157600e54610a44565b610a4481610a7985670de0b6b3a764000063ffffffff611f0516565b3390565b60006128086000356001600160e01b031916611381565b156128255760405162461bcd60e51b815260040161034d90614928565b816128425760405162461bcd60e51b815260040161034d90614858565b61284c60006129a5565b612855336113da565b82111561288957600019821461287d5760405162461bcd60e51b815260040161034d90614808565b612886336113da565b91505b600061289961148e611489611f81565b905060006128b9670de0b6b3a7640000610a79868563ffffffff611f0516565b905060006128c5611ecd565b9050819350808411156128ea5760405162461bcd60e51b815260040161034d90614788565b33600081815260116020526040902054612911919061290b828989896130b1565b86612d5b565b505050919050565b60405161297390859063a9059cbb60e01b9061293b9087908790602401614638565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152836131d6565b50505050565b60008115610b7d5761299e82610a798568056bc75e2d6310000063ffffffff611f0516565b9050610b7d565b60405163789b79bf60e11b8152600080516020614aaf8339815191529063f136f37e906129d690849060040161467c565b600060405180830381600087803b1580156129f057600080fd5b505af1158015612a04573d6000803e3d6000fd5b5050505050565b6000610a4483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612d2f565b6001600160a01b038116612a735760405162461bcd60e51b815260040161034d90614748565b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008183612af05760405162461bcd60e51b815260040161034d9190614717565b506000838581612afc57fe5b0495945050505050565b600080600080612b1788888861329c565b90925090506000612b386f4b3b4ca85a86c47a098a22400000000087611f3f565b9050612b5781610a798568056bc75e2d6310000063ffffffff611f0516565b945050945094509450949050565b612b6d613683565b612b75611ecd565b602084015111801590612b94575060208401516001600160a01b031615155b612bb05760405162461bcd60e51b815260040161034d90614798565b60408401516001600160a01b0316612bd65760208401516001600160a01b031660408501525b6000612be48686868b61342c565b60208501516060860151919250612bfb9190612799565b60608501528715612c1b576060840151612c159089612a0b565b60608501525b600088612c29576000612c2c565b60015b90506000600f60008984604051602001612c479291906144cb565b6040516020818303038152906040528051906020012060001c815260200190815260200160002054905088600014612c9657612c936f4b3b4ca85a86c47a098a2240000000008a611f3f565b98505b600080516020614aaf8339815191526001600160a01b031663585314cf84838e868e8d8d8d6040518963ffffffff1660e01b8152600401612cdd979695949392919061468a565b6060604051808303818588803b158015612cf657600080fd5b505af1158015612d0a573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525061259f9190810190613bb2565b60008184841115612d535760405162461bcd60e51b815260040161034d9190614717565b505050900390565b604051600090612d919086907f37aa2b7d583612f016e4a4de4292cb015139b3d7762663d06a53964912ea2fb6906020016144f1565b60405160208183030381529060405280519060200120905060008360001415612dbd5760009250612dee565b8415612dee576001600160a01b038616600090815260106020526040902054612deb9083908790869061273f565b90505b90556001600160a01b039093166000908152601060205260409020929092555050565b604051612a049086906323b872dd60e01b9061293b908890889088906024016145f0565b60006001600160a01b038516612e5d5760405162461bcd60e51b815260040161034d90614738565b6001600160a01b038516600090815260116020526040812054612e86908663ffffffff61279916565b6001600160a01b0387166000908152601160205260409020819055601354909150612eb7908663ffffffff61279916565b6013556040516001600160a01b038716907fb4c03061fb5b7fed76389d5af8f2e0ddb09f8c70d1333abbb62582835e10accb90612ef990889088908890614709565b60405180910390a2856001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef87604051612f45919061467c565b60405180910390a395945050505050565b6000818303818312801590612f6b5750838113155b80612f805750600083128015612f8057508381135b610a445760405162461bcd60e51b815260040161034d906148e8565b600082612fab57506000610b7d565b82600019148015612fbf5750600160ff1b82145b15612fdc5760405162461bcd60e51b815260040161034d90614898565b82820282848281612fe957fe5b0514610a445760405162461bcd60e51b815260040161034d90614898565b6000816130265760405162461bcd60e51b815260040161034d90614918565b8160001914801561303a5750600160ff1b83145b156130575760405162461bcd60e51b815260040161034d906147d8565b600082848161306257fe5b05949350505050565b60008282018183128015906130805750838112155b80613095575060008312801561309557508381125b610a445760405162461bcd60e51b815260040161034d90614768565b6040805180820182526002815261189b60f11b6020808301919091526001600160a01b038716600090815260119091529182205482916130f99190879063ffffffff612d2f16565b9050600a811161311a57613113858263ffffffff61279916565b9450600090505b6001600160a01b0386166000908152601160205260409020819055601354613148908663ffffffff612a0b16565b6013556040516001600160a01b038716907f743033787f4738ff4d6a7225ce2bd0977ee5f86b91a902a58f5e4d0b297b46449061318a90889088908890614709565b60405180910390a260006001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef87604051612f45919061467c565b60006060846001600160a01b0316846040516131f2919061455d565b6000604051808303816000865af19150503d806000811461322f576040519150601f19603f3d011682016040523d82523d6000602084013e613234565b606091505b50915091508183906132595760405162461bcd60e51b815260040161034d9190614717565b50805115612a04578080602001905161327591908101906139dc565b83906132945760405162461bcd60e51b815260040161034d9190614717565b505050505050565b6000806000600080516020614aaf8339815191526001600160a01b03166378d849ed6040518163ffffffff1660e01b815260040160206040518083038186803b1580156132e857600080fd5b505afa1580156132fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613320919081019061387d565b60048054604051630a7549df60e21b81526001600160a01b03938416936329d5277c9361335b938c93600160601b90910490921691016145a0565b604080518083038186803b15801561337257600080fd5b505afa158015613386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506133aa9190810190613c9c565b909250905081158015906133bd57508015155b6133d95760405162461bcd60e51b815260040161034d906147a8565b6133f581610a7984670de0b6b3a764000063ffffffff611f0516565b8493509150841561342357613420836112cb670de0b6b3a7640000610a79898763ffffffff611f0516565b92505b50935093915050565b600454604084015160208401516060850151608086015160009473c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2946001600160a01b03600160601b9092048216949093909290918b168514156134965760405162461bcd60e51b815260040161034d90614878565b3496508715613508576134c585858a60405180604001604052806002815260200161323760f01b815250612919565b878311156135035761350385600080516020614aaf8339815191528a860360405180604001604052806002815260200161323760f01b815250612919565b61353c565b61353c85600080516020614aaf8339815191528560405180604001604052806002815260200161323760f01b815250612919565b801561363a57856001600160a01b03168b6001600160a01b031614801561356257508615155b801561356e5750808710155b1561360557856001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156135ae57600080fd5b505af11580156135c2573d6000803e3d6000fd5b50505050506135fb8b600080516020614aaf8339815191528360405180604001604052806002815260200161064760f31b815250612919565b808703965061363a565b61363a8b33600080516020614aaf8339815191528460405180604001604052806002815260200161064760f31b815250612e11565b8115613675576136758533600080516020614aaf8339815191528560405180604001604052806002815260200161323960f01b815250612e11565b505050505050949350505050565b60405180606001604052806000801916815260200160008152602001600081525090565b60405180608001604052806004906020820280388339509192915050565b6040518060a001604052806005906020820280388339509192915050565b8035610b7d81614a7f565b8051610b7d81614a7f565b60008083601f84011261370b57600080fd5b50813567ffffffffffffffff81111561372357600080fd5b60208301915083602082028301111561373b57600080fd5b9250929050565b8051610b7d81614a93565b8035610b7d81614a9c565b8051610b7d81614a9c565b8035610b7d81614aa5565b60008083601f84011261378057600080fd5b50813567ffffffffffffffff81111561379857600080fd5b60208301915083600182028301111561373b57600080fd5b600082601f8301126137c157600080fd5b81356137d46137cf8261497b565b614954565b915080825260208301602083018583830111156137f057600080fd5b6137fb838284614a05565b50505092915050565b60006060828403121561381657600080fd5b6138206060614954565b9050600061382e8484613758565b825250602061383f84848301613758565b602083015250604061385384828501613758565b60408301525092915050565b60006020828403121561387157600080fd5b6000610d6284846136e3565b60006020828403121561388f57600080fd5b6000610d6284846136ee565b600080604083850312156138ae57600080fd5b60006138ba85856136e3565b92505060206138cb858286016136e3565b9150509250929050565b6000806000606084860312156138ea57600080fd5b60006138f686866136e3565b9350506020613907868287016136e3565b92505060406139188682870161374d565b9150509250925092565b6000806040838503121561393557600080fd5b600061394185856136e3565b925050602083013567ffffffffffffffff81111561395e57600080fd5b6138cb858286016137b0565b6000806040838503121561397d57600080fd5b600061398985856136e3565b92505060206138cb8582860161374d565b600080602083850312156139ad57600080fd5b823567ffffffffffffffff8111156139c457600080fd5b6139d0858286016136f9565b92509250509250929050565b6000602082840312156139ee57600080fd5b6000610d628484613742565b600080600080600080600080610100898b031215613a1757600080fd5b6000613a238b8b61374d565b9850506020613a348b828c0161374d565b9750506040613a458b828c0161374d565b9650506060613a568b828c0161374d565b9550506080613a678b828c016136e3565b94505060a0613a788b828c016136e3565b93505060c0613a898b828c016136e3565b92505060e089013567ffffffffffffffff811115613aa657600080fd5b613ab28b828c016137b0565b9150509295985092959890939650565b600080600080600080600060e0888a031215613add57600080fd5b6000613ae98a8a61374d565b9750506020613afa8a828b0161374d565b9650506040613b0b8a828b0161374d565b9550506060613b1c8a828b0161374d565b9450506080613b2d8a828b016136e3565b93505060a0613b3e8a828b016136e3565b92505060c088013567ffffffffffffffff811115613b5b57600080fd5b613b678a828b016137b0565b91505092959891949750929550565b600060208284031215613b8857600080fd5b6000610d628484613763565b600060208284031215613ba657600080fd5b6000610d62848461374d565b600060608284031215613bc457600080fd5b6000610d628484613804565b600060208284031215613be257600080fd5b6000610d628484613758565b600080600080600080600060a0888a031215613c0957600080fd5b6000613c158a8a61374d565b9750506020613c268a828b016136e3565b9650506040613c378a828b016136e3565b955050606088013567ffffffffffffffff811115613c5457600080fd5b613c608a828b0161376e565b9450945050608088013567ffffffffffffffff811115613c7f57600080fd5b613c8b8a828b0161376e565b925092505092959891949750929550565b60008060408385031215613caf57600080fd5b6000613cbb8585613758565b92505060206138cb85828601613758565b600080600060608486031215613ce157600080fd5b6000613ced868661374d565b9350506020613cfe8682870161374d565b9250506040613918868287016136e3565b600080600060608486031215613d2457600080fd5b6000613d30868661374d565b93505060206139078682870161374d565b6000613d4d8383613d81565b505060200190565b6000613d4d8383613e3c565b613d6a816149f4565b82525050565b613d6a613d7c826149c5565b614a3d565b613d6a816149c5565b613d93816149a6565b613d9d8184610a88565b9250613da8826149a3565b8060005b83811015613294578151613dc08782613d41565b9650613dcb836149b6565b925050600101613dac565b613ddf816149ac565b613de98184610a88565b9250613df4826149a3565b8060005b83811015613294578151613e0c8782613d55565b9650613e17836149b6565b925050600101613df8565b613d6a816149d0565b613d6a613e37826149d0565b614a48565b613d6a816149a3565b613d6a613e51826149a3565b6149a3565b613d6a613e51826149d5565b6000613e6e8385610a88565b9350613e7b838584614a05565b50500190565b6000613e8c826149b2565b613e9681856149bc565b9350613ea6818560208601614a11565b613eaf81614a69565b9093019392505050565b6000613ec4826149b2565b613ece8185610a88565b9350613ede818560208601614a11565b9290920192915050565b6000613ef56002836149bc565b61031360f41b815260200192915050565b6000613f136002836149bc565b61313560f01b815260200192915050565b6000613f316026836149bc565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000613f79601b836149bc565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000613fb26021836149bc565b7f5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000613ff56001836149bc565b603760f81b815260200192915050565b60006140126002836149bc565b61333760f01b815260200192915050565b60006140306002836149bc565b610c8d60f21b815260200192915050565b600061404e6002836149bc565b61032360f41b815260200192915050565b600061406c6002836149bc565b61313160f01b815260200192915050565b600061408a6002836149bc565b61313360f01b815260200192915050565b60006140a86021836149bc565b7f5369676e6564536166654d6174683a206469766973696f6e206f766572666c6f8152607760f81b602082015260400192915050565b60006140eb6002836149bc565b61189960f11b815260200192915050565b60006141096002836149bc565b61034360f41b815260200192915050565b60006141276002836149bc565b61199960f11b815260200192915050565b60006141456002836149bc565b61313760f01b815260200192915050565b60006141636002836149bc565b61062760f31b815260200192915050565b60006141816021836149bc565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b60006141c4600c836149bc565b6b1d5b985d5d1a1bdc9a5e995960a21b815260200192915050565b60006141ec6002836149bc565b61313960f01b815260200192915050565b600061420a6020836149bc565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b60006142436002836149bc565b61191b60f11b815260200192915050565b6000614261600b836149bc565b6a18d85b1b0819985a5b195960aa1b815260200192915050565b60006142886027836149bc565b7f5369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f815266766572666c6f7760c81b602082015260400192915050565b60006142d16014836149bc565b7319985b1b189858dac81b9bdd08185b1b1bddd95960621b815260200192915050565b60006143016001836149bc565b603960f81b815260200192915050565b600061431e600c836149bc565b6b1b9bdb9499595b9d1c985b9d60a21b815260200192915050565b60006143466002836149bc565b61066760f31b815260200192915050565b60006143646024836149bc565b7f5369676e6564536166654d6174683a207375627472616374696f6e206f766572815263666c6f7760e01b602082015260400192915050565b60006143aa6001836149bc565b601b60f91b815260200192915050565b60006143c76001836149bc565b600760fb1b815260200192915050565b60006143e46020836149bc565b7f5369676e6564536166654d6174683a206469766973696f6e206279207a65726f815260200192915050565b600061441d6006836149bc565b651c185d5cd95960d21b815260200192915050565b805160608301906144438482613e3c565b5060208201516144566020850182613e3c565b5060408201516129736040850182613e3c565b613d6a816149ee565b600061447e8288613d70565b60148201915061448e8287613d70565b60148201915061449e8286613d70565b6014820191506144ae8285613d70565b6014820191506144be8284613e45565b5060200195945050505050565b60006144d78285613d70565b6014820191506144e78284613e2b565b5060010192915050565b60006144fd8285613d70565b60148201915061450d8284613e45565b5060200192915050565b60006145238285613e56565b60048201915061450d8284613e45565b600061453f8286613e56565b600482019150611ebf828486613e62565b6000610d62828486613e62565b6000610a448284613eb9565b60208101610b7d8284613d81565b60208101610b7d8284613d61565b604081016145938285613d61565b610a446020830184613d61565b604081016145ae8285613d81565b610a446020830184613d81565b608081016145c98287613d81565b6145d66020830186613d81565b6145e36040830185613d81565b611ebf6060830184613e3c565b606081016145fe8286613d81565b61460b6020830185613d81565b610d626040830184613e3c565b604081016146268285613d81565b8181036020830152610d628184613e81565b604081016146468285613d81565b610a446020830184613e3c565b606081016146618286613d81565b61460b6020830185613e3c565b60208101610b7d8284613e22565b60208101610b7d8284613e3c565b6101c08101614699828a613e3c565b6146a66020830189613e3c565b6146b36040830188613e22565b6146c06060830187613e3c565b6146cd6080830186613d8a565b6146db610100830185613dd6565b8181036101a08301526146ee8184613e81565b9998505050505050505050565b604081016146468285613e3c565b606081016146618286613e3c565b60208082528101610a448184613e81565b60208082528101610a8581613ee8565b60208082528101610a8581613f06565b60208082528101610a8581613f24565b60208082528101610a8581613f6c565b60208082528101610a8581613fa5565b60208082528101610a8581613fe8565b60208082528101610a8581614005565b60208082528101610a8581614023565b60208082528101610a8581614041565b60208082528101610a858161405f565b60208082528101610a858161407d565b60208082528101610a858161409b565b60208082528101610a85816140de565b60208082528101610a85816140fc565b60208082528101610a858161411a565b60208082528101610a8581614138565b60208082528101610a8581614156565b60208082528101610a8581614174565b60208082528101610a85816141b7565b60208082528101610a85816141df565b60208082528101610a85816141fd565b60208082528101610a8581614236565b60208082528101610a8581614254565b60208082528101610a858161427b565b60208082528101610a85816142c4565b60208082528101610a85816142f4565b60208082528101610a8581614311565b60208082528101610a8581614339565b60208082528101610a8581614357565b60208082528101610a858161439d565b60208082528101610a85816143ba565b60208082528101610a85816143d7565b60208082528101610a8581614410565b60608101610b7d8284614432565b60208101610b7d8284614469565b60405181810167ffffffffffffffff8111828210171561497357600080fd5b604052919050565b600067ffffffffffffffff82111561499257600080fd5b506020601f91909101601f19160190565b90565b50600490565b50600590565b5190565b60200190565b90815260200190565b6000610a85826149e2565b151590565b6001600160e01b03191690565b6001600160a01b031690565b60ff1690565b6000610a85826000610a85826149c5565b82818337506000910152565b60005b83811015614a2c578181015183820152602001614a14565b838111156129735750506000910152565b6000610a8582614a53565b6000610a8582614a5e565b6000610a8582614a79565b6000610a8582614a73565b601f01601f191690565b60f81b90565b60601b90565b614a88816149c5565b8114611d8857600080fd5b614a88816149d0565b614a88816149a3565b614a88816149d556fe000000000000000000000000d8ee69652e4e4838f2531732a46d1f7f584f0b7fa365627a7a72315820f08d69608993c54a231668dbabc76de551d2bd4ec715ee1d77cc28b70bcb63a06c6578706572696d656e74616cf564736f6c634300051100408be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0
Deployed Bytecode
0x60806040526004361061031a5760003560e01c8063715018a6116101ab578063ac544a04116100f7578063dd62ed3e11610095578063f2fde38b1161006f578063f2fde38b146108c1578063f8ddf397146108e1578063f96b660a14610901578063ffa1ad74146109215761031a565b8063dd62ed3e14610861578063eebc508114610881578063ef4e1fe4146108a15761031a565b8063bf7d653b116100d1578063bf7d653b146107f9578063c5bf0e9d1461080e578063c674184f14610821578063d73dd623146108415761031a565b8063ac544a04146107a4578063b9fe1a8f146107c4578063baa7719c146107e45761031a565b80638fb807c5116101645780639dc29fac1161013e5780639dc29fac1461072f578063a75b87d21461074f578063a9059cbb14610764578063ab3d9ffa146107845761031a565b80638fb807c5146106f057806395d89b4114610705578063995363d31461071a5761031a565b8063715018a614610672578063797bf385146106875780637ff9b5961461069c5780638325a1c0146106b15780638da5cb5b146106c65780638f32d59b146106db5761031a565b8063284e2f561161026a57806340c10f1911610223578063631a3ef8116101fd578063631a3ef8146105f257806366188463146106125780636a8cb4c61461063257806370a08231146106525761031a565b806340c10f19146105905780634b57b0be146105b057806354198ce9146105d25761031a565b8063284e2f56146104db5780632ea295fa146104fb5780632fcb4f041461050e578063313ce5671461052e578063323e35b1146105505780633291c11a146105705761031a565b80630ae1dc65116102d757806318160ddd116102b157806318160ddd1461047c5780631d0806ae1461049157806320f6d07c146104a657806323b872dd146104bb5761031a565b80630ae1dc65146104275780630d198dd71461043c57806314dfe7921461045c5761031a565b8063047979301461035857806306b3efd61461038e57806306fdde03146103ae578063095ea7b3146103d057806309ec6b6b146103fd5780630a24cdce14610412575b3373c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2146103565760405162461bcd60e51b815260040161034d906148a8565b60405180910390fd5b005b34801561036457600080fd5b50610378610373366004613ccc565b610936565b604051610385919061467c565b60405180910390f35b34801561039a57600080fd5b506103786103a936600461385f565b610a4b565b3480156103ba57600080fd5b506103c3610a8d565b6040516103859190614717565b3480156103dc57600080fd5b506103f06103eb36600461396a565b610b18565b604051610385919061466e565b34801561040957600080fd5b50610378610b83565b34801561041e57600080fd5b50610378610bb1565b34801561043357600080fd5b50610378610bb7565b34801561044857600080fd5b50610356610457366004613b94565b610c40565b61046f61046a366004613ac2565b610c69565b6040516103859190614938565b34801561048857600080fd5b50610378610ced565b34801561049d57600080fd5b50610378610cf3565b3480156104b257600080fd5b50610378610cf9565b3480156104c757600080fd5b506103f06104d63660046138d5565b610d2f565b3480156104e757600080fd5b506103566104f6366004613922565b610d6a565b61046f6105093660046139fa565b610eb0565b34801561051a57600080fd5b5061035661052936600461385f565b610f45565b34801561053a57600080fd5b50610543610fc4565b6040516103859190614946565b34801561055c57600080fd5b5061035661056b366004613b76565b610fcd565b34801561057c57600080fd5b5061037861058b366004613b94565b61107e565b34801561059c57600080fd5b506103786105ab36600461396a565b611090565b3480156105bc57600080fd5b506105c5611106565b6040516103859190614569565b3480156105de57600080fd5b506103786105ed36600461385f565b61111e565b3480156105fe57600080fd5b5061037861060d366004613ccc565b6111bf565b34801561061e57600080fd5b506103f061062d36600461396a565b6112de565b34801561063e57600080fd5b506103f061064d366004613b76565b611381565b34801561065e57600080fd5b5061037861066d36600461385f565b6113da565b34801561067e57600080fd5b506103566113f5565b34801561069357600080fd5b506105c5611463565b3480156106a857600080fd5b50610378611479565b3480156106bd57600080fd5b50610378611493565b3480156106d257600080fd5b506105c56114aa565b3480156106e757600080fd5b506103f06114b9565b3480156106fc57600080fd5b506103786114df565b34801561071157600080fd5b506103c36114ec565b34801561072657600080fd5b506105c5611547565b34801561073b57600080fd5b5061037861074a36600461396a565b611559565b34801561075b57600080fd5b506105c5611602565b34801561077057600080fd5b506103f061077f36600461396a565b611627565b34801561079057600080fd5b5061035661079f366004613b76565b611637565b3480156107b057600080fd5b506103566107bf36600461399a565b6116e8565b3480156107d057600080fd5b506103786107df366004613b94565b61177f565b3480156107f057600080fd5b50610378611795565b34801561080557600080fd5b506103786117c9565b6103c361081c366004613bee565b6117e8565b34801561082d57600080fd5b5061037861083c366004613b94565b611b49565b34801561084d57600080fd5b506103f061085c36600461396a565b611bb1565b34801561086d57600080fd5b5061037861087c36600461389b565b611c42565b34801561088d57600080fd5b5061037861089c36600461385f565b611c6d565b3480156108ad57600080fd5b506103786108bc366004613d0f565b611c88565b3480156108cd57600080fd5b506103566108dc36600461385f565b611d5b565b3480156108ed57600080fd5b506103566108fc36600461399a565b611d8b565b34801561090d57600080fd5b5061037861091c366004613d0f565b611e1d565b34801561092d57600080fd5b50610378611ec8565b60008315610a44576001600160a01b0382166109645773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291505b600080516020614aaf8339815191526001600160a01b03166365df83f6600f60008560016040516020016109999291906144cb565b6040516020818303038152906040528051906020012060001c815260200190815260200160002054866040518363ffffffff1660e01b81526004016109df9291906146fb565b60206040518083038186803b1580156109f757600080fd5b505afa158015610a0b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a2f9190810190613bd0565b9050610a39611ecd565b811115610a44575060005b9392505050565b6000610a85670de0b6b3a7640000610a79610a64611479565b610a6d866113da565b9063ffffffff611f0516565b9063ffffffff611f3f16565b90505b919050565b6002805460408051602060018416156101000260001901909316849004601f81018490048402820184019092528181529291830182828015610b105780601f10610ae557610100808354040283529160200191610b10565b820191906000526020600020905b815481529060010190602001808311610af357829003601f168201915b505050505081565b3360008181526012602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610b7190869061467c565b60405180910390a35060015b92915050565b600080610b8e611f81565b9050610bab610ba182600061091c610bb7565b826108bc84611fb5565b91505090565b60155481565b6040516359418b1560e11b8152600090600080516020614aaf8339815191529063b283162a90610beb903090600401614577565b60206040518083038186803b158015610c0357600080fd5b505afa158015610c17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610c3b9190810190613bd0565b905090565b610c486114b9565b610c645760405162461bcd60e51b815260040161034d90614868565b601555565b610c71613683565b600160005414610c935760405162461bcd60e51b815260040161034d906148c8565b6002600081905550610cb06000356001600160e01b031916611381565b15610ccd5760405162461bcd60e51b815260040161034d90614928565b610cdc88888888888888611fc9565b600160005598975050505050505050565b60135490565b600e5481565b60405163250f447f60e11b8152600090600080516020614aaf83398151915290634a1e88fe90610beb9030908590600401614585565b6001600160a01b0383166000908152601260209081526040808320338452909152812054610d62908590859085906121e8565b949350505050565b610d726114aa565b6001600160a01b0316336001600160a01b031614610e03577f7ad06df6a0af6bd602d90db766e0d5f253b45187c3717a0f9026ea8b10ff0d4b547f34b31cff1dbd8374124bd4505521fc29cab0f9554a5386ba7d784a4e611c7e3154336001600160a01b038316148015610df75750806001600160a01b0316846001600160a01b0316145b610e0057600080fd5b50505b601480546001600160a01b038481166001600160a01b03198316179092556040519116906000903090610e3790859061455d565b6000604051808303816000865af19150503d8060008114610e74576040519150601f19603f3d011682016040523d82523d6000602084013e610e79565b606091505b50506040519091503d90816000823e82610e91578181fd5b601480546001600160a01b0319166001600160a01b0386161790558181f35b610eb8613683565b600160005414610eda5760405162461bcd60e51b815260040161034d906148c8565b6002600081905550610ef76000356001600160e01b031916611381565b15610f145760405162461bcd60e51b815260040161034d90614928565b610f338989898989898960405180602001604052806000815250612389565b60016000559998505050505050505050565b610f4d611602565b6001600160a01b0316336001600160a01b03161480610f845750610f6f6114aa565b6001600160a01b0316336001600160a01b0316145b610fa05760405162461bcd60e51b815260040161034d90614848565b7f80e6706973d0c59541550537fd6a33b971efad732635e6c3b99fb01006803cdf55565b60045460ff1681565b610fd5611602565b6001600160a01b0316336001600160a01b0316148061100c5750610ff76114aa565b6001600160a01b0316336001600160a01b0316145b6110285760405162461bcd60e51b815260040161034d90614848565b60405160009061105e9083907fa7143c84d793a15503da6f19bf9119a2dac94448ca45d77c8bf08f57b2e9104790602001614517565b604051602081830303815290604052805190602001209050600081555050565b600f6020526000908152604090205481565b60006001600054146110b45760405162461bcd60e51b815260040161034d906148c8565b60026000819055506110d16000356001600160e01b031916611381565b156110ee5760405162461bcd60e51b815260040161034d90614928565b6110f883836125ae565b90505b600160005592915050565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc281565b600080827f37aa2b7d583612f016e4a4de4292cb015139b3d7762663d06a53964912ea2fb660001b6040516020016111579291906144f1565b604051602081830303815290604052805190602001209050610a448160116000866001600160a01b03166001600160a01b03168152602001908152602001600020546111a1611479565b6001600160a01b03871660009081526010602052604090205461273f565b60008315610a44576111cf611ecd565b8411610a44576001600160a01b0382166111fb5773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc291505b6112d7600a600080516020614aaf8339815191526001600160a01b03166313814ca4600f60008760016040516020016112359291906144cb565b6040516020818303038152906040528051906020012060001c815260200190815260200160002054886040518363ffffffff1660e01b815260040161127b9291906146fb565b60206040518083038186803b15801561129357600080fd5b505afa1580156112a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506112cb9190810190613bd0565b9063ffffffff61279916565b9050610a44565b3360009081526012602090815260408083206001600160a01b038616845290915281205480831061131157506000611315565b8290035b3360008181526012602090815260408083206001600160a01b03891680855292529182902084905590519091907f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061136f90859061467c565b60405180910390a35060019392505050565b600080827fa7143c84d793a15503da6f19bf9119a2dac94448ca45d77c8bf08f57b2e9104760001b6040516020016113ba929190614517565b60408051601f198184030181529190528051602090910120549392505050565b6001600160a01b031660009081526011602052604090205490565b6113fd6114b9565b6114195760405162461bcd60e51b815260040161034d90614868565b6001546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600180546001600160a01b0319169055565b600454600160601b90046001600160a01b031681565b6000610c3b61148e611489610cf9565b611fb5565b6127be565b6000610c3b6114a0611f81565b600061091c610bb7565b6001546001600160a01b031690565b6001546000906001600160a01b03166114d06127ed565b6001600160a01b031614905090565b6000610c3b611489610cf9565b6003805460408051602060026001851615610100026000190190941693909304601f81018490048402820184019092528181529291830182828015610b105780601f10610ae557610100808354040283529160200191610b10565b600080516020614aaf83398151915281565b600060016000541461157d5760405162461bcd60e51b815260040161034d906148c8565b600260008190555061159a6000356001600160e01b031916611381565b156115b75760405162461bcd60e51b815260040161034d90614928565b6115c0826127f1565b905080156110fb576110fb6004600c9054906101000a90046001600160a01b03168483604051806040016040528060018152602001603560f81b815250612919565b7f80e6706973d0c59541550537fd6a33b971efad732635e6c3b99fb01006803cdf5490565b6000610a443384846000196121e8565b61163f611602565b6001600160a01b0316336001600160a01b0316148061167657506116616114aa565b6001600160a01b0316336001600160a01b0316145b6116925760405162461bcd60e51b815260040161034d90614848565b6040516000906116c89083907fa7143c84d793a15503da6f19bf9119a2dac94448ca45d77c8bf08f57b2e9104790602001614517565b604051602081830303815290604052805190602001209050600181555050565b6116f0611602565b6001600160a01b0316336001600160a01b0316148061172757506117126114aa565b6001600160a01b0316336001600160a01b0316145b6117435760405162461bcd60e51b815260040161034d90614848565b60005b8181101561177a5761177283838381811061175d57fe5b905060200201602061056b9190810190613b76565b600101611746565b505050565b6000610a8561178c610cf9565b8361091c610bb7565b604051635c3ef8ad60e11b8152600090600080516020614aaf8339815191529063b87df15a90610beb903090600401614577565b6000806117d4610cf9565b9050610bab816117e383611fb5565b612979565b606060016000541461180c5760405162461bcd60e51b815260040161034d906148c8565b60026000819055506118296000356001600160e01b031916611381565b156118465760405162461bcd60e51b815260040161034d90614928565b876118635760405162461bcd60e51b815260040161034d906148d8565b61186d60006129a5565b600061187f473463ffffffff612a0b16565b9050600061189661188e611f81565b6112cb611ecd565b905080600c819055506118da6004600c9054906101000a90046001600160a01b03168a8c60405180604001604052806002815260200161333960f01b815250612919565b7fc688ff9bd4a1c369dd44c5cf64efa9db6652fb6b280aa765cd43f17d256b816e89896004600c9054906101000a90046001600160a01b03168d60405161192494939291906145bb565b60405180910390a16060866119725785858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152509293506119ad92505050565b8787604051611982929190614550565b60405190819003812061199b9188908890602001614533565b60405160208183030381529060405290505b60006060720f400e6818158d541c3ebe45fe3aa0d47372ff6001600160a01b03163463de064e0d8d866040516024016119e7929190614618565b6040516020818303038152906040529060e01b6020820180516001600160e01b038381831617835250505050604051611a20919061455d565b60006040518083038185875af1925050503d8060008114611a5d576040519150601f19603f3d011682016040523d82523d6000602084013e611a62565b606091505b509150915081611a845760405162461bcd60e51b815260040161034d90614888565b6000600c81905550600080516020614aaf8339815191526001600160a01b031663392544838d8f6015546040518463ffffffff1660e01b8152600401611acc93929190614653565b600060405180830381600087803b158015611ae657600080fd5b505af1158015611afa573d6000803e3d6000fd5b50505050844710158015611b18575083611b1561188e611f81565b10155b611b345760405162461bcd60e51b815260040161034d906147f8565b60016000559c9b505050505050505050505050565b600080611b54610cf9565b90506000611b6182611fb5565b905060008412611b8257611b7b818563ffffffff61279916565b9050611b99565b611b9681600086900363ffffffff612a0b16565b90505b610d62611baa83600061091c610bb7565b8383611c88565b3360009081526012602090815260408083206001600160a01b03861684529091528120548190611be7908463ffffffff61279916565b3360008181526012602090815260408083206001600160a01b038a168085529252918290208490559051929350917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b9259061136f90859061467c565b6001600160a01b03918216600090815260126020908152604080832093909416825291909152205490565b6001600160a01b031660009081526010602052604090205490565b60008215801590611c995750828210155b15610a44576112d768056bc75e2d631000008002610a79611d4168056bc75e2d63100000600080516020614aaf8339815191526001600160a01b0316634699f8466040518163ffffffff1660e01b815260040160206040518083038186803b158015611d0457600080fd5b505afa158015611d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611d3c9190810190613bd0565b612a0b565b610a6d611d4e8888612979565b899063ffffffff611f0516565b611d636114b9565b611d7f5760405162461bcd60e51b815260040161034d90614868565b611d8881612a4d565b50565b611d93611602565b6001600160a01b0316336001600160a01b03161480611dca5750611db56114aa565b6001600160a01b0316336001600160a01b0316145b611de65760405162461bcd60e51b815260040161034d90614848565b60005b8181101561177a57611e15838383818110611e0057fe5b905060200201602061079f9190810190613b76565b600101611de9565b600080611e3c611e33868663ffffffff61279916565b6117e387611fb5565b601654604051635e36559360e01b81529192506001600160a01b031690635e36559390611e6f90849087906004016146fb565b60206040518083038186803b158015611e8757600080fd5b505afa158015611e9b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ebf9190810190613bd0565b95945050505050565b600781565b600480546040516370a0823160e01b8152600092600160601b9092046001600160a01b0316916370a0823191610beb91309101614577565b600082611f1457506000610b7d565b82820282848281611f2157fe5b0414610a445760405162461bcd60e51b815260040161034d90614838565b6000610a4483836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250612acf565b60405163157b9bb560e11b8152600090600080516020614aaf83398151915290632af7376a90610beb903090600401614577565b600c5480610a8857610a85826112cb611ecd565b611fd1613683565b611fe66000356001600160e01b031916611381565b156120035760405162461bcd60e51b815260040161034d90614928565b8715806120185750336001600160a01b038416145b6120345760405162461bcd60e51b815260040161034d906147c8565b61203d886129a5565b8761207457833033854260405160200161205b959493929190614472565b6040516020818303038152906040528051906020012097505b6001600160a01b03841661209a5773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc293505b6004546001600160a01b03858116600160601b9092041614156120cf5760405162461bcd60e51b815260040161034d906147b8565b6120d76136a7565b6120df6136c5565b3082526001600160a01b0385166020830181905260408301526060810188905260808101879052600080612115888a8c8e612b06565b602087019390935293509091508290506121415760405162461bcd60e51b815260040161034d906147e8565b6121518c60008d8b88888c612b65565b8051909550600080516020614aaf8339815191529063b1bb8225908461218985610a7983670de0b6b3a764000063ffffffff611f0516565b6040518463ffffffff1660e01b81526004016121a793929190614709565b600060405180830381600087803b1580156121c157600080fd5b505af11580156121d5573d6000803e3d6000fd5b5050505050505050979650505050505050565b60006000198214612244576040805180820190915260028152610c4d60f21b602082015261221f908390859063ffffffff612d2f16565b6001600160a01b03861660009081526012602090815260408083203384529091529020555b6001600160a01b03841661226a5760405162461bcd60e51b815260040161034d90614738565b6001600160a01b03851660009081526011602090815260408083205481518083019092526002825261189b60f11b928201929092529091906122b5908390879063ffffffff612d2f16565b6001600160a01b038089166000908152601160205260408082208490559189168152908120549192506122ee828863ffffffff61279916565b6001600160a01b0389166000908152601160205260408120829055909150612314611479565b90506123228a868684612d5b565b61232e89848484612d5b565b886001600160a01b03168a6001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8a604051612371919061467c565b60405180910390a35060019998505050505050505050565b612391613683565b6123a66000356001600160e01b031916611381565b156123c35760405162461bcd60e51b815260040161034d90614928565b876123e05760405162461bcd60e51b815260040161034d906148f8565b3415806123ec57508534145b6124085760405162461bcd60e51b815260040161034d90614778565b8515158061241557508815155b6124315760405162461bcd60e51b815260040161034d90614908565b6001600160a01b03851615158061244757503415155b8061245157508815155b61246d5760405162461bcd60e51b815260040161034d906148b8565b8815806124825750336001600160a01b038516145b61249e5760405162461bcd60e51b815260040161034d906147c8565b6124a7896129a5565b886124de5784303386426040516020016124c5959493929190614472565b6040516020818303038152906040528051906020012098505b6001600160a01b0385166125045773c02aaa39b223fe8d0a0e5c4f27ead9083c756cc294505b6004546001600160a01b03868116600160601b9092041614156125395760405162461bcd60e51b815260040161034d90614728565b6125416136a7565b6125496136c5565b3082526001600160a01b03868116602080850191909152908616604080850191909152608083018a90528282018c90526000838201819052815192830190915280825261259f918d918d918b9087908790612b65565b9b9a5050505050505050505050565b60006125c56000356001600160e01b031916611381565b156125e25760405162461bcd60e51b815260040161034d90614928565b816125ff5760405162461bcd60e51b815260040161034d90614818565b61260960006129a5565b600061261961148e611489611f81565b905061263781610a7985670de0b6b3a764000063ffffffff611f0516565b91503461267f5761267a6004600c9054906101000a90046001600160a01b031633308660405180604001604052806002815260200161062760f31b815250612e11565b612707565b82341461269e5760405162461bcd60e51b815260040161034d90614828565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc26001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b1580156126ed57600080fd5b505af1158015612701573d6000803e3d6000fd5b50505050505b6001600160a01b03841660009081526011602052604090205461273890859061273282868887612e35565b84612d5b565b5092915050565b60008161274e57506000610d62565b508354611ebf8161278d670de0b6b3a764000061278188612775898963ffffffff612f5616565b9063ffffffff612f9c16565b9063ffffffff61300716565b9063ffffffff61306b16565b600082820183811015610a445760405162461bcd60e51b815260040161034d90614758565b601354600090806127d157600e54610a44565b610a4481610a7985670de0b6b3a764000063ffffffff611f0516565b3390565b60006128086000356001600160e01b031916611381565b156128255760405162461bcd60e51b815260040161034d90614928565b816128425760405162461bcd60e51b815260040161034d90614858565b61284c60006129a5565b612855336113da565b82111561288957600019821461287d5760405162461bcd60e51b815260040161034d90614808565b612886336113da565b91505b600061289961148e611489611f81565b905060006128b9670de0b6b3a7640000610a79868563ffffffff611f0516565b905060006128c5611ecd565b9050819350808411156128ea5760405162461bcd60e51b815260040161034d90614788565b33600081815260116020526040902054612911919061290b828989896130b1565b86612d5b565b505050919050565b60405161297390859063a9059cbb60e01b9061293b9087908790602401614638565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152836131d6565b50505050565b60008115610b7d5761299e82610a798568056bc75e2d6310000063ffffffff611f0516565b9050610b7d565b60405163789b79bf60e11b8152600080516020614aaf8339815191529063f136f37e906129d690849060040161467c565b600060405180830381600087803b1580156129f057600080fd5b505af1158015612a04573d6000803e3d6000fd5b5050505050565b6000610a4483836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250612d2f565b6001600160a01b038116612a735760405162461bcd60e51b815260040161034d90614748565b6001546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008183612af05760405162461bcd60e51b815260040161034d9190614717565b506000838581612afc57fe5b0495945050505050565b600080600080612b1788888861329c565b90925090506000612b386f4b3b4ca85a86c47a098a22400000000087611f3f565b9050612b5781610a798568056bc75e2d6310000063ffffffff611f0516565b945050945094509450949050565b612b6d613683565b612b75611ecd565b602084015111801590612b94575060208401516001600160a01b031615155b612bb05760405162461bcd60e51b815260040161034d90614798565b60408401516001600160a01b0316612bd65760208401516001600160a01b031660408501525b6000612be48686868b61342c565b60208501516060860151919250612bfb9190612799565b60608501528715612c1b576060840151612c159089612a0b565b60608501525b600088612c29576000612c2c565b60015b90506000600f60008984604051602001612c479291906144cb565b6040516020818303038152906040528051906020012060001c815260200190815260200160002054905088600014612c9657612c936f4b3b4ca85a86c47a098a2240000000008a611f3f565b98505b600080516020614aaf8339815191526001600160a01b031663585314cf84838e868e8d8d8d6040518963ffffffff1660e01b8152600401612cdd979695949392919061468a565b6060604051808303818588803b158015612cf657600080fd5b505af1158015612d0a573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525061259f9190810190613bb2565b60008184841115612d535760405162461bcd60e51b815260040161034d9190614717565b505050900390565b604051600090612d919086907f37aa2b7d583612f016e4a4de4292cb015139b3d7762663d06a53964912ea2fb6906020016144f1565b60405160208183030381529060405280519060200120905060008360001415612dbd5760009250612dee565b8415612dee576001600160a01b038616600090815260106020526040902054612deb9083908790869061273f565b90505b90556001600160a01b039093166000908152601060205260409020929092555050565b604051612a049086906323b872dd60e01b9061293b908890889088906024016145f0565b60006001600160a01b038516612e5d5760405162461bcd60e51b815260040161034d90614738565b6001600160a01b038516600090815260116020526040812054612e86908663ffffffff61279916565b6001600160a01b0387166000908152601160205260409020819055601354909150612eb7908663ffffffff61279916565b6013556040516001600160a01b038716907fb4c03061fb5b7fed76389d5af8f2e0ddb09f8c70d1333abbb62582835e10accb90612ef990889088908890614709565b60405180910390a2856001600160a01b031660006001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef87604051612f45919061467c565b60405180910390a395945050505050565b6000818303818312801590612f6b5750838113155b80612f805750600083128015612f8057508381135b610a445760405162461bcd60e51b815260040161034d906148e8565b600082612fab57506000610b7d565b82600019148015612fbf5750600160ff1b82145b15612fdc5760405162461bcd60e51b815260040161034d90614898565b82820282848281612fe957fe5b0514610a445760405162461bcd60e51b815260040161034d90614898565b6000816130265760405162461bcd60e51b815260040161034d90614918565b8160001914801561303a5750600160ff1b83145b156130575760405162461bcd60e51b815260040161034d906147d8565b600082848161306257fe5b05949350505050565b60008282018183128015906130805750838112155b80613095575060008312801561309557508381125b610a445760405162461bcd60e51b815260040161034d90614768565b6040805180820182526002815261189b60f11b6020808301919091526001600160a01b038716600090815260119091529182205482916130f99190879063ffffffff612d2f16565b9050600a811161311a57613113858263ffffffff61279916565b9450600090505b6001600160a01b0386166000908152601160205260409020819055601354613148908663ffffffff612a0b16565b6013556040516001600160a01b038716907f743033787f4738ff4d6a7225ce2bd0977ee5f86b91a902a58f5e4d0b297b46449061318a90889088908890614709565b60405180910390a260006001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef87604051612f45919061467c565b60006060846001600160a01b0316846040516131f2919061455d565b6000604051808303816000865af19150503d806000811461322f576040519150601f19603f3d011682016040523d82523d6000602084013e613234565b606091505b50915091508183906132595760405162461bcd60e51b815260040161034d9190614717565b50805115612a04578080602001905161327591908101906139dc565b83906132945760405162461bcd60e51b815260040161034d9190614717565b505050505050565b6000806000600080516020614aaf8339815191526001600160a01b03166378d849ed6040518163ffffffff1660e01b815260040160206040518083038186803b1580156132e857600080fd5b505afa1580156132fc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250613320919081019061387d565b60048054604051630a7549df60e21b81526001600160a01b03938416936329d5277c9361335b938c93600160601b90910490921691016145a0565b604080518083038186803b15801561337257600080fd5b505afa158015613386573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506133aa9190810190613c9c565b909250905081158015906133bd57508015155b6133d95760405162461bcd60e51b815260040161034d906147a8565b6133f581610a7984670de0b6b3a764000063ffffffff611f0516565b8493509150841561342357613420836112cb670de0b6b3a7640000610a79898763ffffffff611f0516565b92505b50935093915050565b600454604084015160208401516060850151608086015160009473c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2946001600160a01b03600160601b9092048216949093909290918b168514156134965760405162461bcd60e51b815260040161034d90614878565b3496508715613508576134c585858a60405180604001604052806002815260200161323760f01b815250612919565b878311156135035761350385600080516020614aaf8339815191528a860360405180604001604052806002815260200161323760f01b815250612919565b61353c565b61353c85600080516020614aaf8339815191528560405180604001604052806002815260200161323760f01b815250612919565b801561363a57856001600160a01b03168b6001600160a01b031614801561356257508615155b801561356e5750808710155b1561360557856001600160a01b031663d0e30db0826040518263ffffffff1660e01b81526004016000604051808303818588803b1580156135ae57600080fd5b505af11580156135c2573d6000803e3d6000fd5b50505050506135fb8b600080516020614aaf8339815191528360405180604001604052806002815260200161064760f31b815250612919565b808703965061363a565b61363a8b33600080516020614aaf8339815191528460405180604001604052806002815260200161064760f31b815250612e11565b8115613675576136758533600080516020614aaf8339815191528560405180604001604052806002815260200161323960f01b815250612e11565b505050505050949350505050565b60405180606001604052806000801916815260200160008152602001600081525090565b60405180608001604052806004906020820280388339509192915050565b6040518060a001604052806005906020820280388339509192915050565b8035610b7d81614a7f565b8051610b7d81614a7f565b60008083601f84011261370b57600080fd5b50813567ffffffffffffffff81111561372357600080fd5b60208301915083602082028301111561373b57600080fd5b9250929050565b8051610b7d81614a93565b8035610b7d81614a9c565b8051610b7d81614a9c565b8035610b7d81614aa5565b60008083601f84011261378057600080fd5b50813567ffffffffffffffff81111561379857600080fd5b60208301915083600182028301111561373b57600080fd5b600082601f8301126137c157600080fd5b81356137d46137cf8261497b565b614954565b915080825260208301602083018583830111156137f057600080fd5b6137fb838284614a05565b50505092915050565b60006060828403121561381657600080fd5b6138206060614954565b9050600061382e8484613758565b825250602061383f84848301613758565b602083015250604061385384828501613758565b60408301525092915050565b60006020828403121561387157600080fd5b6000610d6284846136e3565b60006020828403121561388f57600080fd5b6000610d6284846136ee565b600080604083850312156138ae57600080fd5b60006138ba85856136e3565b92505060206138cb858286016136e3565b9150509250929050565b6000806000606084860312156138ea57600080fd5b60006138f686866136e3565b9350506020613907868287016136e3565b92505060406139188682870161374d565b9150509250925092565b6000806040838503121561393557600080fd5b600061394185856136e3565b925050602083013567ffffffffffffffff81111561395e57600080fd5b6138cb858286016137b0565b6000806040838503121561397d57600080fd5b600061398985856136e3565b92505060206138cb8582860161374d565b600080602083850312156139ad57600080fd5b823567ffffffffffffffff8111156139c457600080fd5b6139d0858286016136f9565b92509250509250929050565b6000602082840312156139ee57600080fd5b6000610d628484613742565b600080600080600080600080610100898b031215613a1757600080fd5b6000613a238b8b61374d565b9850506020613a348b828c0161374d565b9750506040613a458b828c0161374d565b9650506060613a568b828c0161374d565b9550506080613a678b828c016136e3565b94505060a0613a788b828c016136e3565b93505060c0613a898b828c016136e3565b92505060e089013567ffffffffffffffff811115613aa657600080fd5b613ab28b828c016137b0565b9150509295985092959890939650565b600080600080600080600060e0888a031215613add57600080fd5b6000613ae98a8a61374d565b9750506020613afa8a828b0161374d565b9650506040613b0b8a828b0161374d565b9550506060613b1c8a828b0161374d565b9450506080613b2d8a828b016136e3565b93505060a0613b3e8a828b016136e3565b92505060c088013567ffffffffffffffff811115613b5b57600080fd5b613b678a828b016137b0565b91505092959891949750929550565b600060208284031215613b8857600080fd5b6000610d628484613763565b600060208284031215613ba657600080fd5b6000610d62848461374d565b600060608284031215613bc457600080fd5b6000610d628484613804565b600060208284031215613be257600080fd5b6000610d628484613758565b600080600080600080600060a0888a031215613c0957600080fd5b6000613c158a8a61374d565b9750506020613c268a828b016136e3565b9650506040613c378a828b016136e3565b955050606088013567ffffffffffffffff811115613c5457600080fd5b613c608a828b0161376e565b9450945050608088013567ffffffffffffffff811115613c7f57600080fd5b613c8b8a828b0161376e565b925092505092959891949750929550565b60008060408385031215613caf57600080fd5b6000613cbb8585613758565b92505060206138cb85828601613758565b600080600060608486031215613ce157600080fd5b6000613ced868661374d565b9350506020613cfe8682870161374d565b9250506040613918868287016136e3565b600080600060608486031215613d2457600080fd5b6000613d30868661374d565b93505060206139078682870161374d565b6000613d4d8383613d81565b505060200190565b6000613d4d8383613e3c565b613d6a816149f4565b82525050565b613d6a613d7c826149c5565b614a3d565b613d6a816149c5565b613d93816149a6565b613d9d8184610a88565b9250613da8826149a3565b8060005b83811015613294578151613dc08782613d41565b9650613dcb836149b6565b925050600101613dac565b613ddf816149ac565b613de98184610a88565b9250613df4826149a3565b8060005b83811015613294578151613e0c8782613d55565b9650613e17836149b6565b925050600101613df8565b613d6a816149d0565b613d6a613e37826149d0565b614a48565b613d6a816149a3565b613d6a613e51826149a3565b6149a3565b613d6a613e51826149d5565b6000613e6e8385610a88565b9350613e7b838584614a05565b50500190565b6000613e8c826149b2565b613e9681856149bc565b9350613ea6818560208601614a11565b613eaf81614a69565b9093019392505050565b6000613ec4826149b2565b613ece8185610a88565b9350613ede818560208601614a11565b9290920192915050565b6000613ef56002836149bc565b61031360f41b815260200192915050565b6000613f136002836149bc565b61313560f01b815260200192915050565b6000613f316026836149bc565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015260400192915050565b6000613f79601b836149bc565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b6000613fb26021836149bc565b7f5369676e6564536166654d6174683a206164646974696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000613ff56001836149bc565b603760f81b815260200192915050565b60006140126002836149bc565b61333760f01b815260200192915050565b60006140306002836149bc565b610c8d60f21b815260200192915050565b600061404e6002836149bc565b61032360f41b815260200192915050565b600061406c6002836149bc565b61313160f01b815260200192915050565b600061408a6002836149bc565b61313360f01b815260200192915050565b60006140a86021836149bc565b7f5369676e6564536166654d6174683a206469766973696f6e206f766572666c6f8152607760f81b602082015260400192915050565b60006140eb6002836149bc565b61189960f11b815260200192915050565b60006141096002836149bc565b61034360f41b815260200192915050565b60006141276002836149bc565b61199960f11b815260200192915050565b60006141456002836149bc565b61313760f01b815260200192915050565b60006141636002836149bc565b61062760f31b815260200192915050565b60006141816021836149bc565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b60006141c4600c836149bc565b6b1d5b985d5d1a1bdc9a5e995960a21b815260200192915050565b60006141ec6002836149bc565b61313960f01b815260200192915050565b600061420a6020836149bc565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572815260200192915050565b60006142436002836149bc565b61191b60f11b815260200192915050565b6000614261600b836149bc565b6a18d85b1b0819985a5b195960aa1b815260200192915050565b60006142886027836149bc565b7f5369676e6564536166654d6174683a206d756c7469706c69636174696f6e206f815266766572666c6f7760c81b602082015260400192915050565b60006142d16014836149bc565b7319985b1b189858dac81b9bdd08185b1b1bddd95960621b815260200192915050565b60006143016001836149bc565b603960f81b815260200192915050565b600061431e600c836149bc565b6b1b9bdb9499595b9d1c985b9d60a21b815260200192915050565b60006143466002836149bc565b61066760f31b815260200192915050565b60006143646024836149bc565b7f5369676e6564536166654d6174683a207375627472616374696f6e206f766572815263666c6f7760e01b602082015260400192915050565b60006143aa6001836149bc565b601b60f91b815260200192915050565b60006143c76001836149bc565b600760fb1b815260200192915050565b60006143e46020836149bc565b7f5369676e6564536166654d6174683a206469766973696f6e206279207a65726f815260200192915050565b600061441d6006836149bc565b651c185d5cd95960d21b815260200192915050565b805160608301906144438482613e3c565b5060208201516144566020850182613e3c565b5060408201516129736040850182613e3c565b613d6a816149ee565b600061447e8288613d70565b60148201915061448e8287613d70565b60148201915061449e8286613d70565b6014820191506144ae8285613d70565b6014820191506144be8284613e45565b5060200195945050505050565b60006144d78285613d70565b6014820191506144e78284613e2b565b5060010192915050565b60006144fd8285613d70565b60148201915061450d8284613e45565b5060200192915050565b60006145238285613e56565b60048201915061450d8284613e45565b600061453f8286613e56565b600482019150611ebf828486613e62565b6000610d62828486613e62565b6000610a448284613eb9565b60208101610b7d8284613d81565b60208101610b7d8284613d61565b604081016145938285613d61565b610a446020830184613d61565b604081016145ae8285613d81565b610a446020830184613d81565b608081016145c98287613d81565b6145d66020830186613d81565b6145e36040830185613d81565b611ebf6060830184613e3c565b606081016145fe8286613d81565b61460b6020830185613d81565b610d626040830184613e3c565b604081016146268285613d81565b8181036020830152610d628184613e81565b604081016146468285613d81565b610a446020830184613e3c565b606081016146618286613d81565b61460b6020830185613e3c565b60208101610b7d8284613e22565b60208101610b7d8284613e3c565b6101c08101614699828a613e3c565b6146a66020830189613e3c565b6146b36040830188613e22565b6146c06060830187613e3c565b6146cd6080830186613d8a565b6146db610100830185613dd6565b8181036101a08301526146ee8184613e81565b9998505050505050505050565b604081016146468285613e3c565b606081016146618286613e3c565b60208082528101610a448184613e81565b60208082528101610a8581613ee8565b60208082528101610a8581613f06565b60208082528101610a8581613f24565b60208082528101610a8581613f6c565b60208082528101610a8581613fa5565b60208082528101610a8581613fe8565b60208082528101610a8581614005565b60208082528101610a8581614023565b60208082528101610a8581614041565b60208082528101610a858161405f565b60208082528101610a858161407d565b60208082528101610a858161409b565b60208082528101610a85816140de565b60208082528101610a85816140fc565b60208082528101610a858161411a565b60208082528101610a8581614138565b60208082528101610a8581614156565b60208082528101610a8581614174565b60208082528101610a85816141b7565b60208082528101610a85816141df565b60208082528101610a85816141fd565b60208082528101610a8581614236565b60208082528101610a8581614254565b60208082528101610a858161427b565b60208082528101610a85816142c4565b60208082528101610a85816142f4565b60208082528101610a8581614311565b60208082528101610a8581614339565b60208082528101610a8581614357565b60208082528101610a858161439d565b60208082528101610a85816143ba565b60208082528101610a85816143d7565b60208082528101610a8581614410565b60608101610b7d8284614432565b60208101610b7d8284614469565b60405181810167ffffffffffffffff8111828210171561497357600080fd5b604052919050565b600067ffffffffffffffff82111561499257600080fd5b506020601f91909101601f19160190565b90565b50600490565b50600590565b5190565b60200190565b90815260200190565b6000610a85826149e2565b151590565b6001600160e01b03191690565b6001600160a01b031690565b60ff1690565b6000610a85826000610a85826149c5565b82818337506000910152565b60005b83811015614a2c578181015183820152602001614a14565b838111156129735750506000910152565b6000610a8582614a53565b6000610a8582614a5e565b6000610a8582614a79565b6000610a8582614a73565b601f01601f191690565b60f81b90565b60601b90565b614a88816149c5565b8114611d8857600080fd5b614a88816149d0565b614a88816149a3565b614a88816149d556fe000000000000000000000000d8ee69652e4e4838f2531732a46d1f7f584f0b7fa365627a7a72315820f08d69608993c54a231668dbabc76de551d2bd4ec715ee1d77cc28b70bcb63a06c6578706572696d656e74616cf564736f6c63430005110040
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ 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.