Contract 0x5385bcc7420012babd14675a466e24fbe2f9b1d6 1
Contract Overview
Balance:
0 ETH
ETH Value:
$0.00
My Name Tag:
Not Available
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x347ef1e4831d3026b7647cb7a8051b32064cc4a977b079110bba588e6153aa36 | Enter Markets | 45226916 | 474 days 6 hrs ago | 0x4a78d38ccaecf3be5644d63370091356805953c0 | IN | 0x5385bcc7420012babd14675a466e24fbe2f9b1d6 | 0 ETH | 0.00002227 | |
0x75455a2dff7686e37cc9b61af6d00f0943cb201cc3261e1c08868be40833cefe | Initialize | 7880059 | 746 days 3 hrs ago | dForce Network: Deployer | IN | 0x5385bcc7420012babd14675a466e24fbe2f9b1d6 | 0 ETH | 0.000127511339 ETH | |
0xac64856a516c57519d1ff82de1823e121b8ad539105da9d6075c5ae56f307e31 | 0x60806040 | 7880037 | 746 days 3 hrs ago | dForce Network: Deployer | IN | Create: Controller | 0 ETH | 0.019211125417 ETH |
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
Controller
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity)
/** *Submitted for verification at Arbiscan.io on 2022-03-14 */ /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ //SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.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 SafeMathUpgradeable { /** * @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. */ 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. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 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. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ pragma solidity 0.6.12; interface IControllerAdminInterface { /// @notice Emitted when an admin supports a market event MarketAdded( address iToken, uint256 collateralFactor, uint256 borrowFactor, uint256 supplyCapacity, uint256 borrowCapacity, uint256 distributionFactor ); function _addMarket( address _iToken, uint256 _collateralFactor, uint256 _borrowFactor, uint256 _supplyCapacity, uint256 _borrowCapacity, uint256 _distributionFactor ) external; /// @notice Emitted when new price oracle is set event NewPriceOracle(address oldPriceOracle, address newPriceOracle); function _setPriceOracle(address newOracle) external; /// @notice Emitted when close factor is changed by admin event NewCloseFactor( uint256 oldCloseFactorMantissa, uint256 newCloseFactorMantissa ); function _setCloseFactor(uint256 newCloseFactorMantissa) external; /// @notice Emitted when liquidation incentive is changed by admin event NewLiquidationIncentive( uint256 oldLiquidationIncentiveMantissa, uint256 newLiquidationIncentiveMantissa ); function _setLiquidationIncentive(uint256 newLiquidationIncentiveMantissa) external; /// @notice Emitted when iToken's collateral factor is changed by admin event NewCollateralFactor( address iToken, uint256 oldCollateralFactorMantissa, uint256 newCollateralFactorMantissa ); function _setCollateralFactor( address iToken, uint256 newCollateralFactorMantissa ) external; /// @notice Emitted when iToken's borrow factor is changed by admin event NewBorrowFactor( address iToken, uint256 oldBorrowFactorMantissa, uint256 newBorrowFactorMantissa ); function _setBorrowFactor(address iToken, uint256 newBorrowFactorMantissa) external; /// @notice Emitted when iToken's borrow capacity is changed by admin event NewBorrowCapacity( address iToken, uint256 oldBorrowCapacity, uint256 newBorrowCapacity ); function _setBorrowCapacity(address iToken, uint256 newBorrowCapacity) external; /// @notice Emitted when iToken's supply capacity is changed by admin event NewSupplyCapacity( address iToken, uint256 oldSupplyCapacity, uint256 newSupplyCapacity ); function _setSupplyCapacity(address iToken, uint256 newSupplyCapacity) external; /// @notice Emitted when pause guardian is changed by admin event NewPauseGuardian(address oldPauseGuardian, address newPauseGuardian); function _setPauseGuardian(address newPauseGuardian) external; /// @notice Emitted when mint is paused/unpaused by admin or pause guardian event MintPaused(address iToken, bool paused); function _setMintPaused(address iToken, bool paused) external; function _setAllMintPaused(bool paused) external; /// @notice Emitted when redeem is paused/unpaused by admin or pause guardian event RedeemPaused(address iToken, bool paused); function _setRedeemPaused(address iToken, bool paused) external; function _setAllRedeemPaused(bool paused) external; /// @notice Emitted when borrow is paused/unpaused by admin or pause guardian event BorrowPaused(address iToken, bool paused); function _setBorrowPaused(address iToken, bool paused) external; function _setAllBorrowPaused(bool paused) external; /// @notice Emitted when transfer is paused/unpaused by admin or pause guardian event TransferPaused(bool paused); function _setTransferPaused(bool paused) external; /// @notice Emitted when seize is paused/unpaused by admin or pause guardian event SeizePaused(bool paused); function _setSeizePaused(bool paused) external; function _setiTokenPaused(address iToken, bool paused) external; function _setProtocolPaused(bool paused) external; event NewRewardDistributor( address oldRewardDistributor, address _newRewardDistributor ); function _setRewardDistributor(address _newRewardDistributor) external; } interface IControllerPolicyInterface { function beforeMint( address iToken, address account, uint256 mintAmount ) external; function afterMint( address iToken, address minter, uint256 mintAmount, uint256 mintedAmount ) external; function beforeRedeem( address iToken, address redeemer, uint256 redeemAmount ) external; function afterRedeem( address iToken, address redeemer, uint256 redeemAmount, uint256 redeemedAmount ) external; function beforeBorrow( address iToken, address borrower, uint256 borrowAmount ) external; function afterBorrow( address iToken, address borrower, uint256 borrowedAmount ) external; function beforeRepayBorrow( address iToken, address payer, address borrower, uint256 repayAmount ) external; function afterRepayBorrow( address iToken, address payer, address borrower, uint256 repayAmount ) external; function beforeLiquidateBorrow( address iTokenBorrowed, address iTokenCollateral, address liquidator, address borrower, uint256 repayAmount ) external; function afterLiquidateBorrow( address iTokenBorrowed, address iTokenCollateral, address liquidator, address borrower, uint256 repaidAmount, uint256 seizedAmount ) external; function beforeSeize( address iTokenBorrowed, address iTokenCollateral, address liquidator, address borrower, uint256 seizeAmount ) external; function afterSeize( address iTokenBorrowed, address iTokenCollateral, address liquidator, address borrower, uint256 seizedAmount ) external; function beforeTransfer( address iToken, address from, address to, uint256 amount ) external; function afterTransfer( address iToken, address from, address to, uint256 amount ) external; function beforeFlashloan( address iToken, address to, uint256 amount ) external; function afterFlashloan( address iToken, address to, uint256 amount ) external; } interface IControllerAccountEquityInterface { function calcAccountEquity(address account) external view returns ( uint256, uint256, uint256, uint256 ); function liquidateCalculateSeizeTokens( address iTokenBorrowed, address iTokenCollateral, uint256 actualRepayAmount ) external view returns (uint256); } interface IControllerAccountInterface { function hasEnteredMarket(address account, address iToken) external view returns (bool); function getEnteredMarkets(address account) external view returns (address[] memory); /// @notice Emitted when an account enters a market event MarketEntered(address iToken, address account); function enterMarkets(address[] calldata iTokens) external returns (bool[] memory); function enterMarketFromiToken(address _market, address _account) external; /// @notice Emitted when an account exits a market event MarketExited(address iToken, address account); function exitMarkets(address[] calldata iTokens) external returns (bool[] memory); /// @notice Emitted when an account add a borrow asset event BorrowedAdded(address iToken, address account); /// @notice Emitted when an account remove a borrow asset event BorrowedRemoved(address iToken, address account); function hasBorrowed(address account, address iToken) external view returns (bool); function getBorrowedAssets(address account) external view returns (address[] memory); } interface IControllerInterface is IControllerAdminInterface, IControllerPolicyInterface, IControllerAccountEquityInterface, IControllerAccountInterface { /** * @notice Security checks when updating the comptroller of a market, always expect to return true. */ function isController() external view returns (bool); /** * @notice Return all of the iTokens * @return The list of iToken addresses */ function getAlliTokens() external view returns (address[] memory); /** * @notice Check whether a iToken is listed in controller * @param _iToken The iToken to check for * @return true if the iToken is listed otherwise false */ function hasiToken(address _iToken) external view returns (bool); /** * @return Return the distributor contract address */ function rewardDistributor() external returns (address); } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ pragma solidity 0.6.12; /** * @title dForce Lending Protocol's InterestRateModel Interface. * @author dForce Team. */ interface IInterestRateModelInterface { function isInterestRateModel() external view returns (bool); /** * @dev Calculates the current borrow interest rate per block. * @param cash The total amount of cash the market has. * @param borrows The total amount of borrows the market has. * @param reserves The total amnount of reserves the market has. * @return The borrow rate per block (as a percentage, and scaled by 1e18). */ function getBorrowRate( uint256 cash, uint256 borrows, uint256 reserves ) external view returns (uint256); /** * @dev Calculates the current supply interest rate per block. * @param cash The total amount of cash the market has. * @param borrows The total amount of borrows the market has. * @param reserves The total amnount of reserves the market has. * @param reserveRatio The current reserve factor the market has. * @return The supply rate per block (as a percentage, and scaled by 1e18). */ function getSupplyRate( uint256 cash, uint256 borrows, uint256 reserves, uint256 reserveRatio ) external view returns (uint256); } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ pragma solidity 0.6.12; ////import "./IInterestRateModelInterface.sol"; ////import "./IControllerInterface.sol"; interface IiToken { function isSupported() external returns (bool); function isiToken() external returns (bool); //---------------------------------- //********* User Interface ********* //---------------------------------- function mint(address recipient, uint256 mintAmount) external; function mintForSelfAndEnterMarket(uint256 mintAmount) external; function redeem(address from, uint256 redeemTokens) external; function redeemUnderlying(address from, uint256 redeemAmount) external; function borrow(uint256 borrowAmount) external; function repayBorrow(uint256 repayAmount) external; function repayBorrowBehalf(address borrower, uint256 repayAmount) external; function liquidateBorrow( address borrower, uint256 repayAmount, address iTokenCollateral ) external; function flashloan( address recipient, uint256 loanAmount, bytes memory data ) external; function seize( address _liquidator, address _borrower, uint256 _seizeTokens ) external; function updateInterest() external returns (bool); function controller() external view returns (address); function exchangeRateCurrent() external returns (uint256); function exchangeRateStored() external view returns (uint256); function totalBorrowsCurrent() external returns (uint256); function totalBorrows() external view returns (uint256); function borrowBalanceCurrent(address _user) external returns (uint256); function borrowBalanceStored(address _user) external view returns (uint256); function borrowIndex() external view returns (uint256); function getAccountSnapshot(address _account) external view returns ( uint256, uint256, uint256 ); function borrowRatePerBlock() external view returns (uint256); function supplyRatePerBlock() external view returns (uint256); function getCash() external view returns (uint256); //---------------------------------- //********* Owner Actions ********** //---------------------------------- function _setNewReserveRatio(uint256 _newReserveRatio) external; function _setNewFlashloanFeeRatio(uint256 _newFlashloanFeeRatio) external; function _setNewProtocolFeeRatio(uint256 _newProtocolFeeRatio) external; function _setController(IControllerInterface _newController) external; function _setInterestRateModel( IInterestRateModelInterface _newInterestRateModel ) external; function _withdrawReserves(uint256 _withdrawAmount) external; } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ ////// -FLATTEN-SUPPRESS-WARNING: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * ////IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ ////// -FLATTEN-SUPPRESS-WARNING: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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); } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ pragma solidity 0.6.12; ////import "@openzeppelin/contracts-upgradeable/math/SafeMathUpgradeable.sol"; library SafeRatioMath { using SafeMathUpgradeable for uint256; uint256 private constant BASE = 10**18; uint256 private constant DOUBLE = 10**36; function divup(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x.add(y.sub(1)).div(y); } function rmul(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x.mul(y).div(BASE); } function rdiv(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x.mul(BASE).div(y); } function rdivup(uint256 x, uint256 y) internal pure returns (uint256 z) { z = x.mul(BASE).add(y.sub(1)).div(y); } function tmul( uint256 x, uint256 y, uint256 z ) internal pure returns (uint256 result) { result = x.mul(y).mul(z).div(DOUBLE); } function rpow( uint256 x, uint256 n, uint256 base ) internal pure returns (uint256 z) { assembly { switch x case 0 { switch n case 0 { z := base } default { z := 0 } } default { switch mod(n, 2) case 0 { z := base } default { z := x } let half := div(base, 2) // for rounding. for { n := div(n, 2) } n { n := div(n, 2) } { let xx := mul(x, x) if iszero(eq(div(xx, x), x)) { revert(0, 0) } let xxRound := add(xx, half) if lt(xxRound, xx) { revert(0, 0) } x := div(xxRound, base) if mod(n, 2) { let zx := mul(z, x) if and( iszero(iszero(x)), iszero(eq(div(zx, x), z)) ) { revert(0, 0) } let zxRound := add(zx, half) if lt(zxRound, zx) { revert(0, 0) } z := div(zxRound, base) } } } } } } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ pragma solidity 0.6.12; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {_setPendingOwner} and {_acceptOwner}. */ contract Ownable { /** * @dev Returns the address of the current owner. */ address payable public owner; /** * @dev Returns the address of the current pending owner. */ address payable public pendingOwner; event NewOwner(address indexed previousOwner, address indexed newOwner); event NewPendingOwner( address indexed oldPendingOwner, address indexed newPendingOwner ); /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner == msg.sender, "onlyOwner: caller is not the owner"); _; } /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal { owner = msg.sender; emit NewOwner(address(0), msg.sender); } /** * @notice Base on the inputing parameter `newPendingOwner` to check the exact error reason. * @dev Transfer contract control to a new owner. The newPendingOwner must call `_acceptOwner` to finish the transfer. * @param newPendingOwner New pending owner. */ function _setPendingOwner(address payable newPendingOwner) external onlyOwner { require( newPendingOwner != address(0) && newPendingOwner != pendingOwner, "_setPendingOwner: New owenr can not be zero address and owner has been set!" ); // Gets current owner. address oldPendingOwner = pendingOwner; // Sets new pending owner. pendingOwner = newPendingOwner; emit NewPendingOwner(oldPendingOwner, newPendingOwner); } /** * @dev Accepts the admin rights, but only for pendingOwenr. */ function _acceptOwner() external { require( msg.sender == pendingOwner, "_acceptOwner: Only for pending owner!" ); // Gets current values for events. address oldOwner = owner; address oldPendingOwner = pendingOwner; // Set the new contract owner. owner = pendingOwner; // Clear the pendingOwner. pendingOwner = address(0); emit NewOwner(oldOwner, owner); emit NewPendingOwner(oldPendingOwner, pendingOwner); } uint256[50] private __gap; } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ ////// -FLATTEN-SUPPRESS-WARNING: MIT pragma solidity 0.6.12; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { require( !_initialized, "Initializable: contract is already initialized" ); _; _initialized = true; } } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ pragma solidity 0.6.12; interface IRewardDistributor { function _setRewardToken(address newRewardToken) external; /// @notice Emitted reward token address is changed by admin event NewRewardToken(address oldRewardToken, address newRewardToken); function _addRecipient(address _iToken, uint256 _distributionFactor) external; event NewRecipient(address iToken, uint256 distributionFactor); /// @notice Emitted when mint is paused/unpaused by admin event Paused(bool paused); function _pause() external; function _unpause(uint256 _borrowSpeed, uint256 _supplySpeed) external; /// @notice Emitted when Global Distribution speed for both supply and borrow are updated event GlobalDistributionSpeedsUpdated( uint256 borrowSpeed, uint256 supplySpeed ); function _setGlobalDistributionSpeeds( uint256 borrowSpeed, uint256 supplySpeed ) external; /// @notice Emitted when iToken's Distribution speed is updated event DistributionSpeedsUpdated( address iToken, uint256 borrowSpeed, uint256 supplySpeed ); function updateDistributionSpeed() external; /// @notice Emitted when iToken's Distribution factor is changed by admin event NewDistributionFactor( address iToken, uint256 oldDistributionFactorMantissa, uint256 newDistributionFactorMantissa ); function _setDistributionFactors( address[] calldata iToken, uint256[] calldata distributionFactors ) external; function updateDistributionState(address _iToken, bool _isBorrow) external; function updateReward( address _iToken, address _account, bool _isBorrow ) external; function updateRewardBatch( address[] memory _holders, address[] memory _iTokens ) external; function claimReward(address[] memory _holders, address[] memory _iTokens) external; function claimAllReward(address[] memory _holders) external; /// @notice Emitted when reward of amount is distributed into account event RewardDistributed( address iToken, address account, uint256 amount, uint256 accountIndex ); } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ pragma solidity 0.6.12; ////import "./IiToken.sol"; interface IPriceOracle { /** * @notice Get the underlying price of a iToken asset * @param _iToken The iToken to get the underlying price of * @return The underlying asset price mantissa (scaled by 1e18). * Zero means the price is unavailable. */ function getUnderlyingPrice(address _iToken) external view returns (uint256); /** * @notice Get the price of a underlying asset * @param _iToken The iToken to get the underlying price of * @return The underlying asset price mantissa (scaled by 1e18). * Zero means the price is unavailable and whether the price is valid. */ function getUnderlyingPriceAndStatus(address _iToken) external view returns (uint256, bool); } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ ////// -FLATTEN-SUPPRESS-WARNING: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Library for managing * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive * types. * * Sets have the following properties: * * - Elements are added, removed, and checked for existence in constant time * (O(1)). * - Elements are enumerated in O(n). No guarantees are made on the ordering. * * ``` * contract Example { * // Add the library methods * using EnumerableSet for EnumerableSet.AddressSet; * * // Declare a set state variable * EnumerableSet.AddressSet private mySet; * } * ``` * * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`) * and `uint256` (`UintSet`) are supported. */ library EnumerableSetUpgradeable { // To implement this library for multiple types with as little code // repetition as possible, we write it in terms of a generic Set type with // bytes32 values. // The Set implementation uses private functions, and user-facing // implementations (such as AddressSet) are just wrappers around the // underlying Set. // This means that we can only create new EnumerableSets for types that fit // in bytes32. struct Set { // Storage of set values bytes32[] _values; // Position of the value in the `values` array, plus 1 because index 0 // means a value is not in the set. mapping (bytes32 => uint256) _indexes; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function _add(Set storage set, bytes32 value) private returns (bool) { if (!_contains(set, value)) { set._values.push(value); // The value is stored at length-1, but we add 1 to all indexes // and use 0 as a sentinel value set._indexes[value] = set._values.length; return true; } else { return false; } } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function _remove(Set storage set, bytes32 value) private returns (bool) { // We read and store the value's index to prevent multiple reads from the same storage slot uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { // Equivalent to contains(set, value) // To delete an element from the _values array in O(1), we swap the element to delete with the last one in // the array, and then remove the last element (sometimes called as 'swap and pop'). // This modifies the order of the array, as noted in {at}. uint256 toDeleteIndex = valueIndex - 1; uint256 lastIndex = set._values.length - 1; // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement. bytes32 lastvalue = set._values[lastIndex]; // Move the last value to the index where the value to delete is set._values[toDeleteIndex] = lastvalue; // Update the index for the moved value set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based // Delete the slot where the moved value was stored set._values.pop(); // Delete the index for the deleted slot delete set._indexes[value]; return true; } else { return false; } } /** * @dev Returns true if the value is in the set. O(1). */ function _contains(Set storage set, bytes32 value) private view returns (bool) { return set._indexes[value] != 0; } /** * @dev Returns the number of values on the set. O(1). */ function _length(Set storage set) private view returns (uint256) { return set._values.length; } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function _at(Set storage set, uint256 index) private view returns (bytes32) { require(set._values.length > index, "EnumerableSet: index out of bounds"); return set._values[index]; } // Bytes32Set struct Bytes32Set { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _add(set._inner, value); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) { return _remove(set._inner, value); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) { return _contains(set._inner, value); } /** * @dev Returns the number of values in the set. O(1). */ function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) { return _at(set._inner, index); } // AddressSet struct AddressSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(AddressSet storage set, address value) internal returns (bool) { return _add(set._inner, bytes32(uint256(value))); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(AddressSet storage set, address value) internal returns (bool) { return _remove(set._inner, bytes32(uint256(value))); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(AddressSet storage set, address value) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(value))); } /** * @dev Returns the number of values in the set. O(1). */ function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(AddressSet storage set, uint256 index) internal view returns (address) { return address(uint256(_at(set._inner, index))); } // UintSet struct UintSet { Set _inner; } /** * @dev Add a value to a set. O(1). * * Returns true if the value was added to the set, that is if it was not * already present. */ function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } /** * @dev Removes a value from a set. O(1). * * Returns true if the value was removed from the set, that is if it was * present. */ function remove(UintSet storage set, uint256 value) internal returns (bool) { return _remove(set._inner, bytes32(value)); } /** * @dev Returns true if the value is in the set. O(1). */ function contains(UintSet storage set, uint256 value) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } /** * @dev Returns the number of values on the set. O(1). */ function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } /** * @dev Returns the value stored at position `index` in the set. O(1). * * Note that there are no guarantees on the ordering of values inside the * array, and it may change when more values are added or removed. * * Requirements: * * - `index` must be strictly less than {length}. */ function at(UintSet storage set, uint256 index) internal view returns (uint256) { return uint256(_at(set._inner, index)); } } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ ////// -FLATTEN-SUPPRESS-WARNING: MIT pragma solidity >=0.6.0 <0.8.0; ////import "./IERC20Upgradeable.sol"; ////import "../../math/SafeMathUpgradeable.sol"; ////import "../../utils/AddressUpgradeable.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20Upgradeable { using SafeMathUpgradeable for uint256; using AddressUpgradeable for address; function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20Upgradeable token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20Upgradeable token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } } /** * SourceUnit: /Users/snow/work/dforce/code/LendingV2/LendingContracts/contracts/Controller.sol */ pragma solidity 0.6.12; ////import "@openzeppelin/contracts-upgradeable/token/ERC20/SafeERC20Upgradeable.sol"; ////import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; ////import "@openzeppelin/contracts-upgradeable/utils/EnumerableSetUpgradeable.sol"; ////import "./interface/IControllerInterface.sol"; ////import "./interface/IPriceOracle.sol"; ////import "./interface/IiToken.sol"; ////import "./interface/IRewardDistributor.sol"; ////import "./library/Initializable.sol"; ////import "./library/Ownable.sol"; ////import "./library/SafeRatioMath.sol"; /** * @title dForce's lending controller Contract * @author dForce */ contract Controller is Initializable, Ownable, IControllerInterface { using EnumerableSetUpgradeable for EnumerableSetUpgradeable.AddressSet; using SafeRatioMath for uint256; using SafeMathUpgradeable for uint256; using SafeERC20Upgradeable for IERC20Upgradeable; /// @dev EnumerableSet of all iTokens EnumerableSetUpgradeable.AddressSet internal iTokens; struct Market { /* * Multiplier representing the most one can borrow against their collateral in this market. * For instance, 0.9 to allow borrowing 90% of collateral value. * Must be in [0, 0.9], and stored as a mantissa. */ uint256 collateralFactorMantissa; /* * Multiplier representing the most one can borrow the asset. * For instance, 0.5 to allow borrowing this asset 50% * collateral value * collateralFactor. * When calculating equity, 0.5 with 100 borrow balance will produce 200 borrow value * Must be between (0, 1], and stored as a mantissa. */ uint256 borrowFactorMantissa; /* * The borrow capacity of the asset, will be checked in beforeBorrow() * -1 means there is no limit on the capacity * 0 means the asset can not be borrowed any more */ uint256 borrowCapacity; /* * The supply capacity of the asset, will be checked in beforeMint() * -1 means there is no limit on the capacity * 0 means the asset can not be supplied any more */ uint256 supplyCapacity; // Whether market's mint is paused bool mintPaused; // Whether market's redeem is paused bool redeemPaused; // Whether market's borrow is paused bool borrowPaused; } /// @notice Mapping of iTokens to corresponding markets mapping(address => Market) public markets; struct AccountData { // Account's collateral assets EnumerableSetUpgradeable.AddressSet collaterals; // Account's borrowed assets EnumerableSetUpgradeable.AddressSet borrowed; } /// @dev Mapping of accounts' data, including collateral and borrowed assets mapping(address => AccountData) internal accountsData; /** * @notice Oracle to query the price of a given asset */ address public priceOracle; /** * @notice Multiplier used to calculate the maximum repayAmount when liquidating a borrow */ uint256 public closeFactorMantissa; // closeFactorMantissa must be strictly greater than this value uint256 internal constant closeFactorMinMantissa = 0.05e18; // 0.05 // closeFactorMantissa must not exceed this value uint256 internal constant closeFactorMaxMantissa = 0.9e18; // 0.9 /** * @notice Multiplier representing the discount on collateral that a liquidator receives */ uint256 public liquidationIncentiveMantissa; // liquidationIncentiveMantissa must be no less than this value uint256 internal constant liquidationIncentiveMinMantissa = 1.0e18; // 1.0 // liquidationIncentiveMantissa must be no greater than this value uint256 internal constant liquidationIncentiveMaxMantissa = 1.5e18; // 1.5 // collateralFactorMantissa must not exceed this value uint256 internal constant collateralFactorMaxMantissa = 1e18; // 1.0 // borrowFactorMantissa must not exceed this value uint256 internal constant borrowFactorMaxMantissa = 1e18; // 1.0 /** * @notice Guardian who can pause mint/borrow/liquidate/transfer in case of emergency */ address public pauseGuardian; /// @notice whether global transfer is paused bool public transferPaused; /// @notice whether global seize is paused bool public seizePaused; /** * @notice the address of reward distributor */ address public override rewardDistributor; /** * @dev Check if called by owner or pauseGuardian, and only owner can unpause */ modifier checkPauser(bool _paused) { require( msg.sender == owner || (msg.sender == pauseGuardian && _paused), "Only owner and guardian can pause and only owner can unpause" ); _; } /** * @notice Initializes the contract. */ function initialize() external initializer { __Ownable_init(); } /*********************************/ /******** Security Check *********/ /*********************************/ /** * @notice Ensure this is a Controller contract. */ function isController() external view override returns (bool) { return true; } /*********************************/ /******** Admin Operations *******/ /*********************************/ /** * @notice Admin function to add iToken into supported markets * Checks if the iToken already exsits * Will `revert()` if any check fails * @param _iToken The _iToken to add * @param _collateralFactor The _collateralFactor of _iToken * @param _borrowFactor The _borrowFactor of _iToken * @param _supplyCapacity The _supplyCapacity of _iToken * @param _distributionFactor The _distributionFactor of _iToken */ function _addMarket( address _iToken, uint256 _collateralFactor, uint256 _borrowFactor, uint256 _supplyCapacity, uint256 _borrowCapacity, uint256 _distributionFactor ) external override onlyOwner { require(IiToken(_iToken).isSupported(), "Token is not supported"); // Market must recognize this controller require( IiToken(_iToken).controller() == address(this), "Token's controller is not this one" ); // Market must not have been listed, EnumerableSet.add() will return false if it exsits require(iTokens.add(_iToken), "Token has already been listed"); require( _collateralFactor <= collateralFactorMaxMantissa, "Collateral factor invalid" ); require( _borrowFactor > 0 && _borrowFactor <= borrowFactorMaxMantissa, "Borrow factor invalid" ); // Its value will be taken into account when calculate account equity // Check if the price is available for the calculation require( IPriceOracle(priceOracle).getUnderlyingPrice(_iToken) != 0, "Underlying price is unavailable" ); markets[_iToken] = Market({ collateralFactorMantissa: _collateralFactor, borrowFactorMantissa: _borrowFactor, borrowCapacity: _borrowCapacity, supplyCapacity: _supplyCapacity, mintPaused: false, redeemPaused: false, borrowPaused: false }); IRewardDistributor(rewardDistributor)._addRecipient( _iToken, _distributionFactor ); emit MarketAdded( _iToken, _collateralFactor, _borrowFactor, _supplyCapacity, _borrowCapacity, _distributionFactor ); } /** * @notice Sets price oracle * @dev Admin function to set price oracle * @param _newOracle New oracle contract */ function _setPriceOracle(address _newOracle) external override onlyOwner { address _oldOracle = priceOracle; require( _newOracle != address(0) && _newOracle != _oldOracle, "Oracle address invalid" ); priceOracle = _newOracle; emit NewPriceOracle(_oldOracle, _newOracle); } /** * @notice Sets the closeFactor used when liquidating borrows * @dev Admin function to set closeFactor * @param _newCloseFactorMantissa New close factor, scaled by 1e18 */ function _setCloseFactor(uint256 _newCloseFactorMantissa) external override onlyOwner { require( _newCloseFactorMantissa >= closeFactorMinMantissa && _newCloseFactorMantissa <= closeFactorMaxMantissa, "Close factor invalid" ); uint256 _oldCloseFactorMantissa = closeFactorMantissa; closeFactorMantissa = _newCloseFactorMantissa; emit NewCloseFactor(_oldCloseFactorMantissa, _newCloseFactorMantissa); } /** * @notice Sets liquidationIncentive * @dev Admin function to set liquidationIncentive * @param _newLiquidationIncentiveMantissa New liquidationIncentive scaled by 1e18 */ function _setLiquidationIncentive(uint256 _newLiquidationIncentiveMantissa) external override onlyOwner { require( _newLiquidationIncentiveMantissa >= liquidationIncentiveMinMantissa && _newLiquidationIncentiveMantissa <= liquidationIncentiveMaxMantissa, "Liquidation incentive invalid" ); uint256 _oldLiquidationIncentiveMantissa = liquidationIncentiveMantissa; liquidationIncentiveMantissa = _newLiquidationIncentiveMantissa; emit NewLiquidationIncentive( _oldLiquidationIncentiveMantissa, _newLiquidationIncentiveMantissa ); } /** * @notice Sets the collateralFactor for a iToken * @dev Admin function to set collateralFactor for a iToken * @param _iToken The token to set the factor on * @param _newCollateralFactorMantissa The new collateral factor, scaled by 1e18 */ function _setCollateralFactor( address _iToken, uint256 _newCollateralFactorMantissa ) external override onlyOwner { _checkiTokenListed(_iToken); require( _newCollateralFactorMantissa <= collateralFactorMaxMantissa, "Collateral factor invalid" ); // Its value will be taken into account when calculate account equity // Check if the price is available for the calculation require( IPriceOracle(priceOracle).getUnderlyingPrice(_iToken) != 0, "Failed to set collateral factor, underlying price is unavailable" ); Market storage _market = markets[_iToken]; uint256 _oldCollateralFactorMantissa = _market.collateralFactorMantissa; _market.collateralFactorMantissa = _newCollateralFactorMantissa; emit NewCollateralFactor( _iToken, _oldCollateralFactorMantissa, _newCollateralFactorMantissa ); } /** * @notice Sets the borrowFactor for a iToken * @dev Admin function to set borrowFactor for a iToken * @param _iToken The token to set the factor on * @param _newBorrowFactorMantissa The new borrow factor, scaled by 1e18 */ function _setBorrowFactor(address _iToken, uint256 _newBorrowFactorMantissa) external override onlyOwner { _checkiTokenListed(_iToken); require( _newBorrowFactorMantissa > 0 && _newBorrowFactorMantissa <= borrowFactorMaxMantissa, "Borrow factor invalid" ); // Its value will be taken into account when calculate account equity // Check if the price is available for the calculation require( IPriceOracle(priceOracle).getUnderlyingPrice(_iToken) != 0, "Failed to set borrow factor, underlying price is unavailable" ); Market storage _market = markets[_iToken]; uint256 _oldBorrowFactorMantissa = _market.borrowFactorMantissa; _market.borrowFactorMantissa = _newBorrowFactorMantissa; emit NewBorrowFactor( _iToken, _oldBorrowFactorMantissa, _newBorrowFactorMantissa ); } /** * @notice Sets the borrowCapacity for a iToken * @dev Admin function to set borrowCapacity for a iToken * @param _iToken The token to set the capacity on * @param _newBorrowCapacity The new borrow capacity */ function _setBorrowCapacity(address _iToken, uint256 _newBorrowCapacity) external override onlyOwner { _checkiTokenListed(_iToken); Market storage _market = markets[_iToken]; uint256 oldBorrowCapacity = _market.borrowCapacity; _market.borrowCapacity = _newBorrowCapacity; emit NewBorrowCapacity(_iToken, oldBorrowCapacity, _newBorrowCapacity); } /** * @notice Sets the supplyCapacity for a iToken * @dev Admin function to set supplyCapacity for a iToken * @param _iToken The token to set the capacity on * @param _newSupplyCapacity The new supply capacity */ function _setSupplyCapacity(address _iToken, uint256 _newSupplyCapacity) external override onlyOwner { _checkiTokenListed(_iToken); Market storage _market = markets[_iToken]; uint256 oldSupplyCapacity = _market.supplyCapacity; _market.supplyCapacity = _newSupplyCapacity; emit NewSupplyCapacity(_iToken, oldSupplyCapacity, _newSupplyCapacity); } /** * @notice Sets the pauseGuardian * @dev Admin function to set pauseGuardian * @param _newPauseGuardian The new pause guardian */ function _setPauseGuardian(address _newPauseGuardian) external override onlyOwner { address _oldPauseGuardian = pauseGuardian; require( _newPauseGuardian != address(0) && _newPauseGuardian != _oldPauseGuardian, "Pause guardian address invalid" ); pauseGuardian = _newPauseGuardian; emit NewPauseGuardian(_oldPauseGuardian, _newPauseGuardian); } /** * @notice pause/unpause mint() for all iTokens * @dev Admin function, only owner and pauseGuardian can call this * @param _paused whether to pause or unpause */ function _setAllMintPaused(bool _paused) external override checkPauser(_paused) { EnumerableSetUpgradeable.AddressSet storage _iTokens = iTokens; uint256 _len = _iTokens.length(); for (uint256 i = 0; i < _len; i++) { _setMintPausedInternal(_iTokens.at(i), _paused); } } /** * @notice pause/unpause mint() for the iToken * @dev Admin function, only owner and pauseGuardian can call this * @param _iToken The iToken to pause/unpause * @param _paused whether to pause or unpause */ function _setMintPaused(address _iToken, bool _paused) external override checkPauser(_paused) { _checkiTokenListed(_iToken); _setMintPausedInternal(_iToken, _paused); } function _setMintPausedInternal(address _iToken, bool _paused) internal { markets[_iToken].mintPaused = _paused; emit MintPaused(_iToken, _paused); } /** * @notice pause/unpause redeem() for all iTokens * @dev Admin function, only owner and pauseGuardian can call this * @param _paused whether to pause or unpause */ function _setAllRedeemPaused(bool _paused) external override checkPauser(_paused) { EnumerableSetUpgradeable.AddressSet storage _iTokens = iTokens; uint256 _len = _iTokens.length(); for (uint256 i = 0; i < _len; i++) { _setRedeemPausedInternal(_iTokens.at(i), _paused); } } /** * @notice pause/unpause redeem() for the iToken * @dev Admin function, only owner and pauseGuardian can call this * @param _iToken The iToken to pause/unpause * @param _paused whether to pause or unpause */ function _setRedeemPaused(address _iToken, bool _paused) external override checkPauser(_paused) { _checkiTokenListed(_iToken); _setRedeemPausedInternal(_iToken, _paused); } function _setRedeemPausedInternal(address _iToken, bool _paused) internal { markets[_iToken].redeemPaused = _paused; emit RedeemPaused(_iToken, _paused); } /** * @notice pause/unpause borrow() for all iTokens * @dev Admin function, only owner and pauseGuardian can call this * @param _paused whether to pause or unpause */ function _setAllBorrowPaused(bool _paused) external override checkPauser(_paused) { EnumerableSetUpgradeable.AddressSet storage _iTokens = iTokens; uint256 _len = _iTokens.length(); for (uint256 i = 0; i < _len; i++) { _setBorrowPausedInternal(_iTokens.at(i), _paused); } } /** * @notice pause/unpause borrow() for the iToken * @dev Admin function, only owner and pauseGuardian can call this * @param _iToken The iToken to pause/unpause * @param _paused whether to pause or unpause */ function _setBorrowPaused(address _iToken, bool _paused) external override checkPauser(_paused) { _checkiTokenListed(_iToken); _setBorrowPausedInternal(_iToken, _paused); } function _setBorrowPausedInternal(address _iToken, bool _paused) internal { markets[_iToken].borrowPaused = _paused; emit BorrowPaused(_iToken, _paused); } /** * @notice pause/unpause global transfer() * @dev Admin function, only owner and pauseGuardian can call this * @param _paused whether to pause or unpause */ function _setTransferPaused(bool _paused) external override checkPauser(_paused) { _setTransferPausedInternal(_paused); } function _setTransferPausedInternal(bool _paused) internal { transferPaused = _paused; emit TransferPaused(_paused); } /** * @notice pause/unpause global seize() * @dev Admin function, only owner and pauseGuardian can call this * @param _paused whether to pause or unpause */ function _setSeizePaused(bool _paused) external override checkPauser(_paused) { _setSeizePausedInternal(_paused); } function _setSeizePausedInternal(bool _paused) internal { seizePaused = _paused; emit SeizePaused(_paused); } /** * @notice pause/unpause all actions iToken, including mint/redeem/borrow * @dev Admin function, only owner and pauseGuardian can call this * @param _paused whether to pause or unpause */ function _setiTokenPaused(address _iToken, bool _paused) external override checkPauser(_paused) { _checkiTokenListed(_iToken); _setiTokenPausedInternal(_iToken, _paused); } function _setiTokenPausedInternal(address _iToken, bool _paused) internal { Market storage _market = markets[_iToken]; _market.mintPaused = _paused; emit MintPaused(_iToken, _paused); _market.redeemPaused = _paused; emit RedeemPaused(_iToken, _paused); _market.borrowPaused = _paused; emit BorrowPaused(_iToken, _paused); } /** * @notice pause/unpause entire protocol, including mint/redeem/borrow/seize/transfer * @dev Admin function, only owner and pauseGuardian can call this * @param _paused whether to pause or unpause */ function _setProtocolPaused(bool _paused) external override checkPauser(_paused) { EnumerableSetUpgradeable.AddressSet storage _iTokens = iTokens; uint256 _len = _iTokens.length(); for (uint256 i = 0; i < _len; i++) { address _iToken = _iTokens.at(i); _setiTokenPausedInternal(_iToken, _paused); } _setTransferPausedInternal(_paused); _setSeizePausedInternal(_paused); } /** * @notice Sets Reward Distributor * @dev Admin function to set reward distributor * @param _newRewardDistributor new reward distributor */ function _setRewardDistributor(address _newRewardDistributor) external override onlyOwner { address _oldRewardDistributor = rewardDistributor; require( _newRewardDistributor != address(0) && _newRewardDistributor != _oldRewardDistributor, "Reward Distributor address invalid" ); rewardDistributor = _newRewardDistributor; emit NewRewardDistributor(_oldRewardDistributor, _newRewardDistributor); } /*********************************/ /******** Policy Hooks **********/ /*********************************/ /** * @notice Hook function before iToken `mint()` * Checks if the account should be allowed to mint the given iToken * Will `revert()` if any check fails * @param _iToken The iToken to check the mint against * @param _minter The account which would get the minted tokens * @param _mintAmount The amount of underlying being minted to iToken */ function beforeMint( address _iToken, address _minter, uint256 _mintAmount ) external override { _checkiTokenListed(_iToken); Market storage _market = markets[_iToken]; require(!_market.mintPaused, "Token mint has been paused"); // Check the iToken's supply capacity, -1 means no limit uint256 _totalSupplyUnderlying = IERC20Upgradeable(_iToken).totalSupply().rmul( IiToken(_iToken).exchangeRateStored() ); require( _totalSupplyUnderlying.add(_mintAmount) <= _market.supplyCapacity, "Token supply capacity reached" ); // Update the Reward Distribution Supply state and distribute reward to suppplier IRewardDistributor(rewardDistributor).updateDistributionState( _iToken, false ); IRewardDistributor(rewardDistributor).updateReward( _iToken, _minter, false ); } /** * @notice Hook function after iToken `mint()` * Will `revert()` if any operation fails * @param _iToken The iToken being minted * @param _minter The account which would get the minted tokens * @param _mintAmount The amount of underlying being minted to iToken * @param _mintedAmount The amount of iToken being minted */ function afterMint( address _iToken, address _minter, uint256 _mintAmount, uint256 _mintedAmount ) external override { _iToken; _minter; _mintAmount; _mintedAmount; } /** * @notice Hook function before iToken `redeem()` * Checks if the account should be allowed to redeem the given iToken * Will `revert()` if any check fails * @param _iToken The iToken to check the redeem against * @param _redeemer The account which would redeem iToken * @param _redeemAmount The amount of iToken to redeem */ function beforeRedeem( address _iToken, address _redeemer, uint256 _redeemAmount ) external virtual override { // _redeemAllowed below will check whether _iToken is listed require(!markets[_iToken].redeemPaused, "Token redeem has been paused"); _redeemAllowed(_iToken, _redeemer, _redeemAmount); // Update the Reward Distribution Supply state and distribute reward to suppplier IRewardDistributor(rewardDistributor).updateDistributionState( _iToken, false ); IRewardDistributor(rewardDistributor).updateReward( _iToken, _redeemer, false ); } /** * @notice Hook function after iToken `redeem()` * Will `revert()` if any operation fails * @param _iToken The iToken being redeemed * @param _redeemer The account which redeemed iToken * @param _redeemAmount The amount of iToken being redeemed * @param _redeemedUnderlying The amount of underlying being redeemed */ function afterRedeem( address _iToken, address _redeemer, uint256 _redeemAmount, uint256 _redeemedUnderlying ) external virtual override { _iToken; _redeemer; _redeemAmount; _redeemedUnderlying; } /** * @notice Hook function before iToken `borrow()` * Checks if the account should be allowed to borrow the given iToken * Will `revert()` if any check fails * @param _iToken The iToken to check the borrow against * @param _borrower The account which would borrow iToken * @param _borrowAmount The amount of underlying to borrow */ function beforeBorrow( address _iToken, address _borrower, uint256 _borrowAmount ) external virtual override { _checkiTokenListed(_iToken); Market storage _market = markets[_iToken]; require(!_market.borrowPaused, "Token borrow has been paused"); if (!hasBorrowed(_borrower, _iToken)) { // Unlike collaterals, borrowed asset can only be added by iToken, // rather than enabled by user directly. require(msg.sender == _iToken, "sender must be iToken"); // Have checked _iToken is listed, just add it _addToBorrowed(_borrower, _iToken); } // Check borrower's equity (, uint256 _shortfall, , ) = calcAccountEquityWithEffect(_borrower, _iToken, 0, _borrowAmount); require(_shortfall == 0, "Account has some shortfall"); // Check the iToken's borrow capacity, -1 means no limit uint256 _totalBorrows = IiToken(_iToken).totalBorrows(); require( _totalBorrows.add(_borrowAmount) <= _market.borrowCapacity, "Token borrow capacity reached" ); // Update the Reward Distribution Borrow state and distribute reward to borrower IRewardDistributor(rewardDistributor).updateDistributionState( _iToken, true ); IRewardDistributor(rewardDistributor).updateReward( _iToken, _borrower, true ); } /** * @notice Hook function after iToken `borrow()` * Will `revert()` if any operation fails * @param _iToken The iToken being borrewd * @param _borrower The account which borrowed iToken * @param _borrowedAmount The amount of underlying being borrowed */ function afterBorrow( address _iToken, address _borrower, uint256 _borrowedAmount ) external virtual override { _iToken; _borrower; _borrowedAmount; } /** * @notice Hook function before iToken `repayBorrow()` * Checks if the account should be allowed to repay the given iToken * for the borrower. Will `revert()` if any check fails * @param _iToken The iToken to verify the repay against * @param _payer The account which would repay iToken * @param _borrower The account which has borrowed * @param _repayAmount The amount of underlying to repay */ function beforeRepayBorrow( address _iToken, address _payer, address _borrower, uint256 _repayAmount ) external override { _checkiTokenListed(_iToken); // Update the Reward Distribution Borrow state and distribute reward to borrower IRewardDistributor(rewardDistributor).updateDistributionState( _iToken, true ); IRewardDistributor(rewardDistributor).updateReward( _iToken, _borrower, true ); _payer; _repayAmount; } /** * @notice Hook function after iToken `repayBorrow()` * Will `revert()` if any operation fails * @param _iToken The iToken being repaid * @param _payer The account which would repay * @param _borrower The account which has borrowed * @param _repayAmount The amount of underlying being repaied */ function afterRepayBorrow( address _iToken, address _payer, address _borrower, uint256 _repayAmount ) external override { _checkiTokenListed(_iToken); // Remove _iToken from borrowed list if new borrow balance is 0 if (IiToken(_iToken).borrowBalanceStored(_borrower) == 0) { // Only allow called by iToken as we are going to remove this token from borrower's borrowed list require(msg.sender == _iToken, "sender must be iToken"); // Have checked _iToken is listed, just remove it _removeFromBorrowed(_borrower, _iToken); } _payer; _repayAmount; } /** * @notice Hook function before iToken `liquidateBorrow()` * Checks if the account should be allowed to liquidate the given iToken * for the borrower. Will `revert()` if any check fails * @param _iTokenBorrowed The iToken was borrowed * @param _iTokenCollateral The collateral iToken to be liqudate with * @param _liquidator The account which would repay the borrowed iToken * @param _borrower The account which has borrowed * @param _repayAmount The amount of underlying to repay */ function beforeLiquidateBorrow( address _iTokenBorrowed, address _iTokenCollateral, address _liquidator, address _borrower, uint256 _repayAmount ) external override { // Tokens must have been listed require( iTokens.contains(_iTokenBorrowed) && iTokens.contains(_iTokenCollateral), "Tokens have not been listed" ); (, uint256 _shortfall, , ) = calcAccountEquity(_borrower); require(_shortfall > 0, "Account does not have shortfall"); // Only allowed to repay the borrow balance's close factor uint256 _borrowBalance = IiToken(_iTokenBorrowed).borrowBalanceStored(_borrower); uint256 _maxRepay = _borrowBalance.rmul(closeFactorMantissa); require(_repayAmount <= _maxRepay, "Repay exceeds max repay allowed"); _liquidator; } /** * @notice Hook function after iToken `liquidateBorrow()` * Will `revert()` if any operation fails * @param _iTokenBorrowed The iToken was borrowed * @param _iTokenCollateral The collateral iToken to be seized * @param _liquidator The account which would repay and seize * @param _borrower The account which has borrowed * @param _repaidAmount The amount of underlying being repaied * @param _seizedAmount The amount of collateral being seized */ function afterLiquidateBorrow( address _iTokenBorrowed, address _iTokenCollateral, address _liquidator, address _borrower, uint256 _repaidAmount, uint256 _seizedAmount ) external override { _iTokenBorrowed; _iTokenCollateral; _liquidator; _borrower; _repaidAmount; _seizedAmount; // Unlike repayBorrow, liquidateBorrow does not allow to repay all borrow balance // No need to check whether should remove from borrowed asset list } /** * @notice Hook function before iToken `seize()` * Checks if the liquidator should be allowed to seize the collateral iToken * Will `revert()` if any check fails * @param _iTokenCollateral The collateral iToken to be seize * @param _iTokenBorrowed The iToken was borrowed * @param _liquidator The account which has repaid the borrowed iToken * @param _borrower The account which has borrowed * @param _seizeAmount The amount of collateral iToken to seize */ function beforeSeize( address _iTokenCollateral, address _iTokenBorrowed, address _liquidator, address _borrower, uint256 _seizeAmount ) external override { require(!seizePaused, "Seize has been paused"); // Markets must have been listed require( iTokens.contains(_iTokenBorrowed) && iTokens.contains(_iTokenCollateral), "Tokens have not been listed" ); // Sanity Check the controllers require( IiToken(_iTokenBorrowed).controller() == IiToken(_iTokenCollateral).controller(), "Controller mismatch between Borrowed and Collateral" ); // Update the Reward Distribution Supply state on collateral IRewardDistributor(rewardDistributor).updateDistributionState( _iTokenCollateral, false ); // Update reward of liquidator and borrower on collateral IRewardDistributor(rewardDistributor).updateReward( _iTokenCollateral, _liquidator, false ); IRewardDistributor(rewardDistributor).updateReward( _iTokenCollateral, _borrower, false ); _seizeAmount; } /** * @notice Hook function after iToken `seize()` * Will `revert()` if any operation fails * @param _iTokenCollateral The collateral iToken to be seized * @param _iTokenBorrowed The iToken was borrowed * @param _liquidator The account which has repaid and seized * @param _borrower The account which has borrowed * @param _seizedAmount The amount of collateral being seized */ function afterSeize( address _iTokenCollateral, address _iTokenBorrowed, address _liquidator, address _borrower, uint256 _seizedAmount ) external override { _iTokenBorrowed; _iTokenCollateral; _liquidator; _borrower; _seizedAmount; } /** * @notice Hook function before iToken `transfer()` * Checks if the transfer should be allowed * Will `revert()` if any check fails * @param _iToken The iToken to be transfered * @param _from The account to be transfered from * @param _to The account to be transfered to * @param _amount The amount to be transfered */ function beforeTransfer( address _iToken, address _from, address _to, uint256 _amount ) external override { // _redeemAllowed below will check whether _iToken is listed require(!transferPaused, "Transfer has been paused"); // Check account equity with this amount to decide whether the transfer is allowed _redeemAllowed(_iToken, _from, _amount); // Update the Reward Distribution supply state IRewardDistributor(rewardDistributor).updateDistributionState( _iToken, false ); // Update reward of from and to IRewardDistributor(rewardDistributor).updateReward( _iToken, _from, false ); IRewardDistributor(rewardDistributor).updateReward(_iToken, _to, false); } /** * @notice Hook function after iToken `transfer()` * Will `revert()` if any operation fails * @param _iToken The iToken was transfered * @param _from The account was transfer from * @param _to The account was transfer to * @param _amount The amount was transfered */ function afterTransfer( address _iToken, address _from, address _to, uint256 _amount ) external override { _iToken; _from; _to; _amount; } /** * @notice Hook function before iToken `flashloan()` * Checks if the flashloan should be allowed * Will `revert()` if any check fails * @param _iToken The iToken to be flashloaned * @param _to The account flashloaned transfer to * @param _amount The amount to be flashloaned */ function beforeFlashloan( address _iToken, address _to, uint256 _amount ) external override { // Flashloan share the same pause state with borrow require(!markets[_iToken].borrowPaused, "Token borrow has been paused"); _checkiTokenListed(_iToken); _to; _amount; // Update the Reward Distribution Borrow state IRewardDistributor(rewardDistributor).updateDistributionState( _iToken, true ); } /** * @notice Hook function after iToken `flashloan()` * Will `revert()` if any operation fails * @param _iToken The iToken was flashloaned * @param _to The account flashloan transfer to * @param _amount The amount was flashloaned */ function afterFlashloan( address _iToken, address _to, uint256 _amount ) external override { _iToken; _to; _amount; } /*********************************/ /***** Internal Functions *******/ /*********************************/ function _redeemAllowed( address _iToken, address _redeemer, uint256 _amount ) private view { _checkiTokenListed(_iToken); // No need to check liquidity if _redeemer has not used _iToken as collateral if (!accountsData[_redeemer].collaterals.contains(_iToken)) { return; } (, uint256 _shortfall, , ) = calcAccountEquityWithEffect(_redeemer, _iToken, _amount, 0); require(_shortfall == 0, "Account has some shortfall"); } /** * @dev Check if _iToken is listed */ function _checkiTokenListed(address _iToken) internal view { require(iTokens.contains(_iToken), "Token has not been listed"); } /*********************************/ /** Account equity calculation ***/ /*********************************/ /** * @notice Calculates current account equity * @param _account The account to query equity of * @return account equity, shortfall, collateral value, borrowed value. */ function calcAccountEquity(address _account) public view override returns ( uint256, uint256, uint256, uint256 ) { return calcAccountEquityWithEffect(_account, address(0), 0, 0); } /** * @dev Local vars for avoiding stack-depth limits in calculating account liquidity. * Note that `iTokenBalance` is the number of iTokens the account owns in the collateral, * whereas `borrowBalance` is the amount of underlying that the account has borrowed. */ struct AccountEquityLocalVars { uint256 sumCollateral; uint256 sumBorrowed; uint256 iTokenBalance; uint256 borrowBalance; uint256 exchangeRateMantissa; uint256 underlyingPrice; uint256 collateralValue; uint256 borrowValue; } /** * @notice Calculates current account equity plus some token and amount to effect * @param _account The account to query equity of * @param _tokenToEffect The token address to add some additional redeeem/borrow * @param _redeemAmount The additional amount to redeem * @param _borrowAmount The additional amount to borrow * @return account euqity, shortfall, collateral value, borrowed value plus the effect. */ function calcAccountEquityWithEffect( address _account, address _tokenToEffect, uint256 _redeemAmount, uint256 _borrowAmount ) internal view virtual returns ( uint256, uint256, uint256, uint256 ) { AccountEquityLocalVars memory _local; AccountData storage _accountData = accountsData[_account]; // Calculate value of all collaterals // collateralValuePerToken = underlyingPrice * exchangeRate * collateralFactor // collateralValue = balance * collateralValuePerToken // sumCollateral += collateralValue uint256 _len = _accountData.collaterals.length(); for (uint256 i = 0; i < _len; i++) { IiToken _token = IiToken(_accountData.collaterals.at(i)); _local.iTokenBalance = IERC20Upgradeable(address(_token)).balanceOf( _account ); _local.exchangeRateMantissa = _token.exchangeRateStored(); if (_tokenToEffect == address(_token) && _redeemAmount > 0) { _local.iTokenBalance = _local.iTokenBalance.sub(_redeemAmount); } _local.underlyingPrice = IPriceOracle(priceOracle) .getUnderlyingPrice(address(_token)); require( _local.underlyingPrice != 0, "Invalid price to calculate account equity" ); _local.collateralValue = _local .iTokenBalance .mul(_local.underlyingPrice) .rmul(_local.exchangeRateMantissa) .rmul(markets[address(_token)].collateralFactorMantissa); _local.sumCollateral = _local.sumCollateral.add( _local.collateralValue ); } // Calculate all borrowed value // borrowValue = underlyingPrice * underlyingBorrowed / borrowFactor // sumBorrowed += borrowValue _len = _accountData.borrowed.length(); for (uint256 i = 0; i < _len; i++) { IiToken _token = IiToken(_accountData.borrowed.at(i)); _local.borrowBalance = _token.borrowBalanceStored(_account); if (_tokenToEffect == address(_token) && _borrowAmount > 0) { _local.borrowBalance = _local.borrowBalance.add(_borrowAmount); } _local.underlyingPrice = IPriceOracle(priceOracle) .getUnderlyingPrice(address(_token)); require( _local.underlyingPrice != 0, "Invalid price to calculate account equity" ); // borrowFactorMantissa can not be set to 0 _local.borrowValue = _local .borrowBalance .mul(_local.underlyingPrice) .rdiv(markets[address(_token)].borrowFactorMantissa); _local.sumBorrowed = _local.sumBorrowed.add(_local.borrowValue); } // Should never underflow return _local.sumCollateral > _local.sumBorrowed ? ( _local.sumCollateral - _local.sumBorrowed, uint256(0), _local.sumCollateral, _local.sumBorrowed ) : ( uint256(0), _local.sumBorrowed - _local.sumCollateral, _local.sumCollateral, _local.sumBorrowed ); } /** * @notice Calculate amount of collateral iToken to seize after repaying an underlying amount * @dev Used in liquidation * @param _iTokenBorrowed The iToken was borrowed * @param _iTokenCollateral The collateral iToken to be seized * @param _actualRepayAmount The amount of underlying token liquidator has repaied * @return _seizedTokenCollateral amount of iTokenCollateral tokens to be seized */ function liquidateCalculateSeizeTokens( address _iTokenBorrowed, address _iTokenCollateral, uint256 _actualRepayAmount ) external view virtual override returns (uint256 _seizedTokenCollateral) { /* Read oracle prices for borrowed and collateral assets */ uint256 _priceBorrowed = IPriceOracle(priceOracle).getUnderlyingPrice(_iTokenBorrowed); uint256 _priceCollateral = IPriceOracle(priceOracle).getUnderlyingPrice(_iTokenCollateral); require( _priceBorrowed != 0 && _priceCollateral != 0, "Borrowed or Collateral asset price is invalid" ); uint256 _valueRepayPlusIncentive = _actualRepayAmount.mul(_priceBorrowed).rmul( liquidationIncentiveMantissa ); // Use stored value here as it is view function uint256 _exchangeRateMantissa = IiToken(_iTokenCollateral).exchangeRateStored(); // seizedTokenCollateral = valueRepayPlusIncentive / valuePerTokenCollateral // valuePerTokenCollateral = exchangeRateMantissa * priceCollateral _seizedTokenCollateral = _valueRepayPlusIncentive .rdiv(_exchangeRateMantissa) .div(_priceCollateral); } /*********************************/ /*** Account Markets Operation ***/ /*********************************/ /** * @notice Returns the markets list the account has entered * @param _account The address of the account to query * @return _accountCollaterals The markets list the account has entered */ function getEnteredMarkets(address _account) external view override returns (address[] memory _accountCollaterals) { AccountData storage _accountData = accountsData[_account]; uint256 _len = _accountData.collaterals.length(); _accountCollaterals = new address[](_len); for (uint256 i = 0; i < _len; i++) { _accountCollaterals[i] = _accountData.collaterals.at(i); } } /** * @notice Add markets to `msg.sender`'s markets list for liquidity calculations * @param _iTokens The list of addresses of the iToken markets to be entered * @return _results Success indicator for whether each corresponding market was entered */ function enterMarkets(address[] calldata _iTokens) external override returns (bool[] memory _results) { uint256 _len = _iTokens.length; _results = new bool[](_len); for (uint256 i = 0; i < _len; i++) { _results[i] = _enterMarket(_iTokens[i], msg.sender); } } /** * @notice Add the market to the account's markets list for liquidity calculations * @param _iToken The market to enter * @param _account The address of the account to modify * @return True if entered successfully, false for non-listed market or other errors */ function _enterMarket(address _iToken, address _account) internal returns (bool) { // Market not listed, skip it if (!iTokens.contains(_iToken)) { return false; } // add() will return false if iToken is in account's market list if (accountsData[_account].collaterals.add(_iToken)) { emit MarketEntered(_iToken, _account); } return true; } /** * @notice Only expect to be called by iToken contract. * @dev Add the market to the account's markets list for liquidity calculations * @param _market The market to enter * @param _account The address of the account to modify */ function enterMarketFromiToken(address _market, address _account) external override { // msg.sender must be listed iToken, typically a iMSDMiniPool _checkiTokenListed(msg.sender); require( _enterMarket(_market, _account), "enterMarketFromiToken: Only can enter a listed market!" ); } /** * @notice Returns whether the given account has entered the market * @param _account The address of the account to check * @param _iToken The iToken to check against * @return True if the account has entered the market, otherwise false. */ function hasEnteredMarket(address _account, address _iToken) external view override returns (bool) { return accountsData[_account].collaterals.contains(_iToken); } /** * @notice Remove markets from `msg.sender`'s collaterals for liquidity calculations * @param _iTokens The list of addresses of the iToken to exit * @return _results Success indicators for whether each corresponding market was exited */ function exitMarkets(address[] calldata _iTokens) external override returns (bool[] memory _results) { uint256 _len = _iTokens.length; _results = new bool[](_len); for (uint256 i = 0; i < _len; i++) { _results[i] = _exitMarket(_iTokens[i], msg.sender); } } /** * @notice Remove the market to the account's markets list for liquidity calculations * @param _iToken The market to exit * @param _account The address of the account to modify * @return True if exit successfully, false for non-listed market or other errors */ function _exitMarket(address _iToken, address _account) internal returns (bool) { // Market not listed, skip it if (!iTokens.contains(_iToken)) { return true; } // Account has not entered this market, skip it if (!accountsData[_account].collaterals.contains(_iToken)) { return true; } // Get the iToken balance uint256 _balance = IERC20Upgradeable(_iToken).balanceOf(_account); // Check account's equity if all balance are redeemed // which means iToken can be removed from collaterals _redeemAllowed(_iToken, _account, _balance); // Have checked account has entered market before accountsData[_account].collaterals.remove(_iToken); emit MarketExited(_iToken, _account); return true; } /** * @notice Returns the asset list the account has borrowed * @param _account The address of the account to query * @return _borrowedAssets The asset list the account has borrowed */ function getBorrowedAssets(address _account) external view override returns (address[] memory _borrowedAssets) { AccountData storage _accountData = accountsData[_account]; uint256 _len = _accountData.borrowed.length(); _borrowedAssets = new address[](_len); for (uint256 i = 0; i < _len; i++) { _borrowedAssets[i] = _accountData.borrowed.at(i); } } /** * @notice Add the market to the account's borrowed list for equity calculations * @param _iToken The iToken of underlying to borrow * @param _account The address of the account to modify */ function _addToBorrowed(address _account, address _iToken) internal { // add() will return false if iToken is in account's market list if (accountsData[_account].borrowed.add(_iToken)) { emit BorrowedAdded(_iToken, _account); } } /** * @notice Returns whether the given account has borrowed the given iToken * @param _account The address of the account to check * @param _iToken The iToken to check against * @return True if the account has borrowed the iToken, otherwise false. */ function hasBorrowed(address _account, address _iToken) public view override returns (bool) { return accountsData[_account].borrowed.contains(_iToken); } /** * @notice Remove the iToken from the account's borrowed list * @param _iToken The iToken to remove * @param _account The address of the account to modify */ function _removeFromBorrowed(address _account, address _iToken) internal { // remove() will return false if iToken does not exist in account's borrowed list if (accountsData[_account].borrowed.remove(_iToken)) { emit BorrowedRemoved(_iToken, _account); } } /*********************************/ /****** General Information ******/ /*********************************/ /** * @notice Return all of the iTokens * @return _alliTokens The list of iToken addresses */ function getAlliTokens() public view override returns (address[] memory _alliTokens) { EnumerableSetUpgradeable.AddressSet storage _iTokens = iTokens; uint256 _len = _iTokens.length(); _alliTokens = new address[](_len); for (uint256 i = 0; i < _len; i++) { _alliTokens[i] = _iTokens.at(i); } } /** * @notice Check whether a iToken is listed in controller * @param _iToken The iToken to check for * @return true if the iToken is listed otherwise false */ function hasiToken(address _iToken) public view override returns (bool) { return iTokens.contains(_iToken); } }
[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"BorrowPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"BorrowedAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"BorrowedRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"collateralFactor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"borrowFactor","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supplyCapacity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"borrowCapacity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"distributionFactor","type":"uint256"}],"name":"MarketAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"MarketEntered","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"MarketExited","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"MintPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldBorrowCapacity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBorrowCapacity","type":"uint256"}],"name":"NewBorrowCapacity","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldBorrowFactorMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newBorrowFactorMantissa","type":"uint256"}],"name":"NewBorrowFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldCloseFactorMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCloseFactorMantissa","type":"uint256"}],"name":"NewCloseFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldCollateralFactorMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCollateralFactorMantissa","type":"uint256"}],"name":"NewCollateralFactor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldLiquidationIncentiveMantissa","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLiquidationIncentiveMantissa","type":"uint256"}],"name":"NewLiquidationIncentive","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"NewOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPauseGuardian","type":"address"},{"indexed":false,"internalType":"address","name":"newPauseGuardian","type":"address"}],"name":"NewPauseGuardian","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldPendingOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newPendingOwner","type":"address"}],"name":"NewPendingOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldPriceOracle","type":"address"},{"indexed":false,"internalType":"address","name":"newPriceOracle","type":"address"}],"name":"NewPriceOracle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldRewardDistributor","type":"address"},{"indexed":false,"internalType":"address","name":"_newRewardDistributor","type":"address"}],"name":"NewRewardDistributor","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"oldSupplyCapacity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newSupplyCapacity","type":"uint256"}],"name":"NewSupplyCapacity","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"iToken","type":"address"},{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"RedeemPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"SeizePaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"paused","type":"bool"}],"name":"TransferPaused","type":"event"},{"inputs":[],"name":"_acceptOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"uint256","name":"_collateralFactor","type":"uint256"},{"internalType":"uint256","name":"_borrowFactor","type":"uint256"},{"internalType":"uint256","name":"_supplyCapacity","type":"uint256"},{"internalType":"uint256","name":"_borrowCapacity","type":"uint256"},{"internalType":"uint256","name":"_distributionFactor","type":"uint256"}],"name":"_addMarket","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"_setAllBorrowPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"_setAllMintPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"_setAllRedeemPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"uint256","name":"_newBorrowCapacity","type":"uint256"}],"name":"_setBorrowCapacity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"uint256","name":"_newBorrowFactorMantissa","type":"uint256"}],"name":"_setBorrowFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"bool","name":"_paused","type":"bool"}],"name":"_setBorrowPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCloseFactorMantissa","type":"uint256"}],"name":"_setCloseFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"uint256","name":"_newCollateralFactorMantissa","type":"uint256"}],"name":"_setCollateralFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newLiquidationIncentiveMantissa","type":"uint256"}],"name":"_setLiquidationIncentive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"bool","name":"_paused","type":"bool"}],"name":"_setMintPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newPauseGuardian","type":"address"}],"name":"_setPauseGuardian","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"newPendingOwner","type":"address"}],"name":"_setPendingOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOracle","type":"address"}],"name":"_setPriceOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"_setProtocolPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"bool","name":"_paused","type":"bool"}],"name":"_setRedeemPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newRewardDistributor","type":"address"}],"name":"_setRewardDistributor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"_setSeizePaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"uint256","name":"_newSupplyCapacity","type":"uint256"}],"name":"_setSupplyCapacity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"_setTransferPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"bool","name":"_paused","type":"bool"}],"name":"_setiTokenPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_borrowedAmount","type":"uint256"}],"name":"afterBorrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"afterFlashloan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iTokenBorrowed","type":"address"},{"internalType":"address","name":"_iTokenCollateral","type":"address"},{"internalType":"address","name":"_liquidator","type":"address"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_repaidAmount","type":"uint256"},{"internalType":"uint256","name":"_seizedAmount","type":"uint256"}],"name":"afterLiquidateBorrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_minter","type":"address"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"uint256","name":"_mintedAmount","type":"uint256"}],"name":"afterMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_redeemer","type":"address"},{"internalType":"uint256","name":"_redeemAmount","type":"uint256"},{"internalType":"uint256","name":"_redeemedUnderlying","type":"uint256"}],"name":"afterRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_payer","type":"address"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_repayAmount","type":"uint256"}],"name":"afterRepayBorrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iTokenCollateral","type":"address"},{"internalType":"address","name":"_iTokenBorrowed","type":"address"},{"internalType":"address","name":"_liquidator","type":"address"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_seizedAmount","type":"uint256"}],"name":"afterSeize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"afterTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_borrowAmount","type":"uint256"}],"name":"beforeBorrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"beforeFlashloan","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iTokenBorrowed","type":"address"},{"internalType":"address","name":"_iTokenCollateral","type":"address"},{"internalType":"address","name":"_liquidator","type":"address"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_repayAmount","type":"uint256"}],"name":"beforeLiquidateBorrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_minter","type":"address"},{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"beforeMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_redeemer","type":"address"},{"internalType":"uint256","name":"_redeemAmount","type":"uint256"}],"name":"beforeRedeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_payer","type":"address"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_repayAmount","type":"uint256"}],"name":"beforeRepayBorrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iTokenCollateral","type":"address"},{"internalType":"address","name":"_iTokenBorrowed","type":"address"},{"internalType":"address","name":"_liquidator","type":"address"},{"internalType":"address","name":"_borrower","type":"address"},{"internalType":"uint256","name":"_seizeAmount","type":"uint256"}],"name":"beforeSeize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"beforeTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"calcAccountEquity","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"closeFactorMantissa","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_market","type":"address"},{"internalType":"address","name":"_account","type":"address"}],"name":"enterMarketFromiToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_iTokens","type":"address[]"}],"name":"enterMarkets","outputs":[{"internalType":"bool[]","name":"_results","type":"bool[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_iTokens","type":"address[]"}],"name":"exitMarkets","outputs":[{"internalType":"bool[]","name":"_results","type":"bool[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getAlliTokens","outputs":[{"internalType":"address[]","name":"_alliTokens","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getBorrowedAssets","outputs":[{"internalType":"address[]","name":"_borrowedAssets","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"getEnteredMarkets","outputs":[{"internalType":"address[]","name":"_accountCollaterals","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_iToken","type":"address"}],"name":"hasBorrowed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"address","name":"_iToken","type":"address"}],"name":"hasEnteredMarket","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_iToken","type":"address"}],"name":"hasiToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isController","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_iTokenBorrowed","type":"address"},{"internalType":"address","name":"_iTokenCollateral","type":"address"},{"internalType":"uint256","name":"_actualRepayAmount","type":"uint256"}],"name":"liquidateCalculateSeizeTokens","outputs":[{"internalType":"uint256","name":"_seizedTokenCollateral","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidationIncentiveMantissa","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"markets","outputs":[{"internalType":"uint256","name":"collateralFactorMantissa","type":"uint256"},{"internalType":"uint256","name":"borrowFactorMantissa","type":"uint256"},{"internalType":"uint256","name":"borrowCapacity","type":"uint256"},{"internalType":"uint256","name":"supplyCapacity","type":"uint256"},{"internalType":"bool","name":"mintPaused","type":"bool"},{"internalType":"bool","name":"redeemPaused","type":"bool"},{"internalType":"bool","name":"borrowPaused","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseGuardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardDistributor","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"seizePaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"transferPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50615043806100206000396000f3fe608060405234801561001057600080fd5b50600436106103af5760003560e01c80638ebf6364116101f4578063d5b443601161011a578063e4028eee116100ad578063f079420a1161007c578063f079420a14610d88578063f1575f0814610dc4578063fb2cb34e14610df2578063fc4d33f914610dfa576103af565b8063e4028eee14610d35578063e715d96a14610d61578063e875544614610d80578063efced38514610afb576103af565b8063de65f41b116100e9578063de65f41b14610971578063e29f7f5e14610cd2578063e30c397814610cf1578063e33af48a14610cf9576103af565b8063d5b4436014610c15578063d79287d714610c41578063d8f5a57214610c85578063dbb32d6814610cb3576103af565b8063af505ad911610192578063ca498ad611610161578063ca498ad614610afb578063cb6db19c14610b31578063d0af413814610b77578063d4d4847314610be7576103af565b8063af505ad9146109f3578063bd8296c214610a29578063c299823814610a55578063c488847b14610ac5576103af565b8063a2ddeb85116101ce578063a2ddeb8514610971578063a8f4e9f6146109ad578063ab1777d2146109e3578063acc2166a146109eb576103af565b80638ebf6364146108da5780639d8cc5c4146108f9578063a09cf78b14610925576103af565b80634fd42e17116102d95780637160a8701161027757806386b841871161024657806386b84187146108125780638ccb720b146108485780638da5cb5b1461086e5780638e8f294b14610876576103af565b80637160a8701461077257806372b4304a146107a05780638129fc1c146107dc5780638283e3e2146107e4576103af565b80635f5af1aa116102b35780635f5af1aa146106d25780635f7bc006146106f857806360a8a931146107445780636e96dfd71461074c576103af565b80634fd42e171461066957806355ee1fe1146106865780635c254d11146106ac576103af565b80632a6a6065116103515780633bcf7ec1116103205780633bcf7ec1146105df5780634428e8621461060d5780634ada90af146106475780634e1647fb14610661576103af565b80632a6a60651461054e5780632b9553ce1461056d5780632d70db78146105a3578063317b0b77146105c2576103af565b80631637eefd1161038d5780631637eefd146104b857806318c882a5146104f457806324a3d622146105225780632630c12f14610546576103af565b8063061682de146103b4578063075aff36146103fc5780630d7f67a214610472575b600080fd5b6103fa600480360360a08110156103ca57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135610e02565b005b6104226004803603602081101561041257600080fd5b50356001600160a01b0316610fc5565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561045e578181015183820152602001610446565b505050509050019250505060405180910390f35b6103fa600480360360a081101561048857600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135909116906080013561107e565b6103fa600480360360808110156104ce57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611085565b6103fa6004803603604081101561050a57600080fd5b506001600160a01b038135169060200135151561116c565b61052a6111f1565b604080516001600160a01b039092168252519081900360200190f35b61052a611200565b6103fa6004803603602081101561056457600080fd5b5035151561120f565b6103fa6004803603606081101561058357600080fd5b506001600160a01b038135811691602081013590911690604001356112d0565b6103fa600480360360208110156105b957600080fd5b503515156115dd565b6103fa600480360360208110156105d857600080fd5b5035611657565b6103fa600480360360408110156105f557600080fd5b506001600160a01b0381351690602001351515611753565b6106336004803603602081101561062357600080fd5b50356001600160a01b03166117d3565b604080519115158252519081900360200190f35b61064f6117e6565b60408051918252519081900360200190f35b6106336117ec565b6103fa6004803603602081101561067f57600080fd5b50356117f1565b6103fa6004803603602081101561069c57600080fd5b50356001600160a01b03166118f7565b6103fa600480360360208110156106c257600080fd5b50356001600160a01b0316611a20565b6103fa600480360360208110156106e857600080fd5b50356001600160a01b0316611b3a565b6103fa600480360360c081101561070e57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135611c6a565b610422611c72565b6103fa6004803603602081101561076257600080fd5b50356001600160a01b0316611d0e565b6103fa6004803603604081101561078857600080fd5b506001600160a01b0381351690602001351515611e0f565b6103fa600480360360808110156107b657600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611e8f565b6103fa61202e565b610633600480360360408110156107fa57600080fd5b506001600160a01b0381358116916020013516612087565b6103fa6004803603606081101561082857600080fd5b506001600160a01b038135811691602081013590911690604001356120b3565b6104226004803603602081101561085e57600080fd5b50356001600160a01b0316612352565b61052a6123fd565b61089c6004803603602081101561088c57600080fd5b50356001600160a01b0316612411565b60408051978852602088019690965286860194909452606086019290925215156080850152151560a0840152151560c0830152519081900360e00190f35b6103fa600480360360208110156108f057600080fd5b50351515612456565b6103fa6004803603604081101561090f57600080fd5b506001600160a01b0381351690602001356124cc565b61094b6004803603602081101561093b57600080fd5b50356001600160a01b03166126a5565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6103fa6004803603608081101561098757600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356112ca565b6103fa600480360360608110156109c357600080fd5b506001600160a01b038135811691602081013590911690604001356126c8565b6106336127ba565b61052a6127ca565b6103fa60048036036060811015610a0957600080fd5b506001600160a01b038135811691602081013590911690604001356127d9565b6103fa60048036036040811015610a3f57600080fd5b506001600160a01b03813516906020013561291e565b61042260048036036020811015610a6b57600080fd5b810190602081018135640100000000811115610a8657600080fd5b820183602082011115610a9857600080fd5b80359060200191846020830284011164010000000083111715610aba57600080fd5b5090925090506129e2565b61064f60048036036060811015610adb57600080fd5b506001600160a01b03813581169160208101359091169060400135612a85565b6103fa60048036036060811015610b1157600080fd5b506001600160a01b038135811691602081013590911690604001356111ec565b6103fa600480360360a0811015610b4757600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135612c6f565b61042260048036036020811015610b8d57600080fd5b810190602081018135640100000000811115610ba857600080fd5b820183602082011115610bba57600080fd5b80359060200191846020830284011164010000000083111715610bdc57600080fd5b509092509050612f83565b61063360048036036040811015610bfd57600080fd5b506001600160a01b038135811691602001351661301e565b6103fa60048036036040811015610c2b57600080fd5b506001600160a01b038135169060200135613040565b6103fa600480360360c0811015610c5757600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a00135613104565b6103fa60048036036040811015610c9b57600080fd5b506001600160a01b038135811691602001351661366e565b6103fa60048036036020811015610cc957600080fd5b503515156136bc565b6103fa60048036036020811015610ce857600080fd5b5035151561375e565b61052a613800565b6103fa60048036036080811015610d0f57600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356112ca565b6103fa60048036036040811015610d4b57600080fd5b506001600160a01b03813516906020013561380f565b6103fa60048036036020811015610d7757600080fd5b503515156139db565b61064f613a7d565b6103fa60048036036080811015610d9e57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135613a83565b6103fa60048036036040811015610dda57600080fd5b506001600160a01b0381351690602001351515613b68565b610633613be8565b6103fa613bf8565b610e0d603486613cef565b8015610e1f5750610e1f603485613cef565b610e70576040805162461bcd60e51b815260206004820152601b60248201527f546f6b656e732068617665206e6f74206265656e206c69737465640000000000604482015290519081900360640190fd5b6000610e7b836126a5565b505091505060008111610ed5576040805162461bcd60e51b815260206004820152601f60248201527f4163636f756e7420646f6573206e6f7420686176652073686f727466616c6c00604482015290519081900360640190fd5b6000866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610f2457600080fd5b505afa158015610f38573d6000803e3d6000fd5b505050506040513d6020811015610f4e57600080fd5b5051603954909150600090610f64908390613d04565b905080841115610fbb576040805162461bcd60e51b815260206004820152601f60248201527f52657061792065786365656473206d617820726570617920616c6c6f77656400604482015290519081900360640190fd5b5050505050505050565b6001600160a01b0381166000908152603760205260408120606091610fec60028301613d1c565b90508067ffffffffffffffff8111801561100557600080fd5b5060405190808252806020026020018201604052801561102f578160200160208202803683370190505b50925060005b818110156110765761104a6002840182613d27565b84828151811061105657fe5b6001600160a01b0390921660209283029190910190910152600101611035565b505050919050565b5050505050565b61108e84613d33565b603c5460408051636576717f60e11b81526001600160a01b038781166004830152600160248301529151919092169163caece2fe91604480830192600092919082900301818387803b1580156110e357600080fd5b505af11580156110f7573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b0389811660048301528781166024830152600160448301529151919092169350637d3572fd9250606480830192600092919082900301818387803b15801561115857600080fd5b505af1158015610fbb573d6000803e3d6000fd5b600054819061010090046001600160a01b031633148061119e5750603b546001600160a01b03163314801561119e5750805b6111d95760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b6111e283613d33565b6111ec8383613d92565b505050565b603b546001600160a01b031681565b6038546001600160a01b031681565b600054819061010090046001600160a01b03163314806112415750603b546001600160a01b0316331480156112415750805b61127c5760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b6034600061128982613d1c565b905060005b818110156112b75760006112a28483613d27565b90506112ae8187613e03565b5060010161128e565b506112c184613f30565b6112ca84613f83565b50505050565b6112d983613d33565b6001600160a01b0383166000908152603660205260409020600481015462010000900460ff1615611351576040805162461bcd60e51b815260206004820152601c60248201527f546f6b656e20626f72726f7720686173206265656e2070617573656400000000604482015290519081900360640190fd5b61135b8385612087565b6113be57336001600160a01b038516146113b4576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba1031329034aa37b5b2b760591b604482015290519081900360640190fd5b6113be8385613fd6565b60006113cd8486600086614049565b505091505080600014611427576040805162461bcd60e51b815260206004820152601a60248201527f4163636f756e742068617320736f6d652073686f727466616c6c000000000000604482015290519081900360640190fd5b6000856001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b15801561146257600080fd5b505afa158015611476573d6000803e3d6000fd5b505050506040513d602081101561148c57600080fd5b505160028401549091506114a08286614507565b11156114f3576040805162461bcd60e51b815260206004820152601d60248201527f546f6b656e20626f72726f772063617061636974792072656163686564000000604482015290519081900360640190fd5b603c5460408051636576717f60e11b81526001600160a01b038981166004830152600160248301529151919092169163caece2fe91604480830192600092919082900301818387803b15801561154857600080fd5b505af115801561155c573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b038b811660048301528a81166024830152600160448301529151919092169350637d3572fd9250606480830192600092919082900301818387803b1580156115bd57600080fd5b505af11580156115d1573d6000803e3d6000fd5b50505050505050505050565b600054819061010090046001600160a01b031633148061160f5750603b546001600160a01b03163314801561160f5750805b61164a5760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b61165382613f83565b5050565b60005461010090046001600160a01b031633146116a55760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b66b1a2bc2ec5000081101580156116c45750670c7d713b49da00008111155b61170c576040805162461bcd60e51b815260206004820152601460248201527310db1bdcd948199858dd1bdc881a5b9d985b1a5960621b604482015290519081900360640190fd5b6039805490829055604080518281526020810184905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a15050565b600054819061010090046001600160a01b03163314806117855750603b546001600160a01b0316331480156117855750805b6117c05760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b6117c983613d33565b6111ec8383614561565b60006117e0603483613cef565b92915050565b603a5481565b600190565b60005461010090046001600160a01b0316331461183f5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b670de0b6b3a7640000811015801561185f57506714d1120d7b1600008111155b6118b0576040805162461bcd60e51b815260206004820152601d60248201527f4c69717569646174696f6e20696e63656e7469766520696e76616c6964000000604482015290519081900360640190fd5b603a805490829055604080518281526020810184905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a15050565b60005461010090046001600160a01b031633146119455760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b6038546001600160a01b03908116908216158015906119765750806001600160a01b0316826001600160a01b031614155b6119c0576040805162461bcd60e51b815260206004820152601660248201527513dc9858db19481859191c995cdcc81a5b9d985b1a5960521b604482015290519081900360640190fd5b603880546001600160a01b0319166001600160a01b03848116918217909255604080519284168352602083019190915280517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e229281900390910190a15050565b60005461010090046001600160a01b03163314611a6e5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b603c546001600160a01b0390811690821615801590611a9f5750806001600160a01b0316826001600160a01b031614155b611ada5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f516022913960400191505060405180910390fd5b603c80546001600160a01b0319166001600160a01b03848116918217909255604080519284168352602083019190915280517f8ddca872a7a62d68235cff1a03badc845dc3007cfaa6145379f7bf3452ecb9b99281900390910190a15050565b60005461010090046001600160a01b03163314611b885760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b603b546001600160a01b0390811690821615801590611bb95750806001600160a01b0316826001600160a01b031614155b611c0a576040805162461bcd60e51b815260206004820152601e60248201527f506175736520677561726469616e206164647265737320696e76616c69640000604482015290519081900360640190fd5b603b80546001600160a01b0319166001600160a01b03848116918217909255604080519284168352602083019190915280517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e9281900390910190a15050565b505050505050565b606060346000611c8182613d1c565b90508067ffffffffffffffff81118015611c9a57600080fd5b50604051908082528060200260200182016040528015611cc4578160200160208202803683370190505b50925060005b81811015611d0857611cdc8382613d27565b848281518110611ce857fe5b6001600160a01b0390921660209283029190910190910152600101611cca565b50505090565b60005461010090046001600160a01b03163314611d5c5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b6001600160a01b03811615801590611d8257506001546001600160a01b03828116911614155b611dbd5760405162461bcd60e51b815260040180806020018281038252604b815260200180614dc7604b913960600191505060405180910390fd5b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b90600090a35050565b600054819061010090046001600160a01b0316331480611e415750603b546001600160a01b031633148015611e415750805b611e7c5760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b611e8583613d33565b6111ec83836145c8565b603b54600160a01b900460ff1615611eee576040805162461bcd60e51b815260206004820152601860248201527f5472616e7366657220686173206265656e207061757365640000000000000000604482015290519081900360640190fd5b611ef9848483614637565b603c5460408051636576717f60e11b81526001600160a01b038781166004830152600060248301819052925193169263caece2fe9260448084019391929182900301818387803b158015611f4c57600080fd5b505af1158015611f60573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b0389811660048301528881166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b158015611fbd57600080fd5b505af1158015611fd1573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b0389811660048301528781166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b15801561115857600080fd5b60005460ff16156120705760405162461bcd60e51b815260040180806020018281038252602e815260200180614e77602e913960400191505060405180910390fd5b6120786146d4565b6000805460ff19166001179055565b6001600160a01b03821660009081526037602052604081206120ac9060020183613cef565b9392505050565b6120bc83613d33565b6001600160a01b0383166000908152603660205260409020600481015460ff161561212e576040805162461bcd60e51b815260206004820152601a60248201527f546f6b656e206d696e7420686173206265656e20706175736564000000000000604482015290519081900360640190fd5b600061220a856001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561216c57600080fd5b505afa158015612180573d6000803e3d6000fd5b505050506040513d602081101561219657600080fd5b5051604080516318160ddd60e01b815290516001600160a01b038916916318160ddd916004808301926020929190829003018186803b1580156121d857600080fd5b505afa1580156121ec573d6000803e3d6000fd5b505050506040513d602081101561220257600080fd5b505190613d04565b600383015490915061221c8285614507565b111561226f576040805162461bcd60e51b815260206004820152601d60248201527f546f6b656e20737570706c792063617061636974792072656163686564000000604482015290519081900360640190fd5b603c5460408051636576717f60e11b81526001600160a01b038881166004830152600060248301819052925193169263caece2fe9260448084019391929182900301818387803b1580156122c257600080fd5b505af11580156122d6573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b038a811660048301528981166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b15801561233357600080fd5b505af1158015612347573d6000803e3d6000fd5b505050505050505050565b6001600160a01b038116600090815260376020526040812060609161237682613d1c565b90508067ffffffffffffffff8111801561238f57600080fd5b506040519080825280602002602001820160405280156123b9578160200160208202803683370190505b50925060005b81811015611076576123d18382613d27565b8482815181106123dd57fe5b6001600160a01b03909216602092830291909101909101526001016123bf565b60005461010090046001600160a01b031681565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919060ff808216916101008104821691620100009091041687565b600054819061010090046001600160a01b03163314806124885750603b546001600160a01b0316331480156124885750805b6124c35760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b61165382613f30565b60005461010090046001600160a01b0316331461251a5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b61252382613d33565b60008111801561253b5750670de0b6b3a76400008111155b612584576040805162461bcd60e51b8152602060048201526015602482015274109bdc9c9bddc8199858dd1bdc881a5b9d985b1a59605a1b604482015290519081900360640190fd5b6038546040805163fc57d4df60e01b81526001600160a01b0385811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b1580156125d157600080fd5b505afa1580156125e5573d6000803e3d6000fd5b505050506040513d60208110156125fb57600080fd5b50516126385760405162461bcd60e51b815260040180806020018281038252603c815260200180614ec6603c913960400191505060405180910390fd5b6001600160a01b0382166000818152603660209081526040918290206001810180549086905583519485529184018290528383018590529151919290917fd69d3c48186e96a0af0545cf26e970b49ed3e29a306a37118a5a787bae6b90be9181900360600190a150505050565b6000806000806126b9856000806000614049565b93509350935093509193509193565b6001600160a01b03831660009081526036602052604090206004015462010000900460ff161561273f576040805162461bcd60e51b815260206004820152601c60248201527f546f6b656e20626f72726f7720686173206265656e2070617573656400000000604482015290519081900360640190fd5b61274883613d33565b603c5460408051636576717f60e11b81526001600160a01b038681166004830152600160248301529151919092169163caece2fe91604480830192600092919082900301818387803b15801561279d57600080fd5b505af11580156127b1573d6000803e3d6000fd5b50505050505050565b603b54600160a81b900460ff1681565b603c546001600160a01b031681565b6001600160a01b038316600090815260366020526040902060040154610100900460ff161561284f576040805162461bcd60e51b815260206004820152601c60248201527f546f6b656e2072656465656d20686173206265656e2070617573656400000000604482015290519081900360640190fd5b61285a838383614637565b603c5460408051636576717f60e11b81526001600160a01b038681166004830152600060248301819052925193169263caece2fe9260448084019391929182900301818387803b1580156128ad57600080fd5b505af11580156128c1573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b0388811660048301528781166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b15801561279d57600080fd5b60005461010090046001600160a01b0316331461296c5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b61297582613d33565b6001600160a01b0382166000818152603660209081526040918290206002810180549086905583519485529184018290528383018590529151919290917f6c07964980a680dc12652ccab077a57c65740bf2ebc204a7670438051ee6fa5b9181900360600190a150505050565b6060818067ffffffffffffffff811180156129fc57600080fd5b50604051908082528060200260200182016040528015612a26578160200160208202803683370190505b50915060005b81811015612a7d57612a59858583818110612a4357fe5b905060200201356001600160a01b03163361471c565b838281518110612a6557fe5b91151560209283029190910190910152600101612a2c565b505092915050565b6038546040805163fc57d4df60e01b81526001600160a01b03868116600483015291516000938493169163fc57d4df916024808301926020929190829003018186803b158015612ad457600080fd5b505afa158015612ae8573d6000803e3d6000fd5b505050506040513d6020811015612afe57600080fd5b50516038546040805163fc57d4df60e01b81526001600160a01b0388811660048301529151939450600093919092169163fc57d4df916024808301926020929190829003018186803b158015612b5357600080fd5b505afa158015612b67573d6000803e3d6000fd5b505050506040513d6020811015612b7d57600080fd5b505190508115801590612b8f57508015155b612bca5760405162461bcd60e51b815260040180806020018281038252602d815260200180614f24602d913960400191505060405180910390fd5b603a54600090612be490612bde87866147ab565b90613d04565b90506000866001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b158015612c2157600080fd5b505afa158015612c35573d6000803e3d6000fd5b505050506040513d6020811015612c4b57600080fd5b50519050612c6383612c5d8484614804565b9061481c565b98975050505050505050565b603b54600160a81b900460ff1615612cc6576040805162461bcd60e51b815260206004820152601560248201527414d95a5e99481a185cc81899595b881c185d5cd959605a1b604482015290519081900360640190fd5b612cd1603485613cef565b8015612ce35750612ce3603486613cef565b612d34576040805162461bcd60e51b815260206004820152601b60248201527f546f6b656e732068617665206e6f74206265656e206c69737465640000000000604482015290519081900360640190fd5b846001600160a01b031663f77c47916040518163ffffffff1660e01b815260040160206040518083038186803b158015612d6d57600080fd5b505afa158015612d81573d6000803e3d6000fd5b505050506040513d6020811015612d9757600080fd5b50516040805163f77c479160e01b815290516001600160a01b039283169287169163f77c4791916004808301926020929190829003018186803b158015612ddd57600080fd5b505afa158015612df1573d6000803e3d6000fd5b505050506040513d6020811015612e0757600080fd5b50516001600160a01b031614612e4e5760405162461bcd60e51b8152600401808060200182810382526033815260200180614d726033913960400191505060405180910390fd5b603c5460408051636576717f60e11b81526001600160a01b038881166004830152600060248301819052925193169263caece2fe9260448084019391929182900301818387803b158015612ea157600080fd5b505af1158015612eb5573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b038a811660048301528881166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b158015612f1257600080fd5b505af1158015612f26573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b038a811660048301528781166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b15801561233357600080fd5b6060818067ffffffffffffffff81118015612f9d57600080fd5b50604051908082528060200260200182016040528015612fc7578160200160208202803683370190505b50915060005b81811015612a7d57612ffa858583818110612fe457fe5b905060200201356001600160a01b03163361485e565b83828151811061300657fe5b91151560209283029190910190910152600101612fcd565b6001600160a01b03821660009081526037602052604081206120ac9083613cef565b60005461010090046001600160a01b0316331461308e5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b61309782613d33565b6001600160a01b0382166000818152603660209081526040918290206003810180549086905583519485529184018290528383018590529151919290917f6ffc41eacf6bc473fab68880680a35214210358ff10d45c53cee339f1547f0bb9181900360600190a150505050565b60005461010090046001600160a01b031633146131525760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b856001600160a01b031663744279376040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561318d57600080fd5b505af11580156131a1573d6000803e3d6000fd5b505050506040513d60208110156131b757600080fd5b5051613203576040805162461bcd60e51b8152602060048201526016602482015275151bdad95b881a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b306001600160a01b0316866001600160a01b031663f77c47916040518163ffffffff1660e01b815260040160206040518083038186803b15801561324657600080fd5b505afa15801561325a573d6000803e3d6000fd5b505050506040513d602081101561327057600080fd5b50516001600160a01b0316146132b75760405162461bcd60e51b8152600401808060200182810382526022815260200180614da56022913960400191505060405180910390fd5b6132c260348761499f565b613313576040805162461bcd60e51b815260206004820152601d60248201527f546f6b656e2068617320616c7265616479206265656e206c6973746564000000604482015290519081900360640190fd5b670de0b6b3a764000085111561336c576040805162461bcd60e51b815260206004820152601960248201527810dbdb1b185d195c985b08199858dd1bdc881a5b9d985b1a59603a1b604482015290519081900360640190fd5b6000841180156133845750670de0b6b3a76400008411155b6133cd576040805162461bcd60e51b8152602060048201526015602482015274109bdc9c9bddc8199858dd1bdc881a5b9d985b1a59605a1b604482015290519081900360640190fd5b6038546040805163fc57d4df60e01b81526001600160a01b0389811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561341a57600080fd5b505afa15801561342e573d6000803e3d6000fd5b505050506040513d602081101561344457600080fd5b5051613497576040805162461bcd60e51b815260206004820152601f60248201527f556e6465726c79696e6720707269636520697320756e617661696c61626c6500604482015290519081900360640190fd5b6040518060e001604052808681526020018581526020018381526020018481526020016000151581526020016000151581526020016000151581525060366000886001600160a01b03166001600160a01b031681526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a81548160ff02191690831515021790555060a08201518160040160016101000a81548160ff02191690831515021790555060c08201518160040160026101000a81548160ff021916908315150217905550905050603c60009054906101000a90046001600160a01b03166001600160a01b0316635658fec387836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156135ef57600080fd5b505af1158015613603573d6000803e3d6000fd5b5050604080516001600160a01b038a16815260208101899052808201889052606081018790526080810186905260a0810185905290517f96f15e56d27d14b82ed736fd9387871d60f721cd59f324699722b4f0d11ee1b193509081900360c0019150a1505050505050565b61367733613d33565b613681828261471c565b6116535760405162461bcd60e51b8152600401808060200182810382526036815260200180614fd86036913960400191505060405180910390fd5b600054819061010090046001600160a01b03163314806136ee5750603b546001600160a01b0316331480156136ee5750805b6137295760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b6034600061373682613d1c565b905060005b8181101561107e576137566137508483613d27565b86614561565b60010161373b565b600054819061010090046001600160a01b03163314806137905750603b546001600160a01b0316331480156137905750805b6137cb5760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b603460006137d882613d1c565b905060005b8181101561107e576137f86137f28483613d27565b866145c8565b6001016137dd565b6001546001600160a01b031681565b60005461010090046001600160a01b0316331461385d5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b61386682613d33565b670de0b6b3a76400008111156138bf576040805162461bcd60e51b815260206004820152601960248201527810dbdb1b185d195c985b08199858dd1bdc881a5b9d985b1a59603a1b604482015290519081900360640190fd5b6038546040805163fc57d4df60e01b81526001600160a01b0385811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561390c57600080fd5b505afa158015613920573d6000803e3d6000fd5b505050506040513d602081101561393657600080fd5b50516139735760405162461bcd60e51b8152600401808060200182810382526040815260200180614f736040913960400191505060405180910390fd5b6001600160a01b038216600081815260366020908152604091829020805485825583519485529184018290528383018590529151919290917f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59181900360600190a150505050565b600054819061010090046001600160a01b0316331480613a0d5750603b546001600160a01b031633148015613a0d5750805b613a485760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b60346000613a5582613d1c565b905060005b8181101561107e57613a75613a6f8483613d27565b86613d92565b600101613a5a565b60395481565b613a8c84613d33565b836001600160a01b03166395dd9193836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613ad957600080fd5b505afa158015613aed573d6000803e3d6000fd5b505050506040513d6020811015613b0357600080fd5b50516112ca57336001600160a01b03851614613b5e576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba1031329034aa37b5b2b760591b604482015290519081900360640190fd5b6112ca82856149b4565b600054819061010090046001600160a01b0316331480613b9a5750603b546001600160a01b031633148015613b9a5750805b613bd55760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b613bde83613d33565b6111ec8383613e03565b603b54600160a01b900460ff1681565b6001546001600160a01b03163314613c415760405162461bcd60e51b8152600401808060200182810382526025815260200180614fb36025913960400191505060405180910390fd5b60008054600180546001600160a01b03818116610100818102610100600160a81b03198716178088556001600160a01b031990941690945560405194849004821695909493909204169184917f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236491a36001546040516001600160a01b03918216918316907fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b90600090a35050565b60006120ac836001600160a01b038416614a27565b60006120ac670de0b6b3a7640000612c5d85856147ab565b60006117e082614a3f565b60006120ac8383614a43565b613d3e603482613cef565b613d8f576040805162461bcd60e51b815260206004820152601960248201527f546f6b656e20686173206e6f74206265656e206c697374656400000000000000604482015290519081900360640190fd5b50565b6001600160a01b038216600081815260366020908152604091829020600401805462ff00001916620100008615159081029190911790915582519384529083015280517fa501bd5ac3de9924ce0c13576750267130fd835780f1ec6e1ae9fb13ee7465039281900390910190a15050565b6001600160a01b03821660008181526036602090815260409182902060048101805460ff1916861515908117909155835194855291840191909152815190927f48cff1fdfe035051f817c77855362a92f96f941342d41008f2d596f530c4e96b92908290030190a160048101805461ff00191661010084151590810291909117909155604080516001600160a01b0386168152602081019290925280517f3d95d87adcb06de16ac0e322ea97a06e30967fedcc83a6d1d0b9fda60300801a9281900390910190a160048101805462ff000019166201000084151590810291909117909155604080516001600160a01b0386168152602081019290925280517fa501bd5ac3de9924ce0c13576750267130fd835780f1ec6e1ae9fb13ee7465039281900390910190a1505050565b603b8054821515600160a01b810260ff60a01b199092169190911790915560408051918252517f7b92c580e5b53e34f85950f4117143b86c4031ca9568a3cd30f4b3cd5bb95dc89181900360200190a150565b603b8054821515600160a81b810260ff60a81b199092169190911790915560408051918252517fcaf79886b466b41f609cc39fdc375ab5484cc3811570b7faa22fcb2b55516fdf9181900360200190a150565b6001600160a01b0382166000908152603760205260409020613ffb906002018261499f565b1561165357604080516001600160a01b0380841682528416602082015281517f61400a0050615e96f6a4a234e4fc162ab71775345f32f4641cd884601603a455929181900390910190a15050565b600080600080614057614d0a565b6001600160a01b03891660009081526037602052604081209061407982613d1c565b905060005b818110156142cb5760006140928483613d27565b9050806001600160a01b03166370a082318e6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156140e157600080fd5b505afa1580156140f5573d6000803e3d6000fd5b505050506040513d602081101561410b57600080fd5b5051604080870191909152805163182df0f560e01b815290516001600160a01b0383169163182df0f5916004808301926020929190829003018186803b15801561415457600080fd5b505afa158015614168573d6000803e3d6000fd5b505050506040513d602081101561417e57600080fd5b505160808601526001600160a01b038c81169082161480156141a0575060008b115b156141ba5760408501516141b4908c614aa7565b60408601525b6038546040805163fc57d4df60e01b81526001600160a01b0384811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561420757600080fd5b505afa15801561421b573d6000803e3d6000fd5b505050506040513d602081101561423157600080fd5b505160a086018190526142755760405162461bcd60e51b8152600401808060200182810382526029815260200180614e126029913960400191505060405180910390fd5b6001600160a01b0381166000908152603660205260409081902054608087015160a0880151928801516142ae93612bde929183916147ab565b60c0860181905285516142c091614507565b85525060010161407e565b506142d882600201613d1c565b905060005b818110156144c25760006142f46002850183613d27565b9050806001600160a01b03166395dd91938e6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561434357600080fd5b505afa158015614357573d6000803e3d6000fd5b505050506040513d602081101561436d57600080fd5b505160608601526001600160a01b038c811690821614801561438f575060008a115b156143a95760608501516143a3908b614507565b60608601525b6038546040805163fc57d4df60e01b81526001600160a01b0384811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b1580156143f657600080fd5b505afa15801561440a573d6000803e3d6000fd5b505050506040513d602081101561442057600080fd5b505160a086018190526144645760405162461bcd60e51b8152600401808060200182810382526029815260200180614e126029913960400191505060405180910390fd5b6001600160a01b03811660009081526036602052604090206001015460a0860151606087015161449f929161449991906147ab565b90614804565b60e0860181905260208601516144b491614507565b6020860152506001016142dd565b5060208301518351116144e25782516020840151600091808203916144f2565b6020830151835181810391600091905b929e919d509b50909950975050505050505050565b6000828201838110156120ac576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038216600081815260366020908152604091829020600401805460ff191685151590811790915582519384529083015280517f48cff1fdfe035051f817c77855362a92f96f941342d41008f2d596f530c4e96b9281900390910190a15050565b6001600160a01b038216600081815260366020908152604091829020600401805461ff0019166101008615159081029190911790915582519384529083015280517f3d95d87adcb06de16ac0e322ea97a06e30967fedcc83a6d1d0b9fda60300801a9281900390910190a15050565b61464083613d33565b6001600160a01b03821660009081526037602052604090206146629084613cef565b61466b576111ec565b600061467a8385846000614049565b5050915050806000146112ca576040805162461bcd60e51b815260206004820152601a60248201527f4163636f756e742068617320736f6d652073686f727466616c6c000000000000604482015290519081900360640190fd5b60008054610100600160a81b0319163361010081029190911782556040519091907f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b2364908290a3565b6000614729603484613cef565b614735575060006117e0565b6001600160a01b0382166000908152603760205260409020614757908461499f565b156147a257604080516001600160a01b0380861682528416602082015281517f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a5929181900390910190a15b50600192915050565b6000826147ba575060006117e0565b828202828482816147c757fe5b04146120ac5760405162461bcd60e51b8152600401808060200182810382526021815260200180614ea56021913960400191505060405180910390fd5b60006120ac82612c5d85670de0b6b3a76400006147ab565b60006120ac83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614ae9565b600061486b603484613cef565b614877575060016117e0565b6001600160a01b03821660009081526037602052604090206148999084613cef565b6148a5575060016117e0565b6000836001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156148f457600080fd5b505afa158015614908573d6000803e3d6000fd5b505050506040513d602081101561491e57600080fd5b5051905061492d848483614637565b6001600160a01b038316600090815260376020526040902061494f9085614b8b565b50604080516001600160a01b0380871682528516602082015281517fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d929181900390910190a15060019392505050565b60006120ac836001600160a01b038416614ba0565b6001600160a01b03821660009081526037602052604090206149d99060020182614b8b565b1561165357604080516001600160a01b0380841682528416602082015281517f6df0340c4ae9990f4b8f3c3e0e5408dcf6ba2c086b92966dfdbbef1f2f052e1a929181900390910190a15050565b60009081526001919091016020526040902054151590565b5490565b81546000908210614a855760405162461bcd60e51b8152600401808060200182810382526022815260200180614d506022913960400191505060405180910390fd5b826000018281548110614a9457fe5b9060005260206000200154905092915050565b60006120ac83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614bea565b60008183614b755760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614b3a578181015183820152602001614b22565b50505050905090810190601f168015614b675780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614b8157fe5b0495945050505050565b60006120ac836001600160a01b038416614c44565b6000614bac8383614a27565b614be2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556117e0565b5060006117e0565b60008184841115614c3c5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614b3a578181015183820152602001614b22565b505050900390565b60008181526001830160205260408120548015614d005783546000198083019190810190600090879083908110614c7757fe5b9060005260206000200154905080876000018481548110614c9457fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080614cc457fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506117e0565b60009150506117e0565b6040518061010001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473436f6e74726f6c6c6572206d69736d61746368206265747765656e20426f72726f77656420616e6420436f6c6c61746572616c546f6b656e277320636f6e74726f6c6c6572206973206e6f742074686973206f6e655f73657450656e64696e674f776e65723a204e6577206f77656e722063616e206e6f74206265207a65726f206164647265737320616e64206f776e657220686173206265656e2073657421496e76616c696420707269636520746f2063616c63756c617465206163636f756e74206571756974794f6e6c79206f776e657220616e6420677561726469616e2063616e20706175736520616e64206f6e6c79206f776e65722063616e20756e7061757365496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774661696c656420746f2073657420626f72726f7720666163746f722c20756e6465726c79696e6720707269636520697320756e617661696c61626c656f6e6c794f776e65723a2063616c6c6572206973206e6f7420746865206f776e6572426f72726f776564206f7220436f6c6c61746572616c20617373657420707269636520697320696e76616c6964526577617264204469737472696275746f72206164647265737320696e76616c69644661696c656420746f2073657420636f6c6c61746572616c20666163746f722c20756e6465726c79696e6720707269636520697320756e617661696c61626c655f6163636570744f776e65723a204f6e6c7920666f722070656e64696e67206f776e657221656e7465724d61726b657446726f6d69546f6b656e3a204f6e6c792063616e20656e7465722061206c6973746564206d61726b657421a264697066735822122046829991b6c7bdf4634ad370538181df4ac87fe1a3f85eb848ae3e07e35b998a64736f6c634300060c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103af5760003560e01c80638ebf6364116101f4578063d5b443601161011a578063e4028eee116100ad578063f079420a1161007c578063f079420a14610d88578063f1575f0814610dc4578063fb2cb34e14610df2578063fc4d33f914610dfa576103af565b8063e4028eee14610d35578063e715d96a14610d61578063e875544614610d80578063efced38514610afb576103af565b8063de65f41b116100e9578063de65f41b14610971578063e29f7f5e14610cd2578063e30c397814610cf1578063e33af48a14610cf9576103af565b8063d5b4436014610c15578063d79287d714610c41578063d8f5a57214610c85578063dbb32d6814610cb3576103af565b8063af505ad911610192578063ca498ad611610161578063ca498ad614610afb578063cb6db19c14610b31578063d0af413814610b77578063d4d4847314610be7576103af565b8063af505ad9146109f3578063bd8296c214610a29578063c299823814610a55578063c488847b14610ac5576103af565b8063a2ddeb85116101ce578063a2ddeb8514610971578063a8f4e9f6146109ad578063ab1777d2146109e3578063acc2166a146109eb576103af565b80638ebf6364146108da5780639d8cc5c4146108f9578063a09cf78b14610925576103af565b80634fd42e17116102d95780637160a8701161027757806386b841871161024657806386b84187146108125780638ccb720b146108485780638da5cb5b1461086e5780638e8f294b14610876576103af565b80637160a8701461077257806372b4304a146107a05780638129fc1c146107dc5780638283e3e2146107e4576103af565b80635f5af1aa116102b35780635f5af1aa146106d25780635f7bc006146106f857806360a8a931146107445780636e96dfd71461074c576103af565b80634fd42e171461066957806355ee1fe1146106865780635c254d11146106ac576103af565b80632a6a6065116103515780633bcf7ec1116103205780633bcf7ec1146105df5780634428e8621461060d5780634ada90af146106475780634e1647fb14610661576103af565b80632a6a60651461054e5780632b9553ce1461056d5780632d70db78146105a3578063317b0b77146105c2576103af565b80631637eefd1161038d5780631637eefd146104b857806318c882a5146104f457806324a3d622146105225780632630c12f14610546576103af565b8063061682de146103b4578063075aff36146103fc5780630d7f67a214610472575b600080fd5b6103fa600480360360a08110156103ca57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135610e02565b005b6104226004803603602081101561041257600080fd5b50356001600160a01b0316610fc5565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561045e578181015183820152602001610446565b505050509050019250505060405180910390f35b6103fa600480360360a081101561048857600080fd5b506001600160a01b038135811691602081013582169160408201358116916060810135909116906080013561107e565b6103fa600480360360808110156104ce57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611085565b6103fa6004803603604081101561050a57600080fd5b506001600160a01b038135169060200135151561116c565b61052a6111f1565b604080516001600160a01b039092168252519081900360200190f35b61052a611200565b6103fa6004803603602081101561056457600080fd5b5035151561120f565b6103fa6004803603606081101561058357600080fd5b506001600160a01b038135811691602081013590911690604001356112d0565b6103fa600480360360208110156105b957600080fd5b503515156115dd565b6103fa600480360360208110156105d857600080fd5b5035611657565b6103fa600480360360408110156105f557600080fd5b506001600160a01b0381351690602001351515611753565b6106336004803603602081101561062357600080fd5b50356001600160a01b03166117d3565b604080519115158252519081900360200190f35b61064f6117e6565b60408051918252519081900360200190f35b6106336117ec565b6103fa6004803603602081101561067f57600080fd5b50356117f1565b6103fa6004803603602081101561069c57600080fd5b50356001600160a01b03166118f7565b6103fa600480360360208110156106c257600080fd5b50356001600160a01b0316611a20565b6103fa600480360360208110156106e857600080fd5b50356001600160a01b0316611b3a565b6103fa600480360360c081101561070e57600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060808101359060a00135611c6a565b610422611c72565b6103fa6004803603602081101561076257600080fd5b50356001600160a01b0316611d0e565b6103fa6004803603604081101561078857600080fd5b506001600160a01b0381351690602001351515611e0f565b6103fa600480360360808110156107b657600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135611e8f565b6103fa61202e565b610633600480360360408110156107fa57600080fd5b506001600160a01b0381358116916020013516612087565b6103fa6004803603606081101561082857600080fd5b506001600160a01b038135811691602081013590911690604001356120b3565b6104226004803603602081101561085e57600080fd5b50356001600160a01b0316612352565b61052a6123fd565b61089c6004803603602081101561088c57600080fd5b50356001600160a01b0316612411565b60408051978852602088019690965286860194909452606086019290925215156080850152151560a0840152151560c0830152519081900360e00190f35b6103fa600480360360208110156108f057600080fd5b50351515612456565b6103fa6004803603604081101561090f57600080fd5b506001600160a01b0381351690602001356124cc565b61094b6004803603602081101561093b57600080fd5b50356001600160a01b03166126a5565b604080519485526020850193909352838301919091526060830152519081900360800190f35b6103fa6004803603608081101561098757600080fd5b506001600160a01b038135811691602081013590911690604081013590606001356112ca565b6103fa600480360360608110156109c357600080fd5b506001600160a01b038135811691602081013590911690604001356126c8565b6106336127ba565b61052a6127ca565b6103fa60048036036060811015610a0957600080fd5b506001600160a01b038135811691602081013590911690604001356127d9565b6103fa60048036036040811015610a3f57600080fd5b506001600160a01b03813516906020013561291e565b61042260048036036020811015610a6b57600080fd5b810190602081018135640100000000811115610a8657600080fd5b820183602082011115610a9857600080fd5b80359060200191846020830284011164010000000083111715610aba57600080fd5b5090925090506129e2565b61064f60048036036060811015610adb57600080fd5b506001600160a01b03813581169160208101359091169060400135612a85565b6103fa60048036036060811015610b1157600080fd5b506001600160a01b038135811691602081013590911690604001356111ec565b6103fa600480360360a0811015610b4757600080fd5b506001600160a01b0381358116916020810135821691604082013581169160608101359091169060800135612c6f565b61042260048036036020811015610b8d57600080fd5b810190602081018135640100000000811115610ba857600080fd5b820183602082011115610bba57600080fd5b80359060200191846020830284011164010000000083111715610bdc57600080fd5b509092509050612f83565b61063360048036036040811015610bfd57600080fd5b506001600160a01b038135811691602001351661301e565b6103fa60048036036040811015610c2b57600080fd5b506001600160a01b038135169060200135613040565b6103fa600480360360c0811015610c5757600080fd5b506001600160a01b038135169060208101359060408101359060608101359060808101359060a00135613104565b6103fa60048036036040811015610c9b57600080fd5b506001600160a01b038135811691602001351661366e565b6103fa60048036036020811015610cc957600080fd5b503515156136bc565b6103fa60048036036020811015610ce857600080fd5b5035151561375e565b61052a613800565b6103fa60048036036080811015610d0f57600080fd5b506001600160a01b038135811691602081013582169160408201351690606001356112ca565b6103fa60048036036040811015610d4b57600080fd5b506001600160a01b03813516906020013561380f565b6103fa60048036036020811015610d7757600080fd5b503515156139db565b61064f613a7d565b6103fa60048036036080811015610d9e57600080fd5b506001600160a01b03813581169160208101358216916040820135169060600135613a83565b6103fa60048036036040811015610dda57600080fd5b506001600160a01b0381351690602001351515613b68565b610633613be8565b6103fa613bf8565b610e0d603486613cef565b8015610e1f5750610e1f603485613cef565b610e70576040805162461bcd60e51b815260206004820152601b60248201527f546f6b656e732068617665206e6f74206265656e206c69737465640000000000604482015290519081900360640190fd5b6000610e7b836126a5565b505091505060008111610ed5576040805162461bcd60e51b815260206004820152601f60248201527f4163636f756e7420646f6573206e6f7420686176652073686f727466616c6c00604482015290519081900360640190fd5b6000866001600160a01b03166395dd9193856040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015610f2457600080fd5b505afa158015610f38573d6000803e3d6000fd5b505050506040513d6020811015610f4e57600080fd5b5051603954909150600090610f64908390613d04565b905080841115610fbb576040805162461bcd60e51b815260206004820152601f60248201527f52657061792065786365656473206d617820726570617920616c6c6f77656400604482015290519081900360640190fd5b5050505050505050565b6001600160a01b0381166000908152603760205260408120606091610fec60028301613d1c565b90508067ffffffffffffffff8111801561100557600080fd5b5060405190808252806020026020018201604052801561102f578160200160208202803683370190505b50925060005b818110156110765761104a6002840182613d27565b84828151811061105657fe5b6001600160a01b0390921660209283029190910190910152600101611035565b505050919050565b5050505050565b61108e84613d33565b603c5460408051636576717f60e11b81526001600160a01b038781166004830152600160248301529151919092169163caece2fe91604480830192600092919082900301818387803b1580156110e357600080fd5b505af11580156110f7573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b0389811660048301528781166024830152600160448301529151919092169350637d3572fd9250606480830192600092919082900301818387803b15801561115857600080fd5b505af1158015610fbb573d6000803e3d6000fd5b600054819061010090046001600160a01b031633148061119e5750603b546001600160a01b03163314801561119e5750805b6111d95760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b6111e283613d33565b6111ec8383613d92565b505050565b603b546001600160a01b031681565b6038546001600160a01b031681565b600054819061010090046001600160a01b03163314806112415750603b546001600160a01b0316331480156112415750805b61127c5760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b6034600061128982613d1c565b905060005b818110156112b75760006112a28483613d27565b90506112ae8187613e03565b5060010161128e565b506112c184613f30565b6112ca84613f83565b50505050565b6112d983613d33565b6001600160a01b0383166000908152603660205260409020600481015462010000900460ff1615611351576040805162461bcd60e51b815260206004820152601c60248201527f546f6b656e20626f72726f7720686173206265656e2070617573656400000000604482015290519081900360640190fd5b61135b8385612087565b6113be57336001600160a01b038516146113b4576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba1031329034aa37b5b2b760591b604482015290519081900360640190fd5b6113be8385613fd6565b60006113cd8486600086614049565b505091505080600014611427576040805162461bcd60e51b815260206004820152601a60248201527f4163636f756e742068617320736f6d652073686f727466616c6c000000000000604482015290519081900360640190fd5b6000856001600160a01b03166347bd37186040518163ffffffff1660e01b815260040160206040518083038186803b15801561146257600080fd5b505afa158015611476573d6000803e3d6000fd5b505050506040513d602081101561148c57600080fd5b505160028401549091506114a08286614507565b11156114f3576040805162461bcd60e51b815260206004820152601d60248201527f546f6b656e20626f72726f772063617061636974792072656163686564000000604482015290519081900360640190fd5b603c5460408051636576717f60e11b81526001600160a01b038981166004830152600160248301529151919092169163caece2fe91604480830192600092919082900301818387803b15801561154857600080fd5b505af115801561155c573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b038b811660048301528a81166024830152600160448301529151919092169350637d3572fd9250606480830192600092919082900301818387803b1580156115bd57600080fd5b505af11580156115d1573d6000803e3d6000fd5b50505050505050505050565b600054819061010090046001600160a01b031633148061160f5750603b546001600160a01b03163314801561160f5750805b61164a5760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b61165382613f83565b5050565b60005461010090046001600160a01b031633146116a55760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b66b1a2bc2ec5000081101580156116c45750670c7d713b49da00008111155b61170c576040805162461bcd60e51b815260206004820152601460248201527310db1bdcd948199858dd1bdc881a5b9d985b1a5960621b604482015290519081900360640190fd5b6039805490829055604080518281526020810184905281517f3b9670cf975d26958e754b57098eaa2ac914d8d2a31b83257997b9f346110fd9929181900390910190a15050565b600054819061010090046001600160a01b03163314806117855750603b546001600160a01b0316331480156117855750805b6117c05760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b6117c983613d33565b6111ec8383614561565b60006117e0603483613cef565b92915050565b603a5481565b600190565b60005461010090046001600160a01b0316331461183f5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b670de0b6b3a7640000811015801561185f57506714d1120d7b1600008111155b6118b0576040805162461bcd60e51b815260206004820152601d60248201527f4c69717569646174696f6e20696e63656e7469766520696e76616c6964000000604482015290519081900360640190fd5b603a805490829055604080518281526020810184905281517faeba5a6c40a8ac138134bff1aaa65debf25971188a58804bad717f82f0ec1316929181900390910190a15050565b60005461010090046001600160a01b031633146119455760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b6038546001600160a01b03908116908216158015906119765750806001600160a01b0316826001600160a01b031614155b6119c0576040805162461bcd60e51b815260206004820152601660248201527513dc9858db19481859191c995cdcc81a5b9d985b1a5960521b604482015290519081900360640190fd5b603880546001600160a01b0319166001600160a01b03848116918217909255604080519284168352602083019190915280517fd52b2b9b7e9ee655fcb95d2e5b9e0c9f69e7ef2b8e9d2d0ea78402d576d22e229281900390910190a15050565b60005461010090046001600160a01b03163314611a6e5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b603c546001600160a01b0390811690821615801590611a9f5750806001600160a01b0316826001600160a01b031614155b611ada5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f516022913960400191505060405180910390fd5b603c80546001600160a01b0319166001600160a01b03848116918217909255604080519284168352602083019190915280517f8ddca872a7a62d68235cff1a03badc845dc3007cfaa6145379f7bf3452ecb9b99281900390910190a15050565b60005461010090046001600160a01b03163314611b885760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b603b546001600160a01b0390811690821615801590611bb95750806001600160a01b0316826001600160a01b031614155b611c0a576040805162461bcd60e51b815260206004820152601e60248201527f506175736520677561726469616e206164647265737320696e76616c69640000604482015290519081900360640190fd5b603b80546001600160a01b0319166001600160a01b03848116918217909255604080519284168352602083019190915280517f0613b6ee6a04f0d09f390e4d9318894b9f6ac7fd83897cd8d18896ba579c401e9281900390910190a15050565b505050505050565b606060346000611c8182613d1c565b90508067ffffffffffffffff81118015611c9a57600080fd5b50604051908082528060200260200182016040528015611cc4578160200160208202803683370190505b50925060005b81811015611d0857611cdc8382613d27565b848281518110611ce857fe5b6001600160a01b0390921660209283029190910190910152600101611cca565b50505090565b60005461010090046001600160a01b03163314611d5c5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b6001600160a01b03811615801590611d8257506001546001600160a01b03828116911614155b611dbd5760405162461bcd60e51b815260040180806020018281038252604b815260200180614dc7604b913960600191505060405180910390fd5b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b90600090a35050565b600054819061010090046001600160a01b0316331480611e415750603b546001600160a01b031633148015611e415750805b611e7c5760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b611e8583613d33565b6111ec83836145c8565b603b54600160a01b900460ff1615611eee576040805162461bcd60e51b815260206004820152601860248201527f5472616e7366657220686173206265656e207061757365640000000000000000604482015290519081900360640190fd5b611ef9848483614637565b603c5460408051636576717f60e11b81526001600160a01b038781166004830152600060248301819052925193169263caece2fe9260448084019391929182900301818387803b158015611f4c57600080fd5b505af1158015611f60573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b0389811660048301528881166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b158015611fbd57600080fd5b505af1158015611fd1573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b0389811660048301528781166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b15801561115857600080fd5b60005460ff16156120705760405162461bcd60e51b815260040180806020018281038252602e815260200180614e77602e913960400191505060405180910390fd5b6120786146d4565b6000805460ff19166001179055565b6001600160a01b03821660009081526037602052604081206120ac9060020183613cef565b9392505050565b6120bc83613d33565b6001600160a01b0383166000908152603660205260409020600481015460ff161561212e576040805162461bcd60e51b815260206004820152601a60248201527f546f6b656e206d696e7420686173206265656e20706175736564000000000000604482015290519081900360640190fd5b600061220a856001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b15801561216c57600080fd5b505afa158015612180573d6000803e3d6000fd5b505050506040513d602081101561219657600080fd5b5051604080516318160ddd60e01b815290516001600160a01b038916916318160ddd916004808301926020929190829003018186803b1580156121d857600080fd5b505afa1580156121ec573d6000803e3d6000fd5b505050506040513d602081101561220257600080fd5b505190613d04565b600383015490915061221c8285614507565b111561226f576040805162461bcd60e51b815260206004820152601d60248201527f546f6b656e20737570706c792063617061636974792072656163686564000000604482015290519081900360640190fd5b603c5460408051636576717f60e11b81526001600160a01b038881166004830152600060248301819052925193169263caece2fe9260448084019391929182900301818387803b1580156122c257600080fd5b505af11580156122d6573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b038a811660048301528981166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b15801561233357600080fd5b505af1158015612347573d6000803e3d6000fd5b505050505050505050565b6001600160a01b038116600090815260376020526040812060609161237682613d1c565b90508067ffffffffffffffff8111801561238f57600080fd5b506040519080825280602002602001820160405280156123b9578160200160208202803683370190505b50925060005b81811015611076576123d18382613d27565b8482815181106123dd57fe5b6001600160a01b03909216602092830291909101909101526001016123bf565b60005461010090046001600160a01b031681565b603660205260009081526040902080546001820154600283015460038401546004909401549293919290919060ff808216916101008104821691620100009091041687565b600054819061010090046001600160a01b03163314806124885750603b546001600160a01b0316331480156124885750805b6124c35760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b61165382613f30565b60005461010090046001600160a01b0316331461251a5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b61252382613d33565b60008111801561253b5750670de0b6b3a76400008111155b612584576040805162461bcd60e51b8152602060048201526015602482015274109bdc9c9bddc8199858dd1bdc881a5b9d985b1a59605a1b604482015290519081900360640190fd5b6038546040805163fc57d4df60e01b81526001600160a01b0385811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b1580156125d157600080fd5b505afa1580156125e5573d6000803e3d6000fd5b505050506040513d60208110156125fb57600080fd5b50516126385760405162461bcd60e51b815260040180806020018281038252603c815260200180614ec6603c913960400191505060405180910390fd5b6001600160a01b0382166000818152603660209081526040918290206001810180549086905583519485529184018290528383018590529151919290917fd69d3c48186e96a0af0545cf26e970b49ed3e29a306a37118a5a787bae6b90be9181900360600190a150505050565b6000806000806126b9856000806000614049565b93509350935093509193509193565b6001600160a01b03831660009081526036602052604090206004015462010000900460ff161561273f576040805162461bcd60e51b815260206004820152601c60248201527f546f6b656e20626f72726f7720686173206265656e2070617573656400000000604482015290519081900360640190fd5b61274883613d33565b603c5460408051636576717f60e11b81526001600160a01b038681166004830152600160248301529151919092169163caece2fe91604480830192600092919082900301818387803b15801561279d57600080fd5b505af11580156127b1573d6000803e3d6000fd5b50505050505050565b603b54600160a81b900460ff1681565b603c546001600160a01b031681565b6001600160a01b038316600090815260366020526040902060040154610100900460ff161561284f576040805162461bcd60e51b815260206004820152601c60248201527f546f6b656e2072656465656d20686173206265656e2070617573656400000000604482015290519081900360640190fd5b61285a838383614637565b603c5460408051636576717f60e11b81526001600160a01b038681166004830152600060248301819052925193169263caece2fe9260448084019391929182900301818387803b1580156128ad57600080fd5b505af11580156128c1573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b0388811660048301528781166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b15801561279d57600080fd5b60005461010090046001600160a01b0316331461296c5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b61297582613d33565b6001600160a01b0382166000818152603660209081526040918290206002810180549086905583519485529184018290528383018590529151919290917f6c07964980a680dc12652ccab077a57c65740bf2ebc204a7670438051ee6fa5b9181900360600190a150505050565b6060818067ffffffffffffffff811180156129fc57600080fd5b50604051908082528060200260200182016040528015612a26578160200160208202803683370190505b50915060005b81811015612a7d57612a59858583818110612a4357fe5b905060200201356001600160a01b03163361471c565b838281518110612a6557fe5b91151560209283029190910190910152600101612a2c565b505092915050565b6038546040805163fc57d4df60e01b81526001600160a01b03868116600483015291516000938493169163fc57d4df916024808301926020929190829003018186803b158015612ad457600080fd5b505afa158015612ae8573d6000803e3d6000fd5b505050506040513d6020811015612afe57600080fd5b50516038546040805163fc57d4df60e01b81526001600160a01b0388811660048301529151939450600093919092169163fc57d4df916024808301926020929190829003018186803b158015612b5357600080fd5b505afa158015612b67573d6000803e3d6000fd5b505050506040513d6020811015612b7d57600080fd5b505190508115801590612b8f57508015155b612bca5760405162461bcd60e51b815260040180806020018281038252602d815260200180614f24602d913960400191505060405180910390fd5b603a54600090612be490612bde87866147ab565b90613d04565b90506000866001600160a01b031663182df0f56040518163ffffffff1660e01b815260040160206040518083038186803b158015612c2157600080fd5b505afa158015612c35573d6000803e3d6000fd5b505050506040513d6020811015612c4b57600080fd5b50519050612c6383612c5d8484614804565b9061481c565b98975050505050505050565b603b54600160a81b900460ff1615612cc6576040805162461bcd60e51b815260206004820152601560248201527414d95a5e99481a185cc81899595b881c185d5cd959605a1b604482015290519081900360640190fd5b612cd1603485613cef565b8015612ce35750612ce3603486613cef565b612d34576040805162461bcd60e51b815260206004820152601b60248201527f546f6b656e732068617665206e6f74206265656e206c69737465640000000000604482015290519081900360640190fd5b846001600160a01b031663f77c47916040518163ffffffff1660e01b815260040160206040518083038186803b158015612d6d57600080fd5b505afa158015612d81573d6000803e3d6000fd5b505050506040513d6020811015612d9757600080fd5b50516040805163f77c479160e01b815290516001600160a01b039283169287169163f77c4791916004808301926020929190829003018186803b158015612ddd57600080fd5b505afa158015612df1573d6000803e3d6000fd5b505050506040513d6020811015612e0757600080fd5b50516001600160a01b031614612e4e5760405162461bcd60e51b8152600401808060200182810382526033815260200180614d726033913960400191505060405180910390fd5b603c5460408051636576717f60e11b81526001600160a01b038881166004830152600060248301819052925193169263caece2fe9260448084019391929182900301818387803b158015612ea157600080fd5b505af1158015612eb5573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b038a811660048301528881166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b158015612f1257600080fd5b505af1158015612f26573d6000803e3d6000fd5b5050603c5460408051637d3572fd60e01b81526001600160a01b038a811660048301528781166024830152600060448301819052925193169450637d3572fd93506064808201939182900301818387803b15801561233357600080fd5b6060818067ffffffffffffffff81118015612f9d57600080fd5b50604051908082528060200260200182016040528015612fc7578160200160208202803683370190505b50915060005b81811015612a7d57612ffa858583818110612fe457fe5b905060200201356001600160a01b03163361485e565b83828151811061300657fe5b91151560209283029190910190910152600101612fcd565b6001600160a01b03821660009081526037602052604081206120ac9083613cef565b60005461010090046001600160a01b0316331461308e5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b61309782613d33565b6001600160a01b0382166000818152603660209081526040918290206003810180549086905583519485529184018290528383018590529151919290917f6ffc41eacf6bc473fab68880680a35214210358ff10d45c53cee339f1547f0bb9181900360600190a150505050565b60005461010090046001600160a01b031633146131525760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b856001600160a01b031663744279376040518163ffffffff1660e01b8152600401602060405180830381600087803b15801561318d57600080fd5b505af11580156131a1573d6000803e3d6000fd5b505050506040513d60208110156131b757600080fd5b5051613203576040805162461bcd60e51b8152602060048201526016602482015275151bdad95b881a5cc81b9bdd081cdd5c1c1bdc9d195960521b604482015290519081900360640190fd5b306001600160a01b0316866001600160a01b031663f77c47916040518163ffffffff1660e01b815260040160206040518083038186803b15801561324657600080fd5b505afa15801561325a573d6000803e3d6000fd5b505050506040513d602081101561327057600080fd5b50516001600160a01b0316146132b75760405162461bcd60e51b8152600401808060200182810382526022815260200180614da56022913960400191505060405180910390fd5b6132c260348761499f565b613313576040805162461bcd60e51b815260206004820152601d60248201527f546f6b656e2068617320616c7265616479206265656e206c6973746564000000604482015290519081900360640190fd5b670de0b6b3a764000085111561336c576040805162461bcd60e51b815260206004820152601960248201527810dbdb1b185d195c985b08199858dd1bdc881a5b9d985b1a59603a1b604482015290519081900360640190fd5b6000841180156133845750670de0b6b3a76400008411155b6133cd576040805162461bcd60e51b8152602060048201526015602482015274109bdc9c9bddc8199858dd1bdc881a5b9d985b1a59605a1b604482015290519081900360640190fd5b6038546040805163fc57d4df60e01b81526001600160a01b0389811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561341a57600080fd5b505afa15801561342e573d6000803e3d6000fd5b505050506040513d602081101561344457600080fd5b5051613497576040805162461bcd60e51b815260206004820152601f60248201527f556e6465726c79696e6720707269636520697320756e617661696c61626c6500604482015290519081900360640190fd5b6040518060e001604052808681526020018581526020018381526020018481526020016000151581526020016000151581526020016000151581525060366000886001600160a01b03166001600160a01b031681526020019081526020016000206000820151816000015560208201518160010155604082015181600201556060820151816003015560808201518160040160006101000a81548160ff02191690831515021790555060a08201518160040160016101000a81548160ff02191690831515021790555060c08201518160040160026101000a81548160ff021916908315150217905550905050603c60009054906101000a90046001600160a01b03166001600160a01b0316635658fec387836040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050600060405180830381600087803b1580156135ef57600080fd5b505af1158015613603573d6000803e3d6000fd5b5050604080516001600160a01b038a16815260208101899052808201889052606081018790526080810186905260a0810185905290517f96f15e56d27d14b82ed736fd9387871d60f721cd59f324699722b4f0d11ee1b193509081900360c0019150a1505050505050565b61367733613d33565b613681828261471c565b6116535760405162461bcd60e51b8152600401808060200182810382526036815260200180614fd86036913960400191505060405180910390fd5b600054819061010090046001600160a01b03163314806136ee5750603b546001600160a01b0316331480156136ee5750805b6137295760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b6034600061373682613d1c565b905060005b8181101561107e576137566137508483613d27565b86614561565b60010161373b565b600054819061010090046001600160a01b03163314806137905750603b546001600160a01b0316331480156137905750805b6137cb5760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b603460006137d882613d1c565b905060005b8181101561107e576137f86137f28483613d27565b866145c8565b6001016137dd565b6001546001600160a01b031681565b60005461010090046001600160a01b0316331461385d5760405162461bcd60e51b8152600401808060200182810382526022815260200180614f026022913960400191505060405180910390fd5b61386682613d33565b670de0b6b3a76400008111156138bf576040805162461bcd60e51b815260206004820152601960248201527810dbdb1b185d195c985b08199858dd1bdc881a5b9d985b1a59603a1b604482015290519081900360640190fd5b6038546040805163fc57d4df60e01b81526001600160a01b0385811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561390c57600080fd5b505afa158015613920573d6000803e3d6000fd5b505050506040513d602081101561393657600080fd5b50516139735760405162461bcd60e51b8152600401808060200182810382526040815260200180614f736040913960400191505060405180910390fd5b6001600160a01b038216600081815260366020908152604091829020805485825583519485529184018290528383018590529151919290917f70483e6592cd5182d45ac970e05bc62cdcc90e9d8ef2c2dbe686cf383bcd7fc59181900360600190a150505050565b600054819061010090046001600160a01b0316331480613a0d5750603b546001600160a01b031633148015613a0d5750805b613a485760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b60346000613a5582613d1c565b905060005b8181101561107e57613a75613a6f8483613d27565b86613d92565b600101613a5a565b60395481565b613a8c84613d33565b836001600160a01b03166395dd9193836040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015613ad957600080fd5b505afa158015613aed573d6000803e3d6000fd5b505050506040513d6020811015613b0357600080fd5b50516112ca57336001600160a01b03851614613b5e576040805162461bcd60e51b815260206004820152601560248201527439b2b73232b91036bab9ba1031329034aa37b5b2b760591b604482015290519081900360640190fd5b6112ca82856149b4565b600054819061010090046001600160a01b0316331480613b9a5750603b546001600160a01b031633148015613b9a5750805b613bd55760405162461bcd60e51b815260040180806020018281038252603c815260200180614e3b603c913960400191505060405180910390fd5b613bde83613d33565b6111ec8383613e03565b603b54600160a01b900460ff1681565b6001546001600160a01b03163314613c415760405162461bcd60e51b8152600401808060200182810382526025815260200180614fb36025913960400191505060405180910390fd5b60008054600180546001600160a01b03818116610100818102610100600160a81b03198716178088556001600160a01b031990941690945560405194849004821695909493909204169184917f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b236491a36001546040516001600160a01b03918216918316907fb3d55174552271a4f1aaf36b72f50381e892171636b3fb5447fe00e995e7a37b90600090a35050565b60006120ac836001600160a01b038416614a27565b60006120ac670de0b6b3a7640000612c5d85856147ab565b60006117e082614a3f565b60006120ac8383614a43565b613d3e603482613cef565b613d8f576040805162461bcd60e51b815260206004820152601960248201527f546f6b656e20686173206e6f74206265656e206c697374656400000000000000604482015290519081900360640190fd5b50565b6001600160a01b038216600081815260366020908152604091829020600401805462ff00001916620100008615159081029190911790915582519384529083015280517fa501bd5ac3de9924ce0c13576750267130fd835780f1ec6e1ae9fb13ee7465039281900390910190a15050565b6001600160a01b03821660008181526036602090815260409182902060048101805460ff1916861515908117909155835194855291840191909152815190927f48cff1fdfe035051f817c77855362a92f96f941342d41008f2d596f530c4e96b92908290030190a160048101805461ff00191661010084151590810291909117909155604080516001600160a01b0386168152602081019290925280517f3d95d87adcb06de16ac0e322ea97a06e30967fedcc83a6d1d0b9fda60300801a9281900390910190a160048101805462ff000019166201000084151590810291909117909155604080516001600160a01b0386168152602081019290925280517fa501bd5ac3de9924ce0c13576750267130fd835780f1ec6e1ae9fb13ee7465039281900390910190a1505050565b603b8054821515600160a01b810260ff60a01b199092169190911790915560408051918252517f7b92c580e5b53e34f85950f4117143b86c4031ca9568a3cd30f4b3cd5bb95dc89181900360200190a150565b603b8054821515600160a81b810260ff60a81b199092169190911790915560408051918252517fcaf79886b466b41f609cc39fdc375ab5484cc3811570b7faa22fcb2b55516fdf9181900360200190a150565b6001600160a01b0382166000908152603760205260409020613ffb906002018261499f565b1561165357604080516001600160a01b0380841682528416602082015281517f61400a0050615e96f6a4a234e4fc162ab71775345f32f4641cd884601603a455929181900390910190a15050565b600080600080614057614d0a565b6001600160a01b03891660009081526037602052604081209061407982613d1c565b905060005b818110156142cb5760006140928483613d27565b9050806001600160a01b03166370a082318e6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156140e157600080fd5b505afa1580156140f5573d6000803e3d6000fd5b505050506040513d602081101561410b57600080fd5b5051604080870191909152805163182df0f560e01b815290516001600160a01b0383169163182df0f5916004808301926020929190829003018186803b15801561415457600080fd5b505afa158015614168573d6000803e3d6000fd5b505050506040513d602081101561417e57600080fd5b505160808601526001600160a01b038c81169082161480156141a0575060008b115b156141ba5760408501516141b4908c614aa7565b60408601525b6038546040805163fc57d4df60e01b81526001600160a01b0384811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b15801561420757600080fd5b505afa15801561421b573d6000803e3d6000fd5b505050506040513d602081101561423157600080fd5b505160a086018190526142755760405162461bcd60e51b8152600401808060200182810382526029815260200180614e126029913960400191505060405180910390fd5b6001600160a01b0381166000908152603660205260409081902054608087015160a0880151928801516142ae93612bde929183916147ab565b60c0860181905285516142c091614507565b85525060010161407e565b506142d882600201613d1c565b905060005b818110156144c25760006142f46002850183613d27565b9050806001600160a01b03166395dd91938e6040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b15801561434357600080fd5b505afa158015614357573d6000803e3d6000fd5b505050506040513d602081101561436d57600080fd5b505160608601526001600160a01b038c811690821614801561438f575060008a115b156143a95760608501516143a3908b614507565b60608601525b6038546040805163fc57d4df60e01b81526001600160a01b0384811660048301529151919092169163fc57d4df916024808301926020929190829003018186803b1580156143f657600080fd5b505afa15801561440a573d6000803e3d6000fd5b505050506040513d602081101561442057600080fd5b505160a086018190526144645760405162461bcd60e51b8152600401808060200182810382526029815260200180614e126029913960400191505060405180910390fd5b6001600160a01b03811660009081526036602052604090206001015460a0860151606087015161449f929161449991906147ab565b90614804565b60e0860181905260208601516144b491614507565b6020860152506001016142dd565b5060208301518351116144e25782516020840151600091808203916144f2565b6020830151835181810391600091905b929e919d509b50909950975050505050505050565b6000828201838110156120ac576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6001600160a01b038216600081815260366020908152604091829020600401805460ff191685151590811790915582519384529083015280517f48cff1fdfe035051f817c77855362a92f96f941342d41008f2d596f530c4e96b9281900390910190a15050565b6001600160a01b038216600081815260366020908152604091829020600401805461ff0019166101008615159081029190911790915582519384529083015280517f3d95d87adcb06de16ac0e322ea97a06e30967fedcc83a6d1d0b9fda60300801a9281900390910190a15050565b61464083613d33565b6001600160a01b03821660009081526037602052604090206146629084613cef565b61466b576111ec565b600061467a8385846000614049565b5050915050806000146112ca576040805162461bcd60e51b815260206004820152601a60248201527f4163636f756e742068617320736f6d652073686f727466616c6c000000000000604482015290519081900360640190fd5b60008054610100600160a81b0319163361010081029190911782556040519091907f70aea8d848e8a90fb7661b227dc522eb6395c3dac71b63cb59edd5c9899b2364908290a3565b6000614729603484613cef565b614735575060006117e0565b6001600160a01b0382166000908152603760205260409020614757908461499f565b156147a257604080516001600160a01b0380861682528416602082015281517f3ab23ab0d51cccc0c3085aec51f99228625aa1a922b3a8ca89a26b0f2027a1a5929181900390910190a15b50600192915050565b6000826147ba575060006117e0565b828202828482816147c757fe5b04146120ac5760405162461bcd60e51b8152600401808060200182810382526021815260200180614ea56021913960400191505060405180910390fd5b60006120ac82612c5d85670de0b6b3a76400006147ab565b60006120ac83836040518060400160405280601a81526020017f536166654d6174683a206469766973696f6e206279207a65726f000000000000815250614ae9565b600061486b603484613cef565b614877575060016117e0565b6001600160a01b03821660009081526037602052604090206148999084613cef565b6148a5575060016117e0565b6000836001600160a01b03166370a08231846040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b1580156148f457600080fd5b505afa158015614908573d6000803e3d6000fd5b505050506040513d602081101561491e57600080fd5b5051905061492d848483614637565b6001600160a01b038316600090815260376020526040902061494f9085614b8b565b50604080516001600160a01b0380871682528516602082015281517fe699a64c18b07ac5b7301aa273f36a2287239eb9501d81950672794afba29a0d929181900390910190a15060019392505050565b60006120ac836001600160a01b038416614ba0565b6001600160a01b03821660009081526037602052604090206149d99060020182614b8b565b1561165357604080516001600160a01b0380841682528416602082015281517f6df0340c4ae9990f4b8f3c3e0e5408dcf6ba2c086b92966dfdbbef1f2f052e1a929181900390910190a15050565b60009081526001919091016020526040902054151590565b5490565b81546000908210614a855760405162461bcd60e51b8152600401808060200182810382526022815260200180614d506022913960400191505060405180910390fd5b826000018281548110614a9457fe5b9060005260206000200154905092915050565b60006120ac83836040518060400160405280601e81526020017f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815250614bea565b60008183614b755760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614b3a578181015183820152602001614b22565b50505050905090810190601f168015614b675780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b506000838581614b8157fe5b0495945050505050565b60006120ac836001600160a01b038416614c44565b6000614bac8383614a27565b614be2575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556117e0565b5060006117e0565b60008184841115614c3c5760405162461bcd60e51b8152602060048201818152835160248401528351909283926044909101919085019080838360008315614b3a578181015183820152602001614b22565b505050900390565b60008181526001830160205260408120548015614d005783546000198083019190810190600090879083908110614c7757fe5b9060005260206000200154905080876000018481548110614c9457fe5b600091825260208083209091019290925582815260018981019092526040902090840190558654879080614cc457fe5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506117e0565b60009150506117e0565b6040518061010001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152509056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473436f6e74726f6c6c6572206d69736d61746368206265747765656e20426f72726f77656420616e6420436f6c6c61746572616c546f6b656e277320636f6e74726f6c6c6572206973206e6f742074686973206f6e655f73657450656e64696e674f776e65723a204e6577206f77656e722063616e206e6f74206265207a65726f206164647265737320616e64206f776e657220686173206265656e2073657421496e76616c696420707269636520746f2063616c63756c617465206163636f756e74206571756974794f6e6c79206f776e657220616e6420677561726469616e2063616e20706175736520616e64206f6e6c79206f776e65722063616e20756e7061757365496e697469616c697a61626c653a20636f6e747261637420697320616c726561647920696e697469616c697a6564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774661696c656420746f2073657420626f72726f7720666163746f722c20756e6465726c79696e6720707269636520697320756e617661696c61626c656f6e6c794f776e65723a2063616c6c6572206973206e6f7420746865206f776e6572426f72726f776564206f7220436f6c6c61746572616c20617373657420707269636520697320696e76616c6964526577617264204469737472696275746f72206164647265737320696e76616c69644661696c656420746f2073657420636f6c6c61746572616c20666163746f722c20756e6465726c79696e6720707269636520697320756e617661696c61626c655f6163636570744f776e65723a204f6e6c7920666f722070656e64696e67206f776e657221656e7465724d61726b657446726f6d69546f6b656e3a204f6e6c792063616e20656e7465722061206c6973746564206d61726b657421a264697066735822122046829991b6c7bdf4634ad370538181df4ac87fe1a3f85eb848ae3e07e35b998a64736f6c634300060c0033
Deployed ByteCode Sourcemap
55530:54428:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85828:933;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;85828:933:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;107025:454;;;;;;;;;;;;;;;;-1:-1:-1;107025:454:0;-1:-1:-1;;;;;107025:454:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90158:333;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;90158:333:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;83612:603::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;83612:603:0;;;;;;;;;;;;;;;;;;;;;;:::i;73019:229::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;73019:229:0;;;;;;;;;;:::i;59248:28::-;;;:::i;:::-;;;;-1:-1:-1;;;;;59248:28:0;;;;;;;;;;;;;;57943:26;;;:::i;75544:493::-;;;;;;;;;;;;;;;;-1:-1:-1;75544:493:0;;;;:::i;81083:1549::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;81083:1549:0;;;;;;;;;;;;;;;;;:::i;74141:161::-;;;;;;;;;;;;;;;;-1:-1:-1;74141:161:0;;;;:::i;63654:528::-;;;;;;;;;;;;;;;;-1:-1:-1;63654:528:0;;:::i;70561:225::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;70561:225:0;;;;;;;;;;:::i;109832:123::-;;;;;;;;;;;;;;;;-1:-1:-1;109832:123:0;-1:-1:-1;;;;;109832:123:0;;:::i;:::-;;;;;;;;;;;;;;;;;;58518:43;;;:::i;:::-;;;;;;;;;;;;;;;;60262:92;;;:::i;64394:727::-;;;;;;;;;;;;;;;;-1:-1:-1;64394:727:0;;:::i;63094:348::-;;;;;;;;;;;;;;;;-1:-1:-1;63094:348:0;-1:-1:-1;;;;;63094:348:0;;:::i;76217:523::-;;;;;;;;;;;;;;;;-1:-1:-1;76217:523:0;-1:-1:-1;;;;;76217:523:0;;:::i;69275:475::-;;;;;;;;;;;;;;;;-1:-1:-1;69275:475:0;-1:-1:-1;;;;;69275:475:0;;:::i;87280:568::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;87280:568:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;109236:399::-;;;:::i;34583:538::-;;;;;;;;;;;;;;;;-1:-1:-1;34583:538:0;-1:-1:-1;;;;;34583:538:0;;:::i;71785:229::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;71785:229:0;;;;;;;;;;:::i;90874:876::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;90874:876:0;;;;;;;;;;;;;;;;;;;;;;:::i;59979:78::-;;;:::i;108279:208::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;108279:208:0;;;;;;;;;;:::i;77263:1046::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;77263:1046:0;;;;;;;;;;;;;;;;;:::i;101963:472::-;;;;;;;;;;;;;;;;-1:-1:-1;101963:472:0;-1:-1:-1;;;;;101963:472:0;;:::i;33494:28::-;;;:::i;57446:41::-;;;;;;;;;;;;;;;;-1:-1:-1;57446:41:0;-1:-1:-1;;;;;57446:41:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73631:167;;;;;;;;;;;;;;;;-1:-1:-1;73631:167:0;;;;:::i;66702:1029::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;66702:1029:0;;;;;;;;:::i;94844:296::-;;;;;;;;;;;;;;;;-1:-1:-1;94844:296:0;-1:-1:-1;;;;;94844:296:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80417:278;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;80417:278:0;;;;;;;;;;;;;;;;;;;;;;:::i;92632:531::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;92632:531:0;;;;;;;;;;;;;;;;;:::i;59419:23::-;;;:::i;59519:41::-;;;:::i;79320:721::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;79320:721:0;;;;;;;;;;;;;;;;;:::i;67987:431::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;67987:431:0;;;;;;;;:::i;102722:346::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102722:346:0;;-1:-1:-1;102722:346:0;-1:-1:-1;102722:346:0;:::i;100303:1307::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;100303:1307:0;;;;;;;;;;;;;;;;;:::i;82938:214::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;82938:214:0;;;;;;;;;;;;;;;;;:::i;88376:1342::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;88376:1342:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;105268:342::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;105268:342:0;;-1:-1:-1;105268:342:0;-1:-1:-1;105268:342:0;:::i;104773:218::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;104773:218:0;;;;;;;;;;:::i;68674:431::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;68674:431:0;;;;;;;;:::i;60958:1982::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;60958:1982:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;104111:375::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;104111:375:0;;;;;;;;;;:::i;69952:357::-;;;;;;;;;;;;;;;;-1:-1:-1;69952:357:0;;;;:::i;71170:361::-;;;;;;;;;;;;;;;;-1:-1:-1;71170:361:0;;;;:::i;33612:35::-;;;:::i;92076:220::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;92076:220:0;;;;;;;;;;;;;;;;;;;;;;:::i;65407:1025::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;65407:1025:0;;;;;;;;:::i;72404:361::-;;;;;;;;;;;;;;;;-1:-1:-1;72404:361:0;;;;:::i;58091:34::-;;;:::i;84570:704::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;84570:704:0;;;;;;;;;;;;;;;;;;;;;;:::i;74670:229::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;74670:229:0;;;;;;;;;;:::i;59336:26::-;;;:::i;35213:547::-;;;:::i;85828:933::-;86117:33;:7;86134:15;86117:16;:33::i;:::-;:89;;;;-1:-1:-1;86171:35:0;:7;86188:17;86171:16;:35::i;:::-;86095:166;;;;;-1:-1:-1;;;86095:166:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;86277:18;86303:28;86321:9;86303:17;:28::i;:::-;86274:57;;;;;86365:1;86352:10;:14;86344:58;;;;;-1:-1:-1;;;86344:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;86483:22;86529:15;-1:-1:-1;;;;;86521:44:0;;86566:9;86521:55;;;;;;;;;;;;;-1:-1:-1;;;;;86521:55:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;86521:55:0;86627:19;;86521:55;;-1:-1:-1;86587:17:0;;86607:40;;86521:55;;86607:19;:40::i;:::-;86587:60;;86684:9;86668:12;:25;;86660:69;;;;;-1:-1:-1;;;86660:69:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;85828:933;;;;;;;;:::o;107025:454::-;-1:-1:-1;;;;;107223:22:0;;107188:32;107223:22;;;:12;:22;;;;;107138:32;;107273:30;:21;;;:28;:30::i;:::-;107258:45;;107346:4;107332:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;107332:19:0;;107314:37;;107367:9;107362:110;107386:4;107382:1;:8;107362:110;;;107433:27;:21;;;107458:1;107433:24;:27::i;:::-;107412:15;107428:1;107412:18;;;;;;;;-1:-1:-1;;;;;107412:48:0;;;:18;;;;;;;;;;;:48;107392:3;;107362:110;;;;107025:454;;;;;:::o;90158:333::-;;;;;;:::o;83612:603::-;83785:27;83804:7;83785:18;:27::i;:::-;83934:17;;83915:113;;;-1:-1:-1;;;83915:113:0;;-1:-1:-1;;;;;83915:113:0;;;;;;;83934:17;83915:113;;;;;;83934:17;;;;;83915:61;;:113;;;;;83934:17;;83915:113;;;;;;;83934:17;;83915:113;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;84058:17:0;;84039:126;;;-1:-1:-1;;;84039:126:0;;-1:-1:-1;;;;;84039:126:0;;;;;;;;;;;;;;84058:17;84039:126;;;;;;84058:17;;;;;-1:-1:-1;84039:50:0;;-1:-1:-1;84039:126:0;;;;;84058:17;;84039:126;;;;;;;84058:17;;84039:126;;;;;;;;;;;;;;;;;;;;;;;;;;73019:229;59752:5;;73133:7;;59752:5;;;-1:-1:-1;;;;;59752:5:0;59738:10;:19;;:63;;-1:-1:-1;59776:13:0;;-1:-1:-1;;;;;59776:13:0;59762:10;:27;:38;;;;;59793:7;59762:38;59716:173;;;;-1:-1:-1;;;59716:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73158:27:::1;73177:7;73158:18;:27::i;:::-;73198:42;73223:7;73232;73198:24;:42::i;:::-;73019:229:::0;;;:::o;59248:28::-;;;-1:-1:-1;;;;;59248:28:0;;:::o;57943:26::-;;;-1:-1:-1;;;;;57943:26:0;;:::o;75544:493::-;59752:5;;75643:7;;59752:5;;;-1:-1:-1;;;;;59752:5:0;59738:10;:19;;:63;;-1:-1:-1;59776:13:0;;-1:-1:-1;;;;;59776:13:0;59762:10;:27;:38;;;;;59793:7;59762:38;59716:173;;;;-1:-1:-1;;;59716:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75723:7:::1;75668:52;75756:17;75723:7:::0;75756:15:::1;:17::i;:::-;75741:32;;75791:9;75786:153;75810:4;75806:1;:8;75786:153;;;75836:15;75854:14;:8:::0;75866:1;75854:11:::1;:14::i;:::-;75836:32;;75885:42;75910:7;75919;75885:24;:42::i;:::-;-1:-1:-1::0;75816:3:0::1;;75786:153;;;;75951:35;75978:7;75951:26;:35::i;:::-;75997:32;76021:7;75997:23;:32::i;:::-;59902:1;;75544:493:::0;;:::o;81083:1549::-;81235:27;81254:7;81235:18;:27::i;:::-;-1:-1:-1;;;;;81300:16:0;;81275:22;81300:16;;;:7;:16;;;;;81336:20;;;;;;;;;81335:21;81327:62;;;;;-1:-1:-1;;;81327:62:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;81407:31;81419:9;81430:7;81407:11;:31::i;:::-;81402:365;;81597:10;-1:-1:-1;;;;;81597:21:0;;;81589:55;;;;;-1:-1:-1;;;81589:55:0;;;;;;;;;;;;-1:-1:-1;;;81589:55:0;;;;;;;;;;;;;;;81721:34;81736:9;81747:7;81721:14;:34::i;:::-;81818:18;81857:65;81885:9;81896:7;81905:1;81908:13;81857:27;:65::i;:::-;81815:107;;;;;81943:10;81957:1;81943:15;81935:54;;;;;-1:-1:-1;;;81935:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;82068:21;82100:7;-1:-1:-1;;;;;82092:29:0;;:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;82092:31:0;82192:22;;;;82092:31;;-1:-1:-1;82156:32:0;82092:31;82174:13;82156:17;:32::i;:::-;:58;;82134:137;;;;;-1:-1:-1;;;82134:137:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;82393:17;;82374:113;;;-1:-1:-1;;;82374:113:0;;-1:-1:-1;;;;;82374:113:0;;;;;;;82393:17;82374:113;;;;;;82393:17;;;;;82374:61;;:113;;;;;82393:17;;82374:113;;;;;;;82393:17;;82374:113;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;82517:17:0;;82498:126;;;-1:-1:-1;;;82498:126:0;;-1:-1:-1;;;;;82498:126:0;;;;;;;;;;;;;;82517:17;82498:126;;;;;;82517:17;;;;;-1:-1:-1;82498:50:0;;-1:-1:-1;82498:126:0;;;;;82517:17;;82498:126;;;;;;;82517:17;;82498:126;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81083:1549;;;;;;:::o;74141:161::-;59752:5;;74237:7;;59752:5;;;-1:-1:-1;;;;;59752:5:0;59738:10;:19;;:63;;-1:-1:-1;59776:13:0;;-1:-1:-1;;;;;59776:13:0;59762:10;:27;:38;;;;;59793:7;59762:38;59716:173;;;;-1:-1:-1;;;59716:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74262:32:::1;74286:7;74262:23;:32::i;:::-;74141:161:::0;;:::o;63654:528::-;33980:5;;;;;-1:-1:-1;;;;;33980:5:0;33989:10;33980:19;33972:66;;;;-1:-1:-1;;;33972:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58254:7:::1;63805:23;:49;;:119;;;;;58384:6;63875:23;:49;;63805:119;63783:189;;;::::0;;-1:-1:-1;;;63783:189:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;63783:189:0;;;;;;;;;;;;;::::1;;64019:19;::::0;;64049:45;;;;64110:64:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;;;;;;;;::::1;34049:1;63654:528:::0;:::o;70561:225::-;59752:5;;70673:7;;59752:5;;;-1:-1:-1;;;;;59752:5:0;59738:10;:19;;:63;;-1:-1:-1;59776:13:0;;-1:-1:-1;;;;;59776:13:0;59762:10;:27;:38;;;;;59793:7;59762:38;59716:173;;;;-1:-1:-1;;;59716:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70698:27:::1;70717:7;70698:18;:27::i;:::-;70738:40;70761:7;70770;70738:22;:40::i;109832:123::-:0;109898:4;109922:25;:7;109939;109922:16;:25::i;:::-;109915:32;109832:123;-1:-1:-1;;109832:123:0:o;58518:43::-;;;;:::o;60262:92::-;60342:4;60262:92;:::o;64394:727::-;33980:5;;;;;-1:-1:-1;;;;;33980:5:0;33989:10;33980:19;33972:66;;;;-1:-1:-1;;;33972:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58699:6:::1;64563:32;:84;;:189;;;;;58853:6;64668:32;:84;;64563:189;64541:268;;;::::0;;-1:-1:-1;;;64541:268:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;64865:28;::::0;;64904:63;;;;64985:128:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;;;::::1;::::0;;;;;;;;;::::1;34049:1;64394:727:::0;:::o;63094:348::-;33980:5;;;;;-1:-1:-1;;;;;33980:5:0;33989:10;33980:19;33972:66;;;;-1:-1:-1;;;33972:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63199:11:::1;::::0;-1:-1:-1;;;;;63199:11:0;;::::1;::::0;63243:24;::::1;::::0;;::::1;::::0;:52:::1;;;63285:10;-1:-1:-1::0;;;;;63271:24:0::1;:10;-1:-1:-1::0;;;;;63271:24:0::1;;;63243:52;63221:124;;;::::0;;-1:-1:-1;;;63221:124:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;63221:124:0;;;;;;;;;;;;;::::1;;63356:11;:24:::0;;-1:-1:-1;;;;;;63356:24:0::1;-1:-1:-1::0;;;;;63356:24:0;;::::1;::::0;;::::1;::::0;;;63396:38:::1;::::0;;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;;;;;;;::::1;34049:1;63094:348:::0;:::o;76217:523::-;33980:5;;;;;-1:-1:-1;;;;;33980:5:0;33989:10;33980:19;33972:66;;;;-1:-1:-1;;;33972:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76382:17:::1;::::0;-1:-1:-1;;;;;76382:17:0;;::::1;::::0;76432:35;::::1;::::0;;::::1;::::0;:102:::1;;;76513:21;-1:-1:-1::0;;;;;76488:46:0::1;:21;-1:-1:-1::0;;;;;76488:46:0::1;;;76432:102;76410:186;;;;-1:-1:-1::0;;;76410:186:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76609:17;:41:::0;;-1:-1:-1;;;;;;76609:41:0::1;-1:-1:-1::0;;;;;76609:41:0;;::::1;::::0;;::::1;::::0;;;76666:66:::1;::::0;;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;;;;;;;::::1;34049:1;76217:523:::0;:::o;69275:475::-;33980:5;;;;;-1:-1:-1;;;;;33980:5:0;33989:10;33980:19;33972:66;;;;-1:-1:-1;;;33972:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69428:13:::1;::::0;-1:-1:-1;;;;;69428:13:0;;::::1;::::0;69476:31;::::1;::::0;;::::1;::::0;:90:::1;;;69549:17;-1:-1:-1::0;;;;;69528:38:0::1;:17;-1:-1:-1::0;;;;;69528:38:0::1;;;69476:90;69454:170;;;::::0;;-1:-1:-1;;;69454:170:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;69637:13;:33:::0;;-1:-1:-1;;;;;;69637:33:0::1;-1:-1:-1::0;;;;;69637:33:0;;::::1;::::0;;::::1;::::0;;;69688:54:::1;::::0;;;;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;::::1;::::0;;;;;;;;::::1;34049:1;69275:475:::0;:::o;87280:568::-;;;;;;;:::o;109236:399::-;109327:28;109428:7;109373:52;109463:17;109428:7;109463:15;:17::i;:::-;109448:32;;109519:4;109505:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;109505:19:0;;109491:33;;109540:9;109535:93;109559:4;109555:1;:8;109535:93;;;109602:14;:8;109614:1;109602:11;:14::i;:::-;109585:11;109597:1;109585:14;;;;;;;;-1:-1:-1;;;;;109585:31:0;;;:14;;;;;;;;;;;:31;109565:3;;109535:93;;;;109236:399;;;:::o;34583:538::-;33980:5;;;;;-1:-1:-1;;;;;33980:5:0;33989:10;33980:19;33972:66;;;;-1:-1:-1;;;33972:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;34717:29:0;::::1;::::0;;::::1;::::0;:64:::1;;-1:-1:-1::0;34769:12:0::1;::::0;-1:-1:-1;;;;;34750:31:0;;::::1;34769:12:::0;::::1;34750:31;;34717:64;34695:189;;;;-1:-1:-1::0;;;34695:189:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;34955:12;::::0;;-1:-1:-1;;;;;35016:30:0;;::::1;-1:-1:-1::0;;;;;;35016:30:0;::::1;::::0;::::1;::::0;;;35064:49:::1;::::0;34955:12;::::1;::::0;35016:30;34955:12;;35064:49:::1;::::0;34929:23:::1;::::0;35064:49:::1;34049:1;34583:538:::0;:::o;71785:229::-;59752:5;;71899:7;;59752:5;;;-1:-1:-1;;;;;59752:5:0;59738:10;:19;;:63;;-1:-1:-1;59776:13:0;;-1:-1:-1;;;;;59776:13:0;59762:10;:27;:38;;;;;59793:7;59762:38;59716:173;;;;-1:-1:-1;;;59716:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71924:27:::1;71943:7;71924:18;:27::i;:::-;71964:42;71989:7;71998;71964:24;:42::i;90874:876::-:0;91113:14;;-1:-1:-1;;;91113:14:0;;;;91112:15;91104:52;;;;;-1:-1:-1;;;91104:52:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;91261:39;91276:7;91285:5;91292:7;91261:14;:39::i;:::-;91388:17;;91369:114;;;-1:-1:-1;;;91369:114:0;;-1:-1:-1;;;;;91369:114:0;;;;;;;91388:17;91369:114;;;;;;;;91388:17;;;91369:61;;:114;;;;;91388:17;;91369:114;;;;;;91388:17;;91369:114;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;91556:17:0;;91537:123;;;-1:-1:-1;;;91537:123:0;;-1:-1:-1;;;;;91537:123:0;;;;;;;;;;;;;;91556:17;91537:123;;;;;;;;91556:17;;;-1:-1:-1;91537:50:0;;-1:-1:-1;91537:123:0;;;;;;;;;;;91556:17;;91537:123;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;91690:17:0;;91671:71;;;-1:-1:-1;;;91671:71:0;;-1:-1:-1;;;;;91671:71:0;;;;;;;;;;;;;;91690:17;91671:71;;;;;;;;91690:17;;;-1:-1:-1;91671:50:0;;-1:-1:-1;91671:71:0;;;;;;;;;;;91690:17;;91671:71;;;;;;;;;;59979:78;37258:12;;;;37257:13;37235:109;;;;-1:-1:-1;;;37235:109:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60033:16:::1;:14;:16::i;:::-;37371:12:::0;:19;;-1:-1:-1;;37371:19:0;37386:4;37371:19;;;59979:78::o;108279:208::-;-1:-1:-1;;;;;108430:22:0;;108401:4;108430:22;;;:12;:22;;;;;:49;;:31;;108471:7;108430:40;:49::i;:::-;108423:56;108279:208;-1:-1:-1;;;108279:208:0:o;77263:1046::-;77401:27;77420:7;77401:18;:27::i;:::-;-1:-1:-1;;;;;77466:16:0;;77441:22;77466:16;;;:7;:16;;;;;77502:18;;;;;;77501:19;77493:58;;;;;-1:-1:-1;;;77493:58:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;77630:30;77676:116;77748:7;-1:-1:-1;;;;;77740:35:0;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77740:37:0;77676:40;;;-1:-1:-1;;;77676:40:0;;;;-1:-1:-1;;;;;77676:38:0;;;;;:40;;;;;77740:37;;77676:40;;;;;;;:38;:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;77676:40:0;;:45;:116::i;:::-;77868:22;;;;77630:162;;-1:-1:-1;77825:39:0;77630:162;77852:11;77825:26;:39::i;:::-;:65;;77803:144;;;;;-1:-1:-1;;;77803:144:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;78070:17;;78051:114;;;-1:-1:-1;;;78051:114:0;;-1:-1:-1;;;;;78051:114:0;;;;;;;78070:17;78051:114;;;;;;;;78070:17;;;78051:61;;:114;;;;;78070:17;;78051:114;;;;;;78070:17;;78051:114;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;78195:17:0;;78176:125;;;-1:-1:-1;;;78176:125:0;;-1:-1:-1;;;;;78176:125:0;;;;;;;;;;;;;;78195:17;78176:125;;;;;;;;78195:17;;;-1:-1:-1;78176:50:0;;-1:-1:-1;78176:125:0;;;;;;;;;;;78195:17;;78176:125;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77263:1046;;;;;:::o;101963:472::-;-1:-1:-1;;;;;102165:22:0;;102130:32;102165:22;;;:12;:22;;;;;102076:36;;102215:33;102165:22;102215:31;:33::i;:::-;102200:48;;102295:4;102281:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102281:19:0;;102259:41;;102316:9;102311:117;102335:4;102331:1;:8;102311:117;;;102386:30;:12;102414:1;102386:27;:30::i;:::-;102361:19;102381:1;102361:22;;;;;;;;-1:-1:-1;;;;;102361:55:0;;;:22;;;;;;;;;;;:55;102341:3;;102311:117;;33494:28;;;;;;-1:-1:-1;;;;;33494:28:0;;:::o;57446:41::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;73631:167::-;59752:5;;73730:7;;59752:5;;;-1:-1:-1;;;;;59752:5:0;59738:10;:19;;:63;;-1:-1:-1;59776:13:0;;-1:-1:-1;;;;;59776:13:0;59762:10;:27;:38;;;;;59793:7;59762:38;59716:173;;;;-1:-1:-1;;;59716:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73755:35:::1;73782:7;73755:26;:35::i;66702:1029::-:0;33980:5;;;;;-1:-1:-1;;;;;33980:5:0;33989:10;33980:19;33972:66;;;;-1:-1:-1;;;33972:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66850:27:::1;66869:7;66850:18;:27::i;:::-;66939:1;66912:24;:28;:100;;;;;59119:4;66961:24;:51;;66912:100;66890:171;;;::::0;;-1:-1:-1;;;66890:171:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;66890:171:0;;;;;;;;;;;;;::::1;;67252:11;::::0;67239:53:::1;::::0;;-1:-1:-1;;;67239:53:0;;-1:-1:-1;;;;;67239:53:0;;::::1;;::::0;::::1;::::0;;;67252:11;;;::::1;::::0;67239:44:::1;::::0;:53;;;;;::::1;::::0;;;;;;;;67252:11;67239:53;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;67239:53:0;67217:168:::1;;;;-1:-1:-1::0;;;67217:168:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;67423:16:0;::::1;67398:22;67423:16:::0;;;:7:::1;:16;::::0;;;;;;;;67485:28:::1;::::0;::::1;::::0;;67524:55;;;;67597:126;;;;;;;::::1;::::0;;;;;;;;;;;67423:16;;67485:28;;67597:126:::1;::::0;;;;;;;::::1;34049:1;;66702:1029:::0;;:::o;94844:296::-;94969:7;94991;95013;95035;95077:55;95105:8;95123:1;95127;95130;95077:27;:55::i;:::-;95070:62;;;;;;;;94844:296;;;;;:::o;92632:531::-;-1:-1:-1;;;;;92837:16:0;;;;;;:7;:16;;;;;:29;;;;;;;;92836:30;92828:71;;;;;-1:-1:-1;;;92828:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;92912:27;92931:7;92912:18;:27::i;:::-;93061:17;;93042:113;;;-1:-1:-1;;;93042:113:0;;-1:-1:-1;;;;;93042:113:0;;;;;;;93061:17;93042:113;;;;;;93061:17;;;;;93042:61;;:113;;;;;93061:17;;93042:113;;;;;;;93061:17;;93042:113;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;92632:531;;;:::o;59419:23::-;;;-1:-1:-1;;;59419:23:0;;;;;:::o;59519:41::-;;;-1:-1:-1;;;;;59519:41:0;;:::o;79320:721::-;-1:-1:-1;;;;;79553:16:0;;;;;;:7;:16;;;;;:29;;;;;;;;79552:30;79544:71;;;;;-1:-1:-1;;;79544:71:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;79628:49;79643:7;79652:9;79663:13;79628:14;:49::i;:::-;79800:17;;79781:114;;;-1:-1:-1;;;79781:114:0;;-1:-1:-1;;;;;79781:114:0;;;;;;;79800:17;79781:114;;;;;;;;79800:17;;;79781:61;;:114;;;;;79800:17;;79781:114;;;;;;79800:17;;79781:114;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;79925:17:0;;79906:127;;;-1:-1:-1;;;79906:127:0;;-1:-1:-1;;;;;79906:127:0;;;;;;;;;;;;;;79925:17;79906:127;;;;;;;;79925:17;;;-1:-1:-1;79906:50:0;;-1:-1:-1;79906:127:0;;;;;;;;;;;79925:17;;79906:127;;;;;;;;;;67987:431;33980:5;;;;;-1:-1:-1;;;;;33980:5:0;33989:10;33980:19;33972:66;;;;-1:-1:-1;;;33972:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68131:27:::1;68150:7;68131:18;:27::i;:::-;-1:-1:-1::0;;;;;68196:16:0;::::1;68171:22;68196:16:::0;;;:7:::1;:16;::::0;;;;;;;;68251:22:::1;::::0;::::1;::::0;;68284:43;;;;68345:65;;;;;;;::::1;::::0;;;;;;;;;;;68196:16;;68251:22;;68345:65:::1;::::0;;;;;;;::::1;34049:1;;67987:431:::0;;:::o;102722:346::-;102827:22;102882:8;;102921:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;102921:16:0;;102910:27;;102953:9;102948:113;102972:4;102968:1;:8;102948:113;;;103012:37;103025:8;;103034:1;103025:11;;;;;;;;;;;;;-1:-1:-1;;;;;103025:11:0;103038:10;103012:12;:37::i;:::-;102998:8;103007:1;102998:11;;;;;;;;:51;;;:11;;;;;;;;;;;:51;102978:3;;102948:113;;;;102722:346;;;;;:::o;100303:1307::-;100659:11;;100646:61;;;-1:-1:-1;;;100646:61:0;;-1:-1:-1;;;;;100646:61:0;;;;;;;;;100496:30;;;;100659:11;;100646:44;;:61;;;;;;;;;;;;;;100659:11;100646:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;100646:61:0;100771:11;;100758:63;;;-1:-1:-1;;;100758:63:0;;-1:-1:-1;;;;;100758:63:0;;;;;;;;;100646:61;;-1:-1:-1;100718:24:0;;100771:11;;;;;100758:44;;:63;;;;;100646:61;;100758:63;;;;;;;100771:11;100758:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;100758:63:0;;-1:-1:-1;100854:19:0;;;;;:44;;-1:-1:-1;100877:21:0;;;100854:44;100832:139;;;;-1:-1:-1;;;100832:139:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101094:28;;100984:32;;101032:105;;:38;:18;101055:14;101032:22;:38::i;:::-;:43;;:105::i;:::-;100984:153;;101207:29;101260:17;-1:-1:-1;;;;;101252:45:0;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;101252:47:0;;-1:-1:-1;101500:102:0;101585:16;101500:66;:24;101252:47;101500:43;:66::i;:::-;:84;;:102::i;:::-;101475:127;100303:1307;-1:-1:-1;;;;;;;;100303:1307:0:o;88376:1342::-;88601:11;;-1:-1:-1;;;88601:11:0;;;;88600:12;88592:46;;;;;-1:-1:-1;;;88592:46:0;;;;;;;;;;;;-1:-1:-1;;;88592:46:0;;;;;;;;;;;;;;;88715:33;:7;88732:15;88715:16;:33::i;:::-;:89;;;;-1:-1:-1;88769:35:0;:7;88786:17;88769:16;:35::i;:::-;88693:166;;;;;-1:-1:-1;;;88693:166:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;89001:17;-1:-1:-1;;;;;88993:37:0;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;88993:39:0;88935:37;;;-1:-1:-1;;;88935:37:0;;;;-1:-1:-1;;;;;88935:97:0;;;;:35;;;;;:37;;;;;88993:39;;88935:37;;;;;;;:35;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;88935:37:0;-1:-1:-1;;;;;88935:97:0;;88913:198;;;;-1:-1:-1;;;88913:198:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89213:17;;89194:124;;;-1:-1:-1;;;89194:124:0;;-1:-1:-1;;;;;89194:124:0;;;;;;;89213:17;89194:124;;;;;;;;89213:17;;;89194:61;;:124;;;;;89213:17;;89194:124;;;;;;89213:17;;89194:124;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;89417:17:0;;89398:139;;;-1:-1:-1;;;89398:139:0;;-1:-1:-1;;;;;89398:139:0;;;;;;;;;;;;;;89417:17;89398:139;;;;;;;;89417:17;;;-1:-1:-1;89398:50:0;;-1:-1:-1;89398:139:0;;;;;;;;;;;89417:17;;89398:139;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;89567:17:0;;89548:137;;;-1:-1:-1;;;89548:137:0;;-1:-1:-1;;;;;89548:137:0;;;;;;;;;;;;;;89567:17;89548:137;;;;;;;;89567:17;;;-1:-1:-1;89548:50:0;;-1:-1:-1;89548:137:0;;;;;;;;;;;89567:17;;89548:137;;;;;;;;;;105268:342;105372:22;105427:8;;105464:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;105464:16:0;;105453:27;;105496:9;105491:112;105515:4;105511:1;:8;105491:112;;;105555:36;105567:8;;105576:1;105567:11;;;;;;;;;;;;;-1:-1:-1;;;;;105567:11:0;105580:10;105555:11;:36::i;:::-;105541:8;105550:1;105541:11;;;;;;;;:50;;;:11;;;;;;;;;;;:50;105521:3;;105491:112;;104773:218;-1:-1:-1;;;;;104931:22:0;;104902:4;104931:22;;;:12;:22;;;;;:52;;104975:7;104931:43;:52::i;68674:431::-;33980:5;;;;;-1:-1:-1;;;;;33980:5:0;33989:10;33980:19;33972:66;;;;-1:-1:-1;;;33972:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68818:27:::1;68837:7;68818:18;:27::i;:::-;-1:-1:-1::0;;;;;68883:16:0;::::1;68858:22;68883:16:::0;;;:7:::1;:16;::::0;;;;;;;;68938:22:::1;::::0;::::1;::::0;;68971:43;;;;69032:65;;;;;;;::::1;::::0;;;;;;;;;;;68883:16;;68938:22;;69032:65:::1;::::0;;;;;;;::::1;34049:1;;68674:431:::0;;:::o;60958:1982::-;33980:5;;;;;-1:-1:-1;;;;;33980:5:0;33989:10;33980:19;33972:66;;;;-1:-1:-1;;;33972:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61240:7:::1;-1:-1:-1::0;;;;;61232:28:0::1;;:30;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;61232:30:0;61224:65:::1;;;::::0;;-1:-1:-1;;;61224:65:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;61224:65:0;;;;;;;;;;;;;::::1;;61419:4;-1:-1:-1::0;;;;;61378:46:0::1;61386:7;-1:-1:-1::0;;;;;61378:27:0::1;;:29;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;61378:29:0;-1:-1:-1;;;;;61378:46:0::1;;61356:130;;;;-1:-1:-1::0;;;61356:130:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61604:20;:7;61616::::0;61604:11:::1;:20::i;:::-;61596:62;;;::::0;;-1:-1:-1;;;61596:62:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;58991:4;61693:17;:48;;61671:123;;;::::0;;-1:-1:-1;;;61671:123:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;61671:123:0;;;;;;;;;;;;;::::1;;61845:1;61829:13;:17;:61;;;;;59119:4;61850:13;:40;;61829:61;61807:132;;;::::0;;-1:-1:-1;;;61807:132:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;61807:132:0;;;;;;;;;;;;;::::1;;62130:11;::::0;62117:53:::1;::::0;;-1:-1:-1;;;62117:53:0;;-1:-1:-1;;;;;62117:53:0;;::::1;;::::0;::::1;::::0;;;62130:11;;;::::1;::::0;62117:44:::1;::::0;:53;;;;;::::1;::::0;;;;;;;;62130:11;62117:53;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;62117:53:0;62095:139:::1;;;::::0;;-1:-1:-1;;;62095:139:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;;;;;;;;;;;::::1;;62266:319;;;;;;;;62314:17;62266:319;;;;62368:13;62266:319;;;;62412:15;62266:319;;;;62458:15;62266:319;;;;62500:5;62266:319;;;;;;62534:5;62266:319;;;;;;62568:5;62266:319;;;;::::0;62247:7:::1;:16;62255:7;-1:-1:-1::0;;;;;62247:16:0::1;-1:-1:-1::0;;;;;62247:16:0::1;;;;;;;;;;;;:338;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62617:17;;;;;;;;;-1:-1:-1::0;;;;;62617:17:0::1;-1:-1:-1::0;;;;;62598:51:0::1;;62664:7;62686:19;62598:118;;;;;;;;;;;;;-1:-1:-1::0;;;;;62598:118:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;;62734:198:0::1;::::0;;-1:-1:-1;;;;;62734:198:0;::::1;::::0;;::::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::1;::::0;-1:-1:-1;62734:198:0;;;;;;;-1:-1:-1;62734:198:0::1;60958:1982:::0;;;;;;:::o;104111:375::-;104300:30;104319:10;104300:18;:30::i;:::-;104365:31;104378:7;104387:8;104365:12;:31::i;:::-;104343:135;;;;-1:-1:-1;;;104343:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69952:357;59752:5;;70050:7;;59752:5;;;-1:-1:-1;;;;;59752:5:0;59738:10;:19;;:63;;-1:-1:-1;59776:13:0;;-1:-1:-1;;;;;59776:13:0;59762:10;:27;:38;;;;;59793:7;59762:38;59716:173;;;;-1:-1:-1;;;59716:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70130:7:::1;70075:52;70163:17;70130:7:::0;70163:15:::1;:17::i;:::-;70148:32;;70198:9;70193:109;70217:4;70213:1;:8;70193:109;;;70243:47;70266:14;:8:::0;70278:1;70266:11:::1;:14::i;:::-;70282:7;70243:22;:47::i;:::-;70223:3;;70193:109;;71170:361:::0;59752:5;;71270:7;;59752:5;;;-1:-1:-1;;;;;59752:5:0;59738:10;:19;;:63;;-1:-1:-1;59776:13:0;;-1:-1:-1;;;;;59776:13:0;59762:10;:27;:38;;;;;59793:7;59762:38;59716:173;;;;-1:-1:-1;;;59716:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71350:7:::1;71295:52;71383:17;71350:7:::0;71383:15:::1;:17::i;:::-;71368:32;;71418:9;71413:111;71437:4;71433:1;:8;71413:111;;;71463:49;71488:14;:8:::0;71500:1;71488:11:::1;:14::i;:::-;71504:7;71463:24;:49::i;:::-;71443:3;;71413:111;;33612:35:::0;;;-1:-1:-1;;;;;33612:35:0;;:::o;65407:1025::-;33980:5;;;;;-1:-1:-1;;;;;33980:5:0;33989:10;33980:19;33972:66;;;;-1:-1:-1;;;33972:66:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65556:27:::1;65575:7;65556:18;:27::i;:::-;58991:4;65618:28;:59;;65596:134;;;::::0;;-1:-1:-1;;;65596:134:0;;::::1;;::::0;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;65596:134:0;;;;;;;;;;;;;::::1;;65921:11;::::0;65908:53:::1;::::0;;-1:-1:-1;;;65908:53:0;;-1:-1:-1;;;;;65908:53:0;;::::1;;::::0;::::1;::::0;;;65921:11;;;::::1;::::0;65908:44:::1;::::0;:53;;;;;::::1;::::0;;;;;;;;65921:11;65908:53;::::1;;::::0;::::1;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;::::0;::::1;;-1:-1:-1::0;65908:53:0;65886:172:::1;;;;-1:-1:-1::0;;;65886:172:0::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;66096:16:0;::::1;66071:22;66096:16:::0;;;:7:::1;:16;::::0;;;;;;;;66162:32;;66205:63;;;66286:138;;;;;;;::::1;::::0;;;;;;;;;;;66096:16;;66162:32;;66286:138:::1;::::0;;;;;;;::::1;34049:1;;65407:1025:::0;;:::o;72404:361::-;59752:5;;72504:7;;59752:5;;;-1:-1:-1;;;;;59752:5:0;59738:10;:19;;:63;;-1:-1:-1;59776:13:0;;-1:-1:-1;;;;;59776:13:0;59762:10;:27;:38;;;;;59793:7;59762:38;59716:173;;;;-1:-1:-1;;;59716:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72584:7:::1;72529:52;72617:17;72584:7:::0;72617:15:::1;:17::i;:::-;72602:32;;72652:9;72647:111;72671:4;72667:1;:8;72647:111;;;72697:49;72722:14;:8:::0;72734:1;72722:11:::1;:14::i;:::-;72738:7;72697:24;:49::i;:::-;72677:3;;72647:111;;58091:34:::0;;;;:::o;84570:704::-;84742:27;84761:7;84742:18;:27::i;:::-;84867:7;-1:-1:-1;;;;;84859:36:0;;84896:9;84859:47;;;;;;;;;;;;;-1:-1:-1;;;;;84859:47:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;84859:47:0;84855:370;;85047:10;-1:-1:-1;;;;;85047:21:0;;;85039:55;;;;;-1:-1:-1;;;85039:55:0;;;;;;;;;;;;-1:-1:-1;;;85039:55:0;;;;;;;;;;;;;;;85174:39;85194:9;85205:7;85174:19;:39::i;74670:229::-;59752:5;;74784:7;;59752:5;;;-1:-1:-1;;;;;59752:5:0;59738:10;:19;;:63;;-1:-1:-1;59776:13:0;;-1:-1:-1;;;;;59776:13:0;59762:10;:27;:38;;;;;59793:7;59762:38;59716:173;;;;-1:-1:-1;;;59716:173:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74809:27:::1;74828:7;74809:18;:27::i;:::-;74849:42;74874:7;74883;74849:24;:42::i;59336:26::-:0;;;-1:-1:-1;;;59336:26:0;;;;;:::o;35213:547::-;35293:12;;-1:-1:-1;;;;;35293:12:0;35279:10;:26;35257:113;;;;-1:-1:-1;;;35257:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35427:16;35446:5;;;35488:12;;-1:-1:-1;;;;;35488:12:0;;;35446:5;35553:20;;;-1:-1:-1;;;;;;35553:20:0;;;;;;-1:-1:-1;;;;;;35622:25:0;;;;;;35665;;35446:5;;;;;;;35488:12;;35684:5;;;;;;35446;;35665:25;;;35739:12;;35706:46;;-1:-1:-1;;;;;35739:12:0;;;;35706:46;;;;;35739:12;;35706:46;35213:547;;:::o;48195:158::-;48275:4;48299:46;48309:3;-1:-1:-1;;;;;48329:14:0;;48299:9;:46::i;30352:111::-;30411:9;30437:18;30166:6;30437:8;:1;30443;30437:5;:8::i;48439:117::-;48502:7;48529:19;48537:3;48529:7;:19::i;48900:149::-;48974:7;49017:22;49021:3;49033:5;49017:3;:22::i;94370:141::-;94448:25;:7;94465;94448:16;:25::i;:::-;94440:63;;;;;-1:-1:-1;;;94440:63:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;94370:141;:::o;73256:178::-;-1:-1:-1;;;;;73341:16:0;;;;;;:7;:16;;;;;;;;;:29;;:39;;-1:-1:-1;;73341:39:0;;;;;;;;;;;;;;;73396:30;;;;;;;;;;;;;;;;;;;;;73256:178;;:::o;74907:397::-;-1:-1:-1;;;;;75017:16:0;;74992:22;75017:16;;;:7;:16;;;;;;;;;75046:18;;;:28;;-1:-1:-1;;75046:28:0;;;;;;;;;;75090;;;;;;;;;;;;;;75017:16;;75090:28;;;;;;;;;75131:20;;;:30;;-1:-1:-1;;75131:30:0;;;;;;;;;;;;;;;75177;;;-1:-1:-1;;;;;75177:30:0;;;;;;;;;;;;;;;;;;;;;;;75220:20;;;:30;;-1:-1:-1;;75220:30:0;;;;;;;;;;;;;;;75266;;;-1:-1:-1;;;;;75266:30:0;;;;;;;;;;;;;;;;;;;;;;;74907:397;;;:::o;73806:141::-;73876:14;:24;;;;;-1:-1:-1;;;73876:24:0;;-1:-1:-1;;;;73876:24:0;;;;;;;;;;73916:23;;;;;;;;;;;;;;;;73806:141;:::o;74310:132::-;74377:11;:21;;;;;-1:-1:-1;;;74377:21:0;;-1:-1:-1;;;;74377:21:0;;;;;;;;;;74414:20;;;;;;;;;;;;;;;;74310:132;:::o;107710:274::-;-1:-1:-1;;;;;107867:22:0;;;;;;:12;:22;;;;;:44;;:31;;107903:7;107867:35;:44::i;:::-;107863:114;;;107933:32;;;-1:-1:-1;;;;;107933:32:0;;;;;;;;;;;;;;;;;;;;;;;;107710:274;;:::o;96214:3634::-;96463:7;96485;96507;96529;96564:36;;:::i;:::-;-1:-1:-1;;;;;96646:22:0;;96611:32;96646:22;;;:12;:22;;;;;;96940:33;96646:22;96940:31;:33::i;:::-;96925:48;;96989:9;96984:1129;97008:4;97004:1;:8;96984:1129;;;97034:14;97059:30;:12;97087:1;97059:27;:30::i;:::-;97034:56;;97156:6;-1:-1:-1;;;;;97130:44:0;;97193:8;97130:86;;;;;;;;;;;;;-1:-1:-1;;;;;97130:86:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;97130:86:0;97107:20;;;;:109;;;;97261:27;;-1:-1:-1;;;97261:27:0;;;;-1:-1:-1;;;;;97261:25:0;;;;;:27;;;;;97130:86;;97261:27;;;;;;;:25;:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;97261:27:0;97231;;;:57;-1:-1:-1;;;;;97309:33:0;;;;;;;:54;;;;;97362:1;97346:13;:17;97309:54;97305:157;;;97407:20;;;;:39;;97432:13;97407:24;:39::i;:::-;97384:20;;;:62;97305:157;97516:11;;97503:79;;;-1:-1:-1;;;97503:79:0;;-1:-1:-1;;;;;97503:79:0;;;;;;;;;97516:11;;;;;97503:62;;:79;;;;;;;;;;;;;;97516:11;97503:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;97503:79:0;97478:22;;;:104;;;97599:130;;;;-1:-1:-1;;;97599:130:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;97931:24:0;;;;;;:7;:24;;;;;;;:49;97879:27;;;;97832:22;;;;97771:38;;;;:210;;:136;;97879:27;97771:136;;:60;:84::i;:210::-;97746:22;;;:235;;;98021:20;;:80;;:24;:80::i;:::-;97998:103;;-1:-1:-1;97014:3:0;;96984:1129;;;;98290:30;:12;:21;;:28;:30::i;:::-;98283:37;;98336:9;98331:961;98355:4;98351:1;:8;98331:961;;;98381:14;98406:27;:21;;;98431:1;98406:24;:27::i;:::-;98381:53;;98474:6;-1:-1:-1;;;;;98474:26:0;;98501:8;98474:36;;;;;;;;;;;;;-1:-1:-1;;;;;98474:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;98474:36:0;98451:20;;;:59;-1:-1:-1;;;;;98531:33:0;;;;;;;:54;;;;;98584:1;98568:13;:17;98531:54;98527:157;;;98629:20;;;;:39;;98654:13;98629:24;:39::i;:::-;98606:20;;;:62;98527:157;98738:11;;98725:79;;;-1:-1:-1;;;98725:79:0;;-1:-1:-1;;;;;98725:79:0;;;;;;;;;98738:11;;;;;98725:62;;:79;;;;;;;;;;;;;;98738:11;98725:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;98725:79:0;98700:22;;;:104;;;98821:130;;;;-1:-1:-1;;;98821:130:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;99154:24:0;;;;;;:7;:24;;;;;:45;;;99107:22;;;;99046:38;;;;:154;;99154:45;99046:84;;:38;:60;:84::i;:::-;:107;;:154::i;:::-;99025:18;;;:175;;;99238:18;;;;:42;;:22;:42::i;:::-;99217:18;;;:63;-1:-1:-1;98361:3:0;;98331:961;;;-1:-1:-1;99382:18:0;;;;99359:20;;:41;:481;;99717:20;;99696:18;;;;99671:1;;99696:41;;;;99359:481;;;99466:18;;;;99443:20;;:41;;;;:20;;;99359:481;99339:501;;;;-1:-1:-1;99339:501:0;-1:-1:-1;99339:501:0;;-1:-1:-1;96214:3634:0;-1:-1:-1;;;;;;;;96214:3634:0:o;1042:181::-;1100:7;1132:5;;;1156:6;;;;1148:46;;;;;-1:-1:-1;;;1148:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;70794:172;-1:-1:-1;;;;;70877:16:0;;;;;;:7;:16;;;;;;;;;:27;;:37;;-1:-1:-1;;70877:37:0;;;;;;;;;;70930:28;;;;;;;;;;;;;;;;;;;;;70794:172;;:::o;72022:178::-;-1:-1:-1;;;;;72107:16:0;;;;;;:7;:16;;;;;;;;;:29;;:39;;-1:-1:-1;;72107:39:0;;;;;;;;;;;;;;;72162:30;;;;;;;;;;;;;;;;;;;;;72022:178;;:::o;93761:543::-;93896:27;93915:7;93896:18;:27::i;:::-;-1:-1:-1;;;;;94028:23:0;;;;;;:12;:23;;;;;:53;;94073:7;94028:44;:53::i;:::-;94023:93;;94098:7;;94023:93;94131:18;94170:59;94198:9;94209:7;94218;94227:1;94170:27;:59::i;:::-;94128:101;;;;;94250:10;94264:1;94250:15;94242:54;;;;;-1:-1:-1;;;94242:54:0;;;;;;;;;;;;;;;;;;;;;;;;;;;34165:120;34211:5;:18;;-1:-1:-1;;;;;;34211:18:0;34219:10;34211:18;;;;;;;;;34245:32;;34219:10;;34211:5;34245:32;;34211:5;;34245:32;34165:120::o;103376:459::-;103469:4;103535:25;:7;103552;103535:16;:25::i;:::-;103530:71;;-1:-1:-1;103584:5:0;103577:12;;103530:71;-1:-1:-1;;;;;103691:22:0;;;;;;:12;:22;;;;;:47;;103730:7;103691:38;:47::i;:::-;103687:117;;;103760:32;;;-1:-1:-1;;;;;103760:32:0;;;;;;;;;;;;;;;;;;;;;;;;103687:117;-1:-1:-1;103823:4:0;103376:459;;;;:::o;2396:471::-;2454:7;2699:6;2695:47;;-1:-1:-1;2729:1:0;2722:8;;2695:47;2766:5;;;2770:1;2766;:5;:1;2790:5;;;;;:10;2782:56;;;;-1:-1:-1;;;2782:56:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30471:111;30530:9;30556:18;30572:1;30556:11;:1;30166:6;30556:5;:11::i;3343:132::-;3401:7;3428:39;3432:1;3435;3428:39;;;;;;;;;;;;;;;;;:3;:39::i;105917:886::-;106009:4;106075:25;:7;106092;106075:16;:25::i;:::-;106070:70;;-1:-1:-1;106124:4:0;106117:11;;106070:70;-1:-1:-1;;;;;106214:22:0;;;;;;:12;:22;;;;;:52;;106258:7;106214:43;:52::i;:::-;106209:97;;-1:-1:-1;106290:4:0;106283:11;;106209:97;106353:16;106390:7;-1:-1:-1;;;;;106372:36:0;;106409:8;106372:46;;;;;;;;;;;;;-1:-1:-1;;;;;106372:46:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;106372:46:0;;-1:-1:-1;106557:43:0;106572:7;106581:8;106372:46;106557:14;:43::i;:::-;-1:-1:-1;;;;;106672:22:0;;;;;;:12;:22;;;;;:50;;106714:7;106672:41;:50::i;:::-;-1:-1:-1;106740:31:0;;;-1:-1:-1;;;;;106740:31:0;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;106791:4:0;;105917:886;-1:-1:-1;;;105917:886:0:o;47641:143::-;47711:4;47735:41;47740:3;-1:-1:-1;;;;;47760:14:0;;47735:4;:41::i;108685:301::-;-1:-1:-1;;;;;108864:22:0;;;;;;:12;:22;;;;;:47;;:31;;108903:7;108864:38;:47::i;:::-;108860:119;;;108933:34;;;-1:-1:-1;;;;;108933:34:0;;;;;;;;;;;;;;;;;;;;;;;;108685:301;;:::o;44925:129::-;44998:4;45022:19;;;:12;;;;;:19;;;;;;:24;;;44925:129::o;45140:109::-;45223:18;;45140:109::o;45593:204::-;45688:18;;45660:7;;45688:26;-1:-1:-1;45680:73:0;;;;-1:-1:-1;;;45680:73:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45771:3;:11;;45783:5;45771:18;;;;;;;;;;;;;;;;45764:25;;45593:204;;;;:::o;1506:136::-;1564:7;1591:43;1595:1;1598;1591:43;;;;;;;;;;;;;;;;;:3;:43::i;3971:278::-;4057:7;4092:12;4085:5;4077:28;;;;-1:-1:-1;;;4077:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4116:9;4132:1;4128;:5;;;;;;;3971:278;-1:-1:-1;;;;;3971:278:0:o;47960:149::-;48033:4;48057:44;48065:3;-1:-1:-1;;;;;48085:14:0;;48057:7;:44::i;42705:414::-;42768:4;42790:21;42800:3;42805:5;42790:9;:21::i;:::-;42785:327;;-1:-1:-1;42828:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;43011:18;;42989:19;;;:12;;;:19;;;;;;:40;;;;43044:11;;42785:327;-1:-1:-1;43095:5:0;43088:12;;1945:192;2031:7;2067:12;2059:6;;;;2051:29;;;;-1:-1:-1;;;2051:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;2103:5:0;;;1945:192::o;43295:1544::-;43361:4;43500:19;;;:12;;;:19;;;;;;43536:15;;43532:1300;;43971:18;;-1:-1:-1;;43922:14:0;;;;43971:22;;;;43898:21;;43971:3;;:22;;44258;;;;;;;;;;;;;;44238:42;;44404:9;44375:3;:11;;44387:13;44375:26;;;;;;;;;;;;;;;;;;;:38;;;;44481:23;;;44523:1;44481:12;;;:23;;;;;;44507:17;;;44481:43;;44633:17;;44481:3;;44633:17;;;;;;;;;;;;;;;;;;;;;;44728:3;:12;;:19;44741:5;44728:19;;;;;;;;;;;44721:26;;;44771:4;44764:11;;;;;;;;43532:1300;44815:5;44808:12;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o
Metadata Hash
46829991b6c7bdf4634ad370538181df4ac87fe1a3f85eb848ae3e07e35b998a
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.