Feature Tip: Add private address tag to any address under My Name Tag !
Overview
ETH Balance
13 wei
Eth Value
Less Than $0.01 (@ $3,468.56/ETH)More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 891 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Liquidate Unclos... | 12720841 | 1276 days ago | IN | 0 ETH | 0.00400944 | ||||
Close Loan | 12720372 | 1276 days ago | IN | 0 ETH | 0.00360661 | ||||
Close Loan | 12681607 | 1282 days ago | IN | 0 ETH | 0.01351769 | ||||
Withdraw Collate... | 12681589 | 1282 days ago | IN | 0 ETH | 0.00912688 | ||||
Repay Loan | 12681574 | 1282 days ago | IN | 0 ETH | 0.0120254 | ||||
Withdraw Collate... | 12680874 | 1282 days ago | IN | 0 ETH | 0.01768333 | ||||
Repay Loan | 12680818 | 1282 days ago | IN | 0 ETH | 0.0341978 | ||||
Close Loan | 12680794 | 1282 days ago | IN | 0 ETH | 0.03680935 | ||||
Close Loan | 12680778 | 1282 days ago | IN | 0 ETH | 0.04145066 | ||||
Close Loan | 12678712 | 1282 days ago | IN | 0 ETH | 0.0103832 | ||||
Close Loan | 12674588 | 1283 days ago | IN | 0 ETH | 0.00334818 | ||||
Close Loan | 12674568 | 1283 days ago | IN | 0 ETH | 0.00234273 | ||||
Close Loan | 12673209 | 1283 days ago | IN | 0 ETH | 0.0093744 | ||||
Close Loan | 12662747 | 1285 days ago | IN | 0 ETH | 0.00319948 | ||||
Close Loan | 12662136 | 1285 days ago | IN | 0 ETH | 0.00441162 | ||||
Close Loan | 12658406 | 1285 days ago | IN | 0 ETH | 0.00535689 | ||||
Close Loan | 12649510 | 1287 days ago | IN | 0 ETH | 0.00680899 | ||||
Close Loan | 12628956 | 1290 days ago | IN | 0 ETH | 0.00371778 | ||||
Close Loan | 12619110 | 1292 days ago | IN | 0 ETH | 0.00356963 | ||||
Close Loan | 12619062 | 1292 days ago | IN | 0 ETH | 0.00349445 | ||||
Close Loan | 12617548 | 1292 days ago | IN | 0 ETH | 0.00336782 | ||||
Close Loan | 12608087 | 1293 days ago | IN | 0 ETH | 0.00496978 | ||||
Close Loan | 12604708 | 1294 days ago | IN | 0 ETH | 0.00290862 | ||||
Close Loan | 12589543 | 1296 days ago | IN | 0 ETH | 0.00463911 | ||||
Close Loan | 12578877 | 1298 days ago | IN | 0 ETH | 0.00316742 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block |
From
|
To
|
|||
---|---|---|---|---|---|---|
12720841 | 1276 days ago | 0.00010424 ETH | ||||
12720841 | 1276 days ago | 0.00000575 ETH | ||||
12720752 | 1276 days ago | 0.94425816 ETH | ||||
12720752 | 1276 days ago | 0.05574183 ETH | ||||
12720752 | 1276 days ago | 0.54346195 ETH | ||||
12720752 | 1276 days ago | 0.07820714 ETH | ||||
12720752 | 1276 days ago | 0.7719653 ETH | ||||
12720752 | 1276 days ago | 0.11144301 ETH | ||||
12720752 | 1276 days ago | 0.40902014 ETH | ||||
12720752 | 1276 days ago | 0.59097985 ETH | ||||
12720752 | 1276 days ago | 6.31343623 ETH | ||||
12720752 | 1276 days ago | 0.68656376 ETH | ||||
12720752 | 1276 days ago | 0.99197534 ETH | ||||
12720752 | 1276 days ago | 0.85802465 ETH | ||||
12720752 | 1276 days ago | 0.96357373 ETH | ||||
12720752 | 1276 days ago | 0.5574183 ETH | ||||
12720752 | 1276 days ago | 0.79086156 ETH | ||||
12720752 | 1276 days ago | 1.08214641 ETH | ||||
12720752 | 1276 days ago | 5.77298009 ETH | ||||
12720752 | 1276 days ago | 3.34450982 ETH | ||||
12720752 | 1276 days ago | 6.99547102 ETH | ||||
12720752 | 1276 days ago | 8.36988087 ETH | ||||
12720752 | 1276 days ago | 8.12327136 ETH | ||||
12720752 | 1276 days ago | 0.87672863 ETH | ||||
12720752 | 1276 days ago | 8.88483965 ETH |
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
EtherCollateralsUSD
Compiler Version
v0.5.16+commit.9c3226ce
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-09-24 */ /* ____ __ __ __ _ / __/__ __ ___ / /_ / / ___ / /_ (_)__ __ _\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ / /___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\ /___/ * Synthetix: EtherCollateralsUSD.sol * * Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/EtherCollateralsUSD.sol * Docs: https://docs.synthetix.io/contracts/EtherCollateralsUSD * * Contract Dependencies: * - IAddressResolver * - IEtherCollateralsUSD * - MixinResolver * - Owned * - Pausable * - ReentrancyGuard * Libraries: * - SafeDecimalMath * - SafeMath * * MIT License * =========== * * Copyright (c) 2020 Synthetix * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE */ pragma solidity ^0.5.16; // https://docs.synthetix.io/contracts/Owned contract Owned { address public owner; address public nominatedOwner; constructor(address _owner) public { require(_owner != address(0), "Owner address cannot be 0"); owner = _owner; emit OwnerChanged(address(0), _owner); } function nominateNewOwner(address _owner) external onlyOwner { nominatedOwner = _owner; emit OwnerNominated(_owner); } function acceptOwnership() external { require(msg.sender == nominatedOwner, "You must be nominated before you can accept ownership"); emit OwnerChanged(owner, nominatedOwner); owner = nominatedOwner; nominatedOwner = address(0); } modifier onlyOwner { _onlyOwner(); _; } function _onlyOwner() private view { require(msg.sender == owner, "Only the contract owner may perform this action"); } event OwnerNominated(address newOwner); event OwnerChanged(address oldOwner, address newOwner); } // Inheritance // https://docs.synthetix.io/contracts/Pausable contract Pausable is Owned { uint public lastPauseTime; bool public paused; constructor() internal { // This contract is abstract, and thus cannot be instantiated directly require(owner != address(0), "Owner must be set"); // Paused will be false, and lastPauseTime will be 0 upon initialisation } /** * @notice Change the paused state of the contract * @dev Only the contract owner may call this. */ function setPaused(bool _paused) external onlyOwner { // Ensure we're actually changing the state before we do anything if (_paused == paused) { return; } // Set our paused state. paused = _paused; // If applicable, set the last pause time. if (paused) { lastPauseTime = now; } // Let everyone know that our pause state has changed. emit PauseChanged(paused); } event PauseChanged(bool isPaused); modifier notPaused { require(!paused, "This action cannot be performed while the contract is paused"); _; } } /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the `nonReentrant` modifier * available, which can be aplied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. */ contract ReentrancyGuard { /// @dev counter to allow mutex lock with only one SSTORE operation uint256 private _guardCounter; constructor () internal { // The counter starts at one to prevent changing it from zero to a non-zero // value, which is a more expensive operation. _guardCounter = 1; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { _guardCounter += 1; uint256 localCounter = _guardCounter; _; require(localCounter == _guardCounter, "ReentrancyGuard: reentrant call"); } } interface IAddressResolver { function getAddress(bytes32 name) external view returns (address); function getSynth(bytes32 key) external view returns (address); function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address); } interface ISynth { // Views function currencyKey() external view returns (bytes32); function transferableSynths(address account) external view returns (uint); // Mutative functions function transferAndSettle(address to, uint value) external returns (bool); function transferFromAndSettle( address from, address to, uint value ) external returns (bool); // Restricted: used internally to Synthetix function burn(address account, uint amount) external; function issue(address account, uint amount) external; } interface IIssuer { // Views function anySynthOrSNXRateIsInvalid() external view returns (bool anyRateInvalid); function availableCurrencyKeys() external view returns (bytes32[] memory); function availableSynthCount() external view returns (uint); function availableSynths(uint index) external view returns (ISynth); function canBurnSynths(address account) external view returns (bool); function collateral(address account) external view returns (uint); function collateralisationRatio(address issuer) external view returns (uint); function collateralisationRatioAndAnyRatesInvalid(address _issuer) external view returns (uint cratio, bool anyRateIsInvalid); function debtBalanceOf(address issuer, bytes32 currencyKey) external view returns (uint debtBalance); function issuanceRatio() external view returns (uint); function lastIssueEvent(address account) external view returns (uint); function maxIssuableSynths(address issuer) external view returns (uint maxIssuable); function minimumStakeTime() external view returns (uint); function remainingIssuableSynths(address issuer) external view returns ( uint maxIssuable, uint alreadyIssued, uint totalSystemDebt ); function synths(bytes32 currencyKey) external view returns (ISynth); function synthsByAddress(address synthAddress) external view returns (bytes32); function totalIssuedSynths(bytes32 currencyKey, bool excludeEtherCollateral) external view returns (uint); function transferableSynthetixAndAnyRateIsInvalid(address account, uint balance) external view returns (uint transferable, bool anyRateIsInvalid); // Restricted: used internally to Synthetix function issueSynths(address from, uint amount) external; function issueSynthsOnBehalf( address issueFor, address from, uint amount ) external; function issueMaxSynths(address from) external; function issueMaxSynthsOnBehalf(address issueFor, address from) external; function burnSynths(address from, uint amount) external; function burnSynthsOnBehalf( address burnForAddress, address from, uint amount ) external; function burnSynthsToTarget(address from) external; function burnSynthsToTargetOnBehalf(address burnForAddress, address from) external; function liquidateDelinquentAccount( address account, uint susdAmount, address liquidator ) external returns (uint totalRedeemed, uint amountToLiquidate); } // Inheritance // https://docs.synthetix.io/contracts/AddressResolver contract AddressResolver is Owned, IAddressResolver { mapping(bytes32 => address) public repository; constructor(address _owner) public Owned(_owner) {} /* ========== MUTATIVE FUNCTIONS ========== */ function importAddresses(bytes32[] calldata names, address[] calldata destinations) external onlyOwner { require(names.length == destinations.length, "Input lengths must match"); for (uint i = 0; i < names.length; i++) { repository[names[i]] = destinations[i]; } } /* ========== VIEWS ========== */ function getAddress(bytes32 name) external view returns (address) { return repository[name]; } function requireAndGetAddress(bytes32 name, string calldata reason) external view returns (address) { address _foundAddress = repository[name]; require(_foundAddress != address(0), reason); return _foundAddress; } function getSynth(bytes32 key) external view returns (address) { IIssuer issuer = IIssuer(repository["Issuer"]); require(address(issuer) != address(0), "Cannot find Issuer address"); return address(issuer.synths(key)); } } // Inheritance // Internal references // https://docs.synthetix.io/contracts/MixinResolver contract MixinResolver is Owned { AddressResolver public resolver; mapping(bytes32 => address) private addressCache; bytes32[] public resolverAddressesRequired; uint public constant MAX_ADDRESSES_FROM_RESOLVER = 24; constructor(address _resolver, bytes32[MAX_ADDRESSES_FROM_RESOLVER] memory _addressesToCache) internal { // This contract is abstract, and thus cannot be instantiated directly require(owner != address(0), "Owner must be set"); for (uint i = 0; i < _addressesToCache.length; i++) { if (_addressesToCache[i] != bytes32(0)) { resolverAddressesRequired.push(_addressesToCache[i]); } else { // End early once an empty item is found - assumes there are no empty slots in // _addressesToCache break; } } resolver = AddressResolver(_resolver); // Do not sync the cache as addresses may not be in the resolver yet } /* ========== SETTERS ========== */ function setResolverAndSyncCache(AddressResolver _resolver) external onlyOwner { resolver = _resolver; for (uint i = 0; i < resolverAddressesRequired.length; i++) { bytes32 name = resolverAddressesRequired[i]; // Note: can only be invoked once the resolver has all the targets needed added addressCache[name] = resolver.requireAndGetAddress(name, "Resolver missing target"); } } /* ========== VIEWS ========== */ function requireAndGetAddress(bytes32 name, string memory reason) internal view returns (address) { address _foundAddress = addressCache[name]; require(_foundAddress != address(0), reason); return _foundAddress; } // Note: this could be made external in a utility contract if addressCache was made public // (used for deployment) function isResolverCached(AddressResolver _resolver) external view returns (bool) { if (resolver != _resolver) { return false; } // otherwise, check everything for (uint i = 0; i < resolverAddressesRequired.length; i++) { bytes32 name = resolverAddressesRequired[i]; // false if our cache is invalid or if the resolver doesn't have the required address if (resolver.getAddress(name) != addressCache[name] || addressCache[name] == address(0)) { return false; } } return true; } // Note: can be made external into a utility contract (used for deployment) function getResolverAddressesRequired() external view returns (bytes32[MAX_ADDRESSES_FROM_RESOLVER] memory addressesRequired) { for (uint i = 0; i < resolverAddressesRequired.length; i++) { addressesRequired[i] = resolverAddressesRequired[i]; } } /* ========== INTERNAL FUNCTIONS ========== */ function appendToAddressCache(bytes32 name) internal { resolverAddressesRequired.push(name); require(resolverAddressesRequired.length < MAX_ADDRESSES_FROM_RESOLVER, "Max resolver cache size met"); // Because this is designed to be called internally in constructors, we don't // check the address exists already in the resolver addressCache[name] = resolver.getAddress(name); } } interface IEtherCollateralsUSD { // Views function totalIssuedSynths() external view returns (uint256); function totalLoansCreated() external view returns (uint256); function totalOpenLoanCount() external view returns (uint256); // Mutative functions function openLoan(uint256 _loanAmount) external payable returns (uint256 loanID); function closeLoan(uint256 loanID) external; function liquidateUnclosedLoan(address _loanCreatorsAddress, uint256 _loanID) external; function depositCollateral(address account, uint256 loanID) external payable; function withdrawCollateral(uint256 loanID, uint256 withdrawAmount) external; function repayLoan( address _loanCreatorsAddress, uint256 _loanID, uint256 _repayAmount ) external; } /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); 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-solidity/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) { // Solidity only automatically asserts when dividing by 0 require(b > 0, "SafeMath: division by zero"); 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) { require(b != 0, "SafeMath: modulo by zero"); return a % b; } } // Libraries // https://docs.synthetix.io/contracts/SafeDecimalMath library SafeDecimalMath { using SafeMath for uint; /* Number of decimal places in the representations. */ uint8 public constant decimals = 18; uint8 public constant highPrecisionDecimals = 27; /* The number representing 1.0. */ uint public constant UNIT = 10**uint(decimals); /* The number representing 1.0 for higher fidelity numbers. */ uint public constant PRECISE_UNIT = 10**uint(highPrecisionDecimals); uint private constant UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR = 10**uint(highPrecisionDecimals - decimals); /** * @return Provides an interface to UNIT. */ function unit() external pure returns (uint) { return UNIT; } /** * @return Provides an interface to PRECISE_UNIT. */ function preciseUnit() external pure returns (uint) { return PRECISE_UNIT; } /** * @return The result of multiplying x and y, interpreting the operands as fixed-point * decimals. * * @dev A unit factor is divided out after the product of x and y is evaluated, * so that product must be less than 2**256. As this is an integer division, * the internal division always rounds down. This helps save on gas. Rounding * is more expensive on gas. */ function multiplyDecimal(uint x, uint y) internal pure returns (uint) { /* Divide by UNIT to remove the extra factor introduced by the product. */ return x.mul(y) / UNIT; } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of the specified precision unit. * * @dev The operands should be in the form of a the specified unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function _multiplyDecimalRound( uint x, uint y, uint precisionUnit ) private pure returns (uint) { /* Divide by UNIT to remove the extra factor introduced by the product. */ uint quotientTimesTen = x.mul(y) / (precisionUnit / 10); if (quotientTimesTen % 10 >= 5) { quotientTimesTen += 10; } return quotientTimesTen / 10; } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of a precise unit. * * @dev The operands should be in the precise unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function multiplyDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) { return _multiplyDecimalRound(x, y, PRECISE_UNIT); } /** * @return The result of safely multiplying x and y, interpreting the operands * as fixed-point decimals of a standard unit. * * @dev The operands should be in the standard unit factor which will be * divided out after the product of x and y is evaluated, so that product must be * less than 2**256. * * Unlike multiplyDecimal, this function rounds the result to the nearest increment. * Rounding is useful when you need to retain fidelity for small decimal numbers * (eg. small fractions or percentages). */ function multiplyDecimalRound(uint x, uint y) internal pure returns (uint) { return _multiplyDecimalRound(x, y, UNIT); } /** * @return The result of safely dividing x and y. The return value is a high * precision decimal. * * @dev y is divided after the product of x and the standard precision unit * is evaluated, so the product of x and UNIT must be less than 2**256. As * this is an integer division, the result is always rounded down. * This helps save on gas. Rounding is more expensive on gas. */ function divideDecimal(uint x, uint y) internal pure returns (uint) { /* Reintroduce the UNIT factor that will be divided out by y. */ return x.mul(UNIT).div(y); } /** * @return The result of safely dividing x and y. The return value is as a rounded * decimal in the precision unit specified in the parameter. * * @dev y is divided after the product of x and the specified precision unit * is evaluated, so the product of x and the specified precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function _divideDecimalRound( uint x, uint y, uint precisionUnit ) private pure returns (uint) { uint resultTimesTen = x.mul(precisionUnit * 10).div(y); if (resultTimesTen % 10 >= 5) { resultTimesTen += 10; } return resultTimesTen / 10; } /** * @return The result of safely dividing x and y. The return value is as a rounded * standard precision decimal. * * @dev y is divided after the product of x and the standard precision unit * is evaluated, so the product of x and the standard precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function divideDecimalRound(uint x, uint y) internal pure returns (uint) { return _divideDecimalRound(x, y, UNIT); } /** * @return The result of safely dividing x and y. The return value is as a rounded * high precision decimal. * * @dev y is divided after the product of x and the high precision unit * is evaluated, so the product of x and the high precision unit must * be less than 2**256. The result is rounded to the nearest increment. */ function divideDecimalRoundPrecise(uint x, uint y) internal pure returns (uint) { return _divideDecimalRound(x, y, PRECISE_UNIT); } /** * @dev Convert a standard decimal representation to a high precision one. */ function decimalToPreciseDecimal(uint i) internal pure returns (uint) { return i.mul(UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR); } /** * @dev Convert a high precision decimal to a standard decimal representation. */ function preciseDecimalToDecimal(uint i) internal pure returns (uint) { uint quotientTimesTen = i / (UNIT_TO_HIGH_PRECISION_CONVERSION_FACTOR / 10); if (quotientTimesTen % 10 >= 5) { quotientTimesTen += 10; } return quotientTimesTen / 10; } } interface ISystemStatus { struct Status { bool canSuspend; bool canResume; } struct Suspension { bool suspended; // reason is an integer code, // 0 => no reason, 1 => upgrading, 2+ => defined by system usage uint248 reason; } // Views function accessControl(bytes32 section, address account) external view returns (bool canSuspend, bool canResume); function requireSystemActive() external view; function requireIssuanceActive() external view; function requireExchangeActive() external view; function requireSynthActive(bytes32 currencyKey) external view; function requireSynthsActive(bytes32 sourceCurrencyKey, bytes32 destinationCurrencyKey) external view; function synthSuspension(bytes32 currencyKey) external view returns (bool suspended, uint248 reason); // Restricted functions function suspendSynth(bytes32 currencyKey, uint256 reason) external; function updateAccessControl( bytes32 section, address account, bool canSuspend, bool canResume ) external; } interface IFeePool { // Views // solhint-disable-next-line func-name-mixedcase function FEE_ADDRESS() external view returns (address); function feesAvailable(address account) external view returns (uint, uint); function feePeriodDuration() external view returns (uint); function isFeesClaimable(address account) external view returns (bool); function targetThreshold() external view returns (uint); function totalFeesAvailable() external view returns (uint); function totalRewardsAvailable() external view returns (uint); // Mutative Functions function claimFees() external returns (bool); function claimOnBehalf(address claimingForAddress) external returns (bool); function closeCurrentFeePeriod() external; // Restricted: used internally to Synthetix function appendAccountIssuanceRecord( address account, uint lockedAmount, uint debtEntryIndex ) external; function recordFeePaid(uint sUSDAmount) external; function setRewardsToDistribute(uint amount) external; } interface IERC20 { // ERC20 Optional Views function name() external view returns (string memory); function symbol() external view returns (string memory); function decimals() external view returns (uint8); // Views function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); // Mutative functions function transfer(address to, uint value) external returns (bool); function approve(address spender, uint value) external returns (bool); function transferFrom( address from, address to, uint value ) external returns (bool); // Events event Transfer(address indexed from, address indexed to, uint value); event Approval(address indexed owner, address indexed spender, uint value); } // https://docs.synthetix.io/contracts/source/interfaces/IExchangeRates interface IExchangeRates { // Structs struct RateAndUpdatedTime { uint216 rate; uint40 time; } struct InversePricing { uint entryPoint; uint upperLimit; uint lowerLimit; bool frozenAtUpperLimit; bool frozenAtLowerLimit; } // Views function aggregators(bytes32 currencyKey) external view returns (address); function aggregatorWarningFlags() external view returns (address); function anyRateIsInvalid(bytes32[] calldata currencyKeys) external view returns (bool); function canFreezeRate(bytes32 currencyKey) external view returns (bool); function currentRoundForRate(bytes32 currencyKey) external view returns (uint); function currenciesUsingAggregator(address aggregator) external view returns (bytes32[] memory); function effectiveValue( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external view returns (uint value); function effectiveValueAndRates( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey ) external view returns ( uint value, uint sourceRate, uint destinationRate ); function effectiveValueAtRound( bytes32 sourceCurrencyKey, uint sourceAmount, bytes32 destinationCurrencyKey, uint roundIdForSrc, uint roundIdForDest ) external view returns (uint value); function getCurrentRoundId(bytes32 currencyKey) external view returns (uint); function getLastRoundIdBeforeElapsedSecs( bytes32 currencyKey, uint startingRoundId, uint startingTimestamp, uint timediff ) external view returns (uint); function inversePricing(bytes32 currencyKey) external view returns ( uint entryPoint, uint upperLimit, uint lowerLimit, bool frozenAtUpperLimit, bool frozenAtLowerLimit ); function lastRateUpdateTimes(bytes32 currencyKey) external view returns (uint256); function oracle() external view returns (address); function rateAndTimestampAtRound(bytes32 currencyKey, uint roundId) external view returns (uint rate, uint time); function rateAndUpdatedTime(bytes32 currencyKey) external view returns (uint rate, uint time); function rateForCurrency(bytes32 currencyKey) external view returns (uint); function rateIsFlagged(bytes32 currencyKey) external view returns (bool); function rateIsFrozen(bytes32 currencyKey) external view returns (bool); function rateIsInvalid(bytes32 currencyKey) external view returns (bool); function rateIsStale(bytes32 currencyKey) external view returns (bool); function rateStalePeriod() external view returns (uint); function ratesAndUpdatedTimeForCurrencyLastNRounds(bytes32 currencyKey, uint numRounds) external view returns (uint[] memory rates, uint[] memory times); function ratesAndInvalidForCurrencies(bytes32[] calldata currencyKeys) external view returns (uint[] memory rates, bool anyRateInvalid); function ratesForCurrencies(bytes32[] calldata currencyKeys) external view returns (uint[] memory); // Mutative functions function freezeRate(bytes32 currencyKey) external; } // Inheritance // Libraries // Internal references // ETH Collateral v0.3 (sUSD) // https://docs.synthetix.io/contracts/EtherCollateralsUSD contract EtherCollateralsUSD is Owned, Pausable, ReentrancyGuard, MixinResolver, IEtherCollateralsUSD { using SafeMath for uint256; using SafeDecimalMath for uint256; bytes32 internal constant ETH = "ETH"; // ========== CONSTANTS ========== uint256 internal constant ONE_THOUSAND = 1e18 * 1000; uint256 internal constant ONE_HUNDRED = 1e18 * 100; uint256 internal constant SECONDS_IN_A_YEAR = 31536000; // Common Year // Where fees are pooled in sUSD. address internal constant FEE_ADDRESS = 0xfeEFEEfeefEeFeefEEFEEfEeFeefEEFeeFEEFEeF; uint256 internal constant ACCOUNT_LOAN_LIMIT_CAP = 1000; bytes32 private constant sUSD = "sUSD"; bytes32 public constant COLLATERAL = "ETH"; // ========== SETTER STATE VARIABLES ========== // The ratio of Collateral to synths issued uint256 public collateralizationRatio = SafeDecimalMath.unit() * 150; // If updated, all outstanding loans will pay this interest rate in on closure of the loan. Default 5% uint256 public interestRate = (5 * SafeDecimalMath.unit()) / 100; uint256 public interestPerSecond = interestRate.div(SECONDS_IN_A_YEAR); // Minting fee for issuing the synths. Default 50 bips. uint256 public issueFeeRate = (5 * SafeDecimalMath.unit()) / 1000; // Maximum amount of sUSD that can be issued by the EtherCollateral contract. Default 10MM uint256 public issueLimit = SafeDecimalMath.unit() * 10000000; // Minimum amount of ETH to create loan preventing griefing and gas consumption. Min 1ETH uint256 public minLoanCollateralSize = SafeDecimalMath.unit() * 1; // Maximum number of loans an account can create uint256 public accountLoanLimit = 50; // If true then any wallet addres can close a loan not just the loan creator. bool public loanLiquidationOpen = false; // Time when remaining loans can be liquidated uint256 public liquidationDeadline; // Liquidation ratio when loans can be liquidated uint256 public liquidationRatio = (150 * SafeDecimalMath.unit()) / 100; // 1.5 ratio // Liquidation penalty when loans are liquidated. default 10% uint256 public liquidationPenalty = SafeDecimalMath.unit() / 10; // ========== STATE VARIABLES ========== // The total number of synths issued by the collateral in this contract uint256 public totalIssuedSynths; // Total number of loans ever created uint256 public totalLoansCreated; // Total number of open loans uint256 public totalOpenLoanCount; // Synth loan storage struct struct SynthLoanStruct { // Acccount that created the loan address payable account; // Amount (in collateral token ) that they deposited uint256 collateralAmount; // Amount (in synths) that they issued to borrow uint256 loanAmount; // Minting Fee uint256 mintingFee; // When the loan was created uint256 timeCreated; // ID for the loan uint256 loanID; // When the loan was paidback (closed) uint256 timeClosed; // Applicable Interest rate uint256 loanInterestRate; // interest amounts accrued uint256 accruedInterest; // last timestamp interest amounts accrued uint40 lastInterestAccrued; } // Users Loans by address mapping(address => SynthLoanStruct[]) public accountsSynthLoans; // Account Open Loan Counter mapping(address => uint256) public accountOpenLoanCounter; /* ========== ADDRESS RESOLVER CONFIGURATION ========== */ bytes32 private constant CONTRACT_SYSTEMSTATUS = "SystemStatus"; bytes32 private constant CONTRACT_SYNTHSUSD = "SynthsUSD"; bytes32 private constant CONTRACT_EXRATES = "ExchangeRates"; bytes32 private constant CONTRACT_FEEPOOL = "FeePool"; bytes32[24] private addressesToCache = [CONTRACT_SYSTEMSTATUS, CONTRACT_SYNTHSUSD, CONTRACT_EXRATES, CONTRACT_FEEPOOL]; // ========== CONSTRUCTOR ========== constructor(address _owner, address _resolver) public Owned(_owner) Pausable() MixinResolver(_resolver, addressesToCache) { liquidationDeadline = block.timestamp + 92 days; // Time before loans can be open for liquidation to end the trial contract } // ========== SETTERS ========== function setCollateralizationRatio(uint256 ratio) external onlyOwner { require(ratio <= ONE_THOUSAND, "Too high"); require(ratio >= ONE_HUNDRED, "Too low"); collateralizationRatio = ratio; emit CollateralizationRatioUpdated(ratio); } function setInterestRate(uint256 _interestRate) external onlyOwner { require(_interestRate > SECONDS_IN_A_YEAR, "Interest rate cannot be less that the SECONDS_IN_A_YEAR"); require(_interestRate <= SafeDecimalMath.unit(), "Interest cannot be more than 100% APR"); interestRate = _interestRate; interestPerSecond = _interestRate.div(SECONDS_IN_A_YEAR); emit InterestRateUpdated(interestRate); } function setIssueFeeRate(uint256 _issueFeeRate) external onlyOwner { issueFeeRate = _issueFeeRate; emit IssueFeeRateUpdated(issueFeeRate); } function setIssueLimit(uint256 _issueLimit) external onlyOwner { issueLimit = _issueLimit; emit IssueLimitUpdated(issueLimit); } function setMinLoanCollateralSize(uint256 _minLoanCollateralSize) external onlyOwner { minLoanCollateralSize = _minLoanCollateralSize; emit MinLoanCollateralSizeUpdated(minLoanCollateralSize); } function setAccountLoanLimit(uint256 _loanLimit) external onlyOwner { require(_loanLimit < ACCOUNT_LOAN_LIMIT_CAP, "Owner cannot set higher than ACCOUNT_LOAN_LIMIT_CAP"); accountLoanLimit = _loanLimit; emit AccountLoanLimitUpdated(accountLoanLimit); } function setLoanLiquidationOpen(bool _loanLiquidationOpen) external onlyOwner { require(block.timestamp > liquidationDeadline, "Before liquidation deadline"); loanLiquidationOpen = _loanLiquidationOpen; emit LoanLiquidationOpenUpdated(loanLiquidationOpen); } function setLiquidationRatio(uint256 _liquidationRatio) external onlyOwner { require(_liquidationRatio > SafeDecimalMath.unit(), "Ratio less than 100%"); liquidationRatio = _liquidationRatio; emit LiquidationRatioUpdated(liquidationRatio); } // ========== PUBLIC VIEWS ========== function getContractInfo() external view returns ( uint256 _collateralizationRatio, uint256 _issuanceRatio, uint256 _interestRate, uint256 _interestPerSecond, uint256 _issueFeeRate, uint256 _issueLimit, uint256 _minLoanCollateralSize, uint256 _totalIssuedSynths, uint256 _totalLoansCreated, uint256 _totalOpenLoanCount, uint256 _ethBalance, uint256 _liquidationDeadline, bool _loanLiquidationOpen ) { _collateralizationRatio = collateralizationRatio; _issuanceRatio = issuanceRatio(); _interestRate = interestRate; _interestPerSecond = interestPerSecond; _issueFeeRate = issueFeeRate; _issueLimit = issueLimit; _minLoanCollateralSize = minLoanCollateralSize; _totalIssuedSynths = totalIssuedSynths; _totalLoansCreated = totalLoansCreated; _totalOpenLoanCount = totalOpenLoanCount; _ethBalance = address(this).balance; _liquidationDeadline = liquidationDeadline; _loanLiquidationOpen = loanLiquidationOpen; } // returns value of 100 / collateralizationRatio. // e.g. 100/150 = 0.6666666667 function issuanceRatio() public view returns (uint256) { // this rounds so you get slightly more rather than slightly less return ONE_HUNDRED.divideDecimalRound(collateralizationRatio); } function loanAmountFromCollateral(uint256 collateralAmount) public view returns (uint256) { // a fraction more is issued due to rounding return collateralAmount.multiplyDecimal(issuanceRatio()).multiplyDecimal(exchangeRates().rateForCurrency(ETH)); } function collateralAmountForLoan(uint256 loanAmount) external view returns (uint256) { return loanAmount .multiplyDecimal(collateralizationRatio.divideDecimalRound(exchangeRates().rateForCurrency(ETH))) .divideDecimalRound(ONE_HUNDRED); } // compound accrued interest with remaining loanAmount * (now - lastTimestampInterestPaid) function currentInterestOnLoan(address _account, uint256 _loanID) external view returns (uint256) { // Get the loan from storage SynthLoanStruct memory synthLoan = _getLoanFromStorage(_account, _loanID); uint256 currentInterest = accruedInterestOnLoan( synthLoan.loanAmount.add(synthLoan.accruedInterest), _timeSinceInterestAccrual(synthLoan) ); return synthLoan.accruedInterest.add(currentInterest); } function accruedInterestOnLoan(uint256 _loanAmount, uint256 _seconds) public view returns (uint256 interestAmount) { // Simple interest calculated per second // Interest = Principal * rate * time interestAmount = _loanAmount.multiplyDecimalRound(interestPerSecond.mul(_seconds)); } function totalFeesOnLoan(address _account, uint256 _loanID) external view returns (uint256 interestAmount, uint256 mintingFee) { SynthLoanStruct memory synthLoan = _getLoanFromStorage(_account, _loanID); uint256 loanAmountWithAccruedInterest = synthLoan.loanAmount.add(synthLoan.accruedInterest); interestAmount = synthLoan.accruedInterest.add( accruedInterestOnLoan(loanAmountWithAccruedInterest, _timeSinceInterestAccrual(synthLoan)) ); mintingFee = synthLoan.mintingFee; } function getMintingFee(address _account, uint256 _loanID) external view returns (uint256) { // Get the loan from storage SynthLoanStruct memory synthLoan = _getLoanFromStorage(_account, _loanID); return synthLoan.mintingFee; } /** * r = target issuance ratio * D = debt balance * V = Collateral * P = liquidation penalty * Calculates amount of synths = (D - V * r) / (1 - (1 + P) * r) */ function calculateAmountToLiquidate(uint debtBalance, uint collateral) public view returns (uint) { uint unit = SafeDecimalMath.unit(); uint ratio = liquidationRatio; uint dividend = debtBalance.sub(collateral.divideDecimal(ratio)); uint divisor = unit.sub(unit.add(liquidationPenalty).divideDecimal(ratio)); return dividend.divideDecimal(divisor); } function openLoanIDsByAccount(address _account) external view returns (uint256[] memory) { SynthLoanStruct[] memory synthLoans = accountsSynthLoans[_account]; uint256[] memory _openLoanIDs = new uint256[](synthLoans.length); uint256 _counter = 0; for (uint256 i = 0; i < synthLoans.length; i++) { if (synthLoans[i].timeClosed == 0) { _openLoanIDs[_counter] = synthLoans[i].loanID; _counter++; } } // Create the fixed size array to return uint256[] memory _result = new uint256[](_counter); // Copy loanIDs from dynamic array to fixed array for (uint256 j = 0; j < _counter; j++) { _result[j] = _openLoanIDs[j]; } // Return an array with list of open Loan IDs return _result; } function getLoan(address _account, uint256 _loanID) external view returns ( address account, uint256 collateralAmount, uint256 loanAmount, uint256 timeCreated, uint256 loanID, uint256 timeClosed, uint256 accruedInterest, uint256 totalFees ) { SynthLoanStruct memory synthLoan = _getLoanFromStorage(_account, _loanID); account = synthLoan.account; collateralAmount = synthLoan.collateralAmount; loanAmount = synthLoan.loanAmount; timeCreated = synthLoan.timeCreated; loanID = synthLoan.loanID; timeClosed = synthLoan.timeClosed; accruedInterest = synthLoan.accruedInterest.add( accruedInterestOnLoan(synthLoan.loanAmount.add(synthLoan.accruedInterest), _timeSinceInterestAccrual(synthLoan)) ); totalFees = accruedInterest.add(synthLoan.mintingFee); } function getLoanCollateralRatio(address _account, uint256 _loanID) external view returns (uint256 loanCollateralRatio) { // Get the loan from storage SynthLoanStruct memory synthLoan = _getLoanFromStorage(_account, _loanID); (loanCollateralRatio, , ) = _loanCollateralRatio(synthLoan); } function _loanCollateralRatio(SynthLoanStruct memory _loan) internal view returns ( uint256 loanCollateralRatio, uint256 collateralValue, uint256 interestAmount ) { // Any interest accrued prior is rolled up into loan amount uint256 loanAmountWithAccruedInterest = _loan.loanAmount.add(_loan.accruedInterest); interestAmount = accruedInterestOnLoan(loanAmountWithAccruedInterest, _timeSinceInterestAccrual(_loan)); collateralValue = _loan.collateralAmount.multiplyDecimal(exchangeRates().rateForCurrency(COLLATERAL)); loanCollateralRatio = collateralValue.divideDecimal(loanAmountWithAccruedInterest.add(interestAmount)); } function timeSinceInterestAccrualOnLoan(address _account, uint256 _loanID) external view returns (uint256) { // Get the loan from storage SynthLoanStruct memory synthLoan = _getLoanFromStorage(_account, _loanID); return _timeSinceInterestAccrual(synthLoan); } // ========== PUBLIC FUNCTIONS ========== function openLoan(uint256 _loanAmount) external payable notPaused nonReentrant ETHRateNotInvalid returns (uint256 loanID) { systemStatus().requireIssuanceActive(); // Require ETH sent to be greater than minLoanCollateralSize require( msg.value >= minLoanCollateralSize, "Not enough ETH to create this loan. Please see the minLoanCollateralSize" ); // Require loanLiquidationOpen to be false or we are in liquidation phase require(loanLiquidationOpen == false, "Loans are now being liquidated"); // Each account is limited to creating 50 (accountLoanLimit) loans require(accountsSynthLoans[msg.sender].length < accountLoanLimit, "Each account is limited to 50 loans"); // Calculate issuance amount based on issuance ratio uint256 maxLoanAmount = loanAmountFromCollateral(msg.value); // Require requested _loanAmount to be less than maxLoanAmount // Issuance ratio caps collateral to loan value at 150% require(_loanAmount <= maxLoanAmount, "Loan amount exceeds max borrowing power"); uint256 mintingFee = _calculateMintingFee(_loanAmount); uint256 loanAmountMinusFee = _loanAmount.sub(mintingFee); // Require sUSD loan to mint does not exceed cap require(totalIssuedSynths.add(_loanAmount) <= issueLimit, "Loan Amount exceeds the supply cap."); // Get a Loan ID loanID = _incrementTotalLoansCounter(); // Create Loan storage object SynthLoanStruct memory synthLoan = SynthLoanStruct({ account: msg.sender, collateralAmount: msg.value, loanAmount: _loanAmount, mintingFee: mintingFee, timeCreated: block.timestamp, loanID: loanID, timeClosed: 0, loanInterestRate: interestRate, accruedInterest: 0, lastInterestAccrued: 0 }); // Fee distribution. Mint the sUSD fees into the FeePool and record fees paid if (mintingFee > 0) { synthsUSD().issue(FEE_ADDRESS, mintingFee); feePool().recordFeePaid(mintingFee); } // Record loan in mapping to account in an array of the accounts open loans accountsSynthLoans[msg.sender].push(synthLoan); // Increment totalIssuedSynths totalIssuedSynths = totalIssuedSynths.add(_loanAmount); // Issue the synth (less fee) synthsUSD().issue(msg.sender, loanAmountMinusFee); // Tell the Dapps a loan was created emit LoanCreated(msg.sender, loanID, _loanAmount); } function closeLoan(uint256 loanID) external nonReentrant ETHRateNotInvalid { _closeLoan(msg.sender, loanID, false); } // Add ETH collateral to an open loan function depositCollateral(address account, uint256 loanID) external payable notPaused { require(msg.value > 0, "Deposit amount must be greater than 0"); systemStatus().requireIssuanceActive(); // Require loanLiquidationOpen to be false or we are in liquidation phase require(loanLiquidationOpen == false, "Loans are now being liquidated"); // Get the loan from storage SynthLoanStruct memory synthLoan = _getLoanFromStorage(account, loanID); // Check loan exists and is open _checkLoanIsOpen(synthLoan); uint256 totalCollateral = synthLoan.collateralAmount.add(msg.value); _updateLoanCollateral(synthLoan, totalCollateral); // Tell the Dapps collateral was added to loan emit CollateralDeposited(account, loanID, msg.value, totalCollateral); } // Withdraw ETH collateral from an open loan function withdrawCollateral(uint256 loanID, uint256 withdrawAmount) external notPaused nonReentrant ETHRateNotInvalid { require(withdrawAmount > 0, "Amount to withdraw must be greater than 0"); systemStatus().requireIssuanceActive(); // Require loanLiquidationOpen to be false or we are in liquidation phase require(loanLiquidationOpen == false, "Loans are now being liquidated"); // Get the loan from storage SynthLoanStruct memory synthLoan = _getLoanFromStorage(msg.sender, loanID); // Check loan exists and is open _checkLoanIsOpen(synthLoan); uint256 collateralAfter = synthLoan.collateralAmount.sub(withdrawAmount); SynthLoanStruct memory loanAfter = _updateLoanCollateral(synthLoan, collateralAfter); // require collateral ratio after to be above the liquidation ratio (uint256 collateralRatioAfter, , ) = _loanCollateralRatio(loanAfter); require(collateralRatioAfter > liquidationRatio, "Collateral ratio below liquidation after withdraw"); // transfer ETH to msg.sender msg.sender.transfer(withdrawAmount); // Tell the Dapps collateral was added to loan emit CollateralWithdrawn(msg.sender, loanID, withdrawAmount, loanAfter.collateralAmount); } function repayLoan( address _loanCreatorsAddress, uint256 _loanID, uint256 _repayAmount ) external ETHRateNotInvalid { systemStatus().requireSystemActive(); // check msg.sender has sufficient sUSD to pay require(IERC20(address(synthsUSD())).balanceOf(msg.sender) >= _repayAmount, "Not enough sUSD balance"); SynthLoanStruct memory synthLoan = _getLoanFromStorage(_loanCreatorsAddress, _loanID); // Check loan exists and is open _checkLoanIsOpen(synthLoan); // Any interest accrued prior is rolled up into loan amount uint256 loanAmountWithAccruedInterest = synthLoan.loanAmount.add(synthLoan.accruedInterest); uint256 interestAmount = accruedInterestOnLoan(loanAmountWithAccruedInterest, _timeSinceInterestAccrual(synthLoan)); // repay any accrued interests first // and repay principal loan amount with remaining amounts uint256 accruedInterest = synthLoan.accruedInterest.add(interestAmount); ( uint256 interestPaid, uint256 loanAmountPaid, uint256 accruedInterestAfter, uint256 loanAmountAfter ) = _splitInterestLoanPayment(_repayAmount, accruedInterest, synthLoan.loanAmount); // burn sUSD from msg.sender for repaid amount synthsUSD().burn(msg.sender, _repayAmount); // Send interest paid to fee pool and record loan amount paid _processInterestAndLoanPayment(interestPaid, loanAmountPaid); // update loan with new total loan amount, record accrued interests _updateLoan(synthLoan, loanAmountAfter, accruedInterestAfter, block.timestamp); emit LoanRepaid(_loanCreatorsAddress, _loanID, _repayAmount, loanAmountAfter); } // Liquidate loans at or below issuance ratio function liquidateLoan( address _loanCreatorsAddress, uint256 _loanID, uint256 _debtToCover ) external nonReentrant ETHRateNotInvalid { systemStatus().requireSystemActive(); // check msg.sender (liquidator's wallet) has sufficient sUSD require(IERC20(address(synthsUSD())).balanceOf(msg.sender) >= _debtToCover, "Not enough sUSD balance"); SynthLoanStruct memory synthLoan = _getLoanFromStorage(_loanCreatorsAddress, _loanID); // Check loan exists and is open _checkLoanIsOpen(synthLoan); (uint256 collateralRatio, uint256 collateralValue, uint256 interestAmount) = _loanCollateralRatio(synthLoan); require(collateralRatio < liquidationRatio, "Collateral ratio above liquidation ratio"); // calculate amount to liquidate to fix ratio including accrued interest uint256 liquidationAmount = calculateAmountToLiquidate( synthLoan.loanAmount.add(synthLoan.accruedInterest).add(interestAmount), collateralValue ); // cap debt to liquidate uint256 amountToLiquidate = liquidationAmount < _debtToCover ? liquidationAmount : _debtToCover; // burn sUSD from msg.sender for amount to liquidate synthsUSD().burn(msg.sender, amountToLiquidate); (uint256 interestPaid, uint256 loanAmountPaid, uint256 accruedInterestAfter, ) = _splitInterestLoanPayment( amountToLiquidate, synthLoan.accruedInterest.add(interestAmount), synthLoan.loanAmount ); // Send interests paid to fee pool and record loan amount paid _processInterestAndLoanPayment(interestPaid, loanAmountPaid); // Collateral value to redeem uint256 collateralRedeemed = exchangeRates().effectiveValue(sUSD, amountToLiquidate, COLLATERAL); // Add penalty uint256 totalCollateralLiquidated = collateralRedeemed.multiplyDecimal( SafeDecimalMath.unit().add(liquidationPenalty) ); // update remaining loanAmount less amount paid and update accrued interests less interest paid _updateLoan(synthLoan, synthLoan.loanAmount.sub(loanAmountPaid), accruedInterestAfter, block.timestamp); // update remaining collateral on loan _updateLoanCollateral(synthLoan, synthLoan.collateralAmount.sub(totalCollateralLiquidated)); // Send liquidated ETH collateral to msg.sender msg.sender.transfer(totalCollateralLiquidated); // emit loan liquidation event emit LoanPartiallyLiquidated( _loanCreatorsAddress, _loanID, msg.sender, amountToLiquidate, totalCollateralLiquidated ); } function _splitInterestLoanPayment( uint256 _paymentAmount, uint256 _accruedInterest, uint256 _loanAmount ) internal pure returns ( uint256 interestPaid, uint256 loanAmountPaid, uint256 accruedInterestAfter, uint256 loanAmountAfter ) { uint256 remainingPayment = _paymentAmount; // repay any accrued interests first accruedInterestAfter = _accruedInterest; if (remainingPayment > 0 && _accruedInterest > 0) { // Max repay is the accruedInterest amount interestPaid = remainingPayment > _accruedInterest ? _accruedInterest : remainingPayment; accruedInterestAfter = accruedInterestAfter.sub(interestPaid); remainingPayment = remainingPayment.sub(interestPaid); } // Remaining amounts - pay down loan amount loanAmountAfter = _loanAmount; if (remainingPayment > 0) { loanAmountAfter = loanAmountAfter.sub(remainingPayment); loanAmountPaid = remainingPayment; } } function _processInterestAndLoanPayment(uint256 interestPaid, uint256 loanAmountPaid) internal { // Fee distribution. Mint the sUSD fees into the FeePool and record fees paid if (interestPaid > 0) { synthsUSD().issue(FEE_ADDRESS, interestPaid); feePool().recordFeePaid(interestPaid); } // Decrement totalIssuedSynths if (loanAmountPaid > 0) { totalIssuedSynths = totalIssuedSynths.sub(loanAmountPaid); } } // Liquidation of an open loan available for anyone function liquidateUnclosedLoan(address _loanCreatorsAddress, uint256 _loanID) external nonReentrant ETHRateNotInvalid { require(loanLiquidationOpen, "Liquidation is not open"); // Close the creators loan and send collateral to the closer. _closeLoan(_loanCreatorsAddress, _loanID, true); // Tell the Dapps this loan was liquidated emit LoanLiquidated(_loanCreatorsAddress, _loanID, msg.sender); } // ========== PRIVATE FUNCTIONS ========== function _closeLoan( address account, uint256 loanID, bool liquidation ) private { systemStatus().requireIssuanceActive(); // Get the loan from storage SynthLoanStruct memory synthLoan = _getLoanFromStorage(account, loanID); // Check loan exists and is open _checkLoanIsOpen(synthLoan); // Calculate and deduct accrued interest (5%) for fee pool // Accrued interests (captured in loanAmount) + new interests uint256 interestAmount = accruedInterestOnLoan( synthLoan.loanAmount.add(synthLoan.accruedInterest), _timeSinceInterestAccrual(synthLoan) ); uint256 repayAmount = synthLoan.loanAmount.add(interestAmount); uint256 totalAccruedInterest = synthLoan.accruedInterest.add(interestAmount); require( IERC20(address(synthsUSD())).balanceOf(msg.sender) >= repayAmount, "You do not have the required Synth balance to close this loan." ); // Record loan as closed _recordLoanClosure(synthLoan); // Decrement totalIssuedSynths // subtract the accrued interest from the loanAmount totalIssuedSynths = totalIssuedSynths.sub(synthLoan.loanAmount.sub(synthLoan.accruedInterest)); // Burn all Synths issued for the loan + the fees synthsUSD().burn(msg.sender, repayAmount); // Fee distribution. Mint the sUSD fees into the FeePool and record fees paid synthsUSD().issue(FEE_ADDRESS, totalAccruedInterest); feePool().recordFeePaid(totalAccruedInterest); uint256 remainingCollateral = synthLoan.collateralAmount; if (liquidation) { // Send liquidator redeemed collateral + 10% penalty uint256 collateralRedeemed = exchangeRates().effectiveValue(sUSD, repayAmount, COLLATERAL); // add penalty uint256 totalCollateralLiquidated = collateralRedeemed.multiplyDecimal( SafeDecimalMath.unit().add(liquidationPenalty) ); // ensure remaining ETH collateral sufficient to cover collateral liquidated // will revert if the liquidated collateral + penalty is more than remaining collateral remainingCollateral = remainingCollateral.sub(totalCollateralLiquidated); // Send liquidator CollateralLiquidated msg.sender.transfer(totalCollateralLiquidated); } // Send remaining collateral to loan creator synthLoan.account.transfer(remainingCollateral); // Tell the Dapps emit LoanClosed(account, loanID, totalAccruedInterest); } function _getLoanFromStorage(address account, uint256 loanID) private view returns (SynthLoanStruct memory) { SynthLoanStruct[] memory synthLoans = accountsSynthLoans[account]; for (uint256 i = 0; i < synthLoans.length; i++) { if (synthLoans[i].loanID == loanID) { return synthLoans[i]; } } } function _updateLoan( SynthLoanStruct memory _synthLoan, uint256 _newLoanAmount, uint256 _newAccruedInterest, uint256 _lastInterestAccrued ) private { // Get storage pointer to the accounts array of loans SynthLoanStruct[] storage synthLoans = accountsSynthLoans[_synthLoan.account]; for (uint256 i = 0; i < synthLoans.length; i++) { if (synthLoans[i].loanID == _synthLoan.loanID) { synthLoans[i].loanAmount = _newLoanAmount; synthLoans[i].accruedInterest = _newAccruedInterest; synthLoans[i].lastInterestAccrued = uint40(_lastInterestAccrued); } } } function _updateLoanCollateral(SynthLoanStruct memory _synthLoan, uint256 _newCollateralAmount) private returns (SynthLoanStruct memory) { // Get storage pointer to the accounts array of loans SynthLoanStruct[] storage synthLoans = accountsSynthLoans[_synthLoan.account]; for (uint256 i = 0; i < synthLoans.length; i++) { if (synthLoans[i].loanID == _synthLoan.loanID) { synthLoans[i].collateralAmount = _newCollateralAmount; return synthLoans[i]; } } } function _recordLoanClosure(SynthLoanStruct memory synthLoan) private { // Get storage pointer to the accounts array of loans SynthLoanStruct[] storage synthLoans = accountsSynthLoans[synthLoan.account]; for (uint256 i = 0; i < synthLoans.length; i++) { if (synthLoans[i].loanID == synthLoan.loanID) { // Record the time the loan was closed synthLoans[i].timeClosed = block.timestamp; } } // Reduce Total Open Loans Count totalOpenLoanCount = totalOpenLoanCount.sub(1); } function _incrementTotalLoansCounter() private returns (uint256) { // Increase the total Open loan count totalOpenLoanCount = totalOpenLoanCount.add(1); // Increase the total Loans Created count totalLoansCreated = totalLoansCreated.add(1); // Return total count to be used as a unique ID. return totalLoansCreated; } function _calculateMintingFee(uint256 _loanAmount) private view returns (uint256 mintingFee) { mintingFee = _loanAmount.multiplyDecimalRound(issueFeeRate); } function _timeSinceInterestAccrual(SynthLoanStruct memory _synthLoan) private view returns (uint256 timeSinceAccrual) { // The last interest accrued timestamp for the loan // If lastInterestAccrued timestamp is not set (0), use loan timeCreated uint256 lastInterestAccrual = _synthLoan.lastInterestAccrued > 0 ? uint256(_synthLoan.lastInterestAccrued) : _synthLoan.timeCreated; // diff between last interested accrued and now // use loan's timeClosed if loan is closed timeSinceAccrual = _synthLoan.timeClosed > 0 ? _synthLoan.timeClosed.sub(lastInterestAccrual) : block.timestamp.sub(lastInterestAccrual); } function _checkLoanIsOpen(SynthLoanStruct memory _synthLoan) internal pure { require(_synthLoan.loanID > 0, "Loan does not exist"); require(_synthLoan.timeClosed == 0, "Loan already closed"); } /* ========== INTERNAL VIEWS ========== */ function systemStatus() internal view returns (ISystemStatus) { return ISystemStatus(requireAndGetAddress(CONTRACT_SYSTEMSTATUS, "Missing SystemStatus address")); } function synthsUSD() internal view returns (ISynth) { return ISynth(requireAndGetAddress(CONTRACT_SYNTHSUSD, "Missing SynthsUSD address")); } function exchangeRates() internal view returns (IExchangeRates) { return IExchangeRates(requireAndGetAddress(CONTRACT_EXRATES, "Missing ExchangeRates address")); } function feePool() internal view returns (IFeePool) { return IFeePool(requireAndGetAddress(CONTRACT_FEEPOOL, "Missing FeePool address")); } /* ========== MODIFIERS ========== */ modifier ETHRateNotInvalid() { require(!exchangeRates().rateIsInvalid(COLLATERAL), "Blocked as ETH rate is invalid"); _; } // ========== EVENTS ========== event CollateralizationRatioUpdated(uint256 ratio); event LiquidationRatioUpdated(uint256 ratio); event InterestRateUpdated(uint256 interestRate); event IssueFeeRateUpdated(uint256 issueFeeRate); event IssueLimitUpdated(uint256 issueLimit); event MinLoanCollateralSizeUpdated(uint256 minLoanCollateralSize); event AccountLoanLimitUpdated(uint256 loanLimit); event LoanLiquidationOpenUpdated(bool loanLiquidationOpen); event LoanCreated(address indexed account, uint256 loanID, uint256 amount); event LoanClosed(address indexed account, uint256 loanID, uint256 feesPaid); event LoanLiquidated(address indexed account, uint256 loanID, address liquidator); event LoanPartiallyLiquidated( address indexed account, uint256 loanID, address liquidator, uint256 liquidatedAmount, uint256 liquidatedCollateral ); event CollateralDeposited(address indexed account, uint256 loanID, uint256 collateralAmount, uint256 collateralAfter); event CollateralWithdrawn(address indexed account, uint256 loanID, uint256 amountWithdrawn, uint256 collateralAfter); event LoanRepaid(address indexed account, uint256 loanID, uint256 repaidAmount, uint256 newLoanAmount); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_resolver","type":"address"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"loanLimit","type":"uint256"}],"name":"AccountLoanLimitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"loanID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralAfter","type":"uint256"}],"name":"CollateralDeposited","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"loanID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountWithdrawn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralAfter","type":"uint256"}],"name":"CollateralWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"ratio","type":"uint256"}],"name":"CollateralizationRatioUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"interestRate","type":"uint256"}],"name":"InterestRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"issueFeeRate","type":"uint256"}],"name":"IssueFeeRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"issueLimit","type":"uint256"}],"name":"IssueLimitUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"ratio","type":"uint256"}],"name":"LiquidationRatioUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"loanID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"feesPaid","type":"uint256"}],"name":"LoanClosed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"loanID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"LoanCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"loanID","type":"uint256"},{"indexed":false,"internalType":"address","name":"liquidator","type":"address"}],"name":"LoanLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"loanLiquidationOpen","type":"bool"}],"name":"LoanLiquidationOpenUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"loanID","type":"uint256"},{"indexed":false,"internalType":"address","name":"liquidator","type":"address"},{"indexed":false,"internalType":"uint256","name":"liquidatedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidatedCollateral","type":"uint256"}],"name":"LoanPartiallyLiquidated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"loanID","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"repaidAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newLoanAmount","type":"uint256"}],"name":"LoanRepaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"minLoanCollateralSize","type":"uint256"}],"name":"MinLoanCollateralSizeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"isPaused","type":"bool"}],"name":"PauseChanged","type":"event"},{"constant":true,"inputs":[],"name":"COLLATERAL","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_ADDRESSES_FROM_RESOLVER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"accountLoanLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"accountOpenLoanCounter","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"accountsSynthLoans","outputs":[{"internalType":"address payable","name":"account","type":"address"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"uint256","name":"loanAmount","type":"uint256"},{"internalType":"uint256","name":"mintingFee","type":"uint256"},{"internalType":"uint256","name":"timeCreated","type":"uint256"},{"internalType":"uint256","name":"loanID","type":"uint256"},{"internalType":"uint256","name":"timeClosed","type":"uint256"},{"internalType":"uint256","name":"loanInterestRate","type":"uint256"},{"internalType":"uint256","name":"accruedInterest","type":"uint256"},{"internalType":"uint40","name":"lastInterestAccrued","type":"uint40"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"_loanAmount","type":"uint256"},{"internalType":"uint256","name":"_seconds","type":"uint256"}],"name":"accruedInterestOnLoan","outputs":[{"internalType":"uint256","name":"interestAmount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"debtBalance","type":"uint256"},{"internalType":"uint256","name":"collateral","type":"uint256"}],"name":"calculateAmountToLiquidate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"loanID","type":"uint256"}],"name":"closeLoan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"loanAmount","type":"uint256"}],"name":"collateralAmountForLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"collateralizationRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_loanID","type":"uint256"}],"name":"currentInterestOnLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"loanID","type":"uint256"}],"name":"depositCollateral","outputs":[],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[],"name":"getContractInfo","outputs":[{"internalType":"uint256","name":"_collateralizationRatio","type":"uint256"},{"internalType":"uint256","name":"_issuanceRatio","type":"uint256"},{"internalType":"uint256","name":"_interestRate","type":"uint256"},{"internalType":"uint256","name":"_interestPerSecond","type":"uint256"},{"internalType":"uint256","name":"_issueFeeRate","type":"uint256"},{"internalType":"uint256","name":"_issueLimit","type":"uint256"},{"internalType":"uint256","name":"_minLoanCollateralSize","type":"uint256"},{"internalType":"uint256","name":"_totalIssuedSynths","type":"uint256"},{"internalType":"uint256","name":"_totalLoansCreated","type":"uint256"},{"internalType":"uint256","name":"_totalOpenLoanCount","type":"uint256"},{"internalType":"uint256","name":"_ethBalance","type":"uint256"},{"internalType":"uint256","name":"_liquidationDeadline","type":"uint256"},{"internalType":"bool","name":"_loanLiquidationOpen","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_loanID","type":"uint256"}],"name":"getLoan","outputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"uint256","name":"loanAmount","type":"uint256"},{"internalType":"uint256","name":"timeCreated","type":"uint256"},{"internalType":"uint256","name":"loanID","type":"uint256"},{"internalType":"uint256","name":"timeClosed","type":"uint256"},{"internalType":"uint256","name":"accruedInterest","type":"uint256"},{"internalType":"uint256","name":"totalFees","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_loanID","type":"uint256"}],"name":"getLoanCollateralRatio","outputs":[{"internalType":"uint256","name":"loanCollateralRatio","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_loanID","type":"uint256"}],"name":"getMintingFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getResolverAddressesRequired","outputs":[{"internalType":"bytes32[24]","name":"addressesRequired","type":"bytes32[24]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"interestPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"interestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"contract AddressResolver","name":"_resolver","type":"address"}],"name":"isResolverCached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"issuanceRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"issueFeeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"issueLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_loanCreatorsAddress","type":"address"},{"internalType":"uint256","name":"_loanID","type":"uint256"},{"internalType":"uint256","name":"_debtToCover","type":"uint256"}],"name":"liquidateLoan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_loanCreatorsAddress","type":"address"},{"internalType":"uint256","name":"_loanID","type":"uint256"}],"name":"liquidateUnclosedLoan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"liquidationDeadline","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"liquidationPenalty","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"liquidationRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"collateralAmount","type":"uint256"}],"name":"loanAmountFromCollateral","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"loanLiquidationOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minLoanCollateralSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"nominateNewOwner","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"nominatedOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_loanAmount","type":"uint256"}],"name":"openLoan","outputs":[{"internalType":"uint256","name":"loanID","type":"uint256"}],"payable":true,"stateMutability":"payable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_account","type":"address"}],"name":"openLoanIDsByAccount","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"address","name":"_loanCreatorsAddress","type":"address"},{"internalType":"uint256","name":"_loanID","type":"uint256"},{"internalType":"uint256","name":"_repayAmount","type":"uint256"}],"name":"repayLoan","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"resolver","outputs":[{"internalType":"contract AddressResolver","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"resolverAddressesRequired","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_loanLimit","type":"uint256"}],"name":"setAccountLoanLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"ratio","type":"uint256"}],"name":"setCollateralizationRatio","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_interestRate","type":"uint256"}],"name":"setInterestRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_issueFeeRate","type":"uint256"}],"name":"setIssueFeeRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_issueLimit","type":"uint256"}],"name":"setIssueLimit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_liquidationRatio","type":"uint256"}],"name":"setLiquidationRatio","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"_loanLiquidationOpen","type":"bool"}],"name":"setLoanLiquidationOpen","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_minLoanCollateralSize","type":"uint256"}],"name":"setMinLoanCollateralSize","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bool","name":"_paused","type":"bool"}],"name":"setPaused","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"contract AddressResolver","name":"_resolver","type":"address"}],"name":"setResolverAndSyncCache","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_loanID","type":"uint256"}],"name":"timeSinceInterestAccrualOnLoan","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_loanID","type":"uint256"}],"name":"totalFeesOnLoan","outputs":[{"internalType":"uint256","name":"interestAmount","type":"uint256"},{"internalType":"uint256","name":"mintingFee","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalIssuedSynths","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalLoansCreated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalOpenLoanCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"loanID","type":"uint256"},{"internalType":"uint256","name":"withdrawAmount","type":"uint256"}],"name":"withdrawCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040819052630241ebdb60e61b81527384d626b2bb4d0f064067e4bf80fce7055d8f3e7b9063907af6c09060849060209060048186803b1580156200004557600080fd5b505af41580156200005a573d6000803e3d6000fd5b505050506040513d60208110156200007157600080fd5b505160960260085560408051630241ebdb60e61b815290516064917384d626b2bb4d0f064067e4bf80fce7055d8f3e7b9163907af6c091600480820192602092909190829003018186803b158015620000c957600080fd5b505af4158015620000de573d6000803e3d6000fd5b505050506040513d6020811015620000f557600080fd5b5051600502816200010257fe5b04600955620001266301e133806009546200069360201b6200404e1790919060201c565b600a556103e87384d626b2bb4d0f064067e4bf80fce7055d8f3e7b63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b1580156200017157600080fd5b505af415801562000186573d6000803e3d6000fd5b505050506040513d60208110156200019d57600080fd5b505160050281620001aa57fe5b04600b557384d626b2bb4d0f064067e4bf80fce7055d8f3e7b63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015620001f357600080fd5b505af415801562000208573d6000803e3d6000fd5b505050506040513d60208110156200021f57600080fd5b50516298968002600c5560408051630241ebdb60e61b815290517384d626b2bb4d0f064067e4bf80fce7055d8f3e7b9163907af6c0916004808301926020929190829003018186803b1580156200027557600080fd5b505af41580156200028a573d6000803e3d6000fd5b505050506040513d6020811015620002a157600080fd5b5051600d556032600e55600f805460ff1916905560408051630241ebdb60e61b815290516064917384d626b2bb4d0f064067e4bf80fce7055d8f3e7b9163907af6c091600480820192602092909190829003018186803b1580156200030557600080fd5b505af41580156200031a573d6000803e3d6000fd5b505050506040513d60208110156200033157600080fd5b5051609602816200033e57fe5b04601155600a7384d626b2bb4d0f064067e4bf80fce7055d8f3e7b63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b1580156200038957600080fd5b505af41580156200039e573d6000803e3d6000fd5b505050506040513d6020811015620003b557600080fd5b505181620003bf57fe5b0460125560405180608001604052806b53797374656d53746174757360a01b81526020016814de5b9d1a1cd554d160ba1b81526020016c45786368616e6765526174657360981b815260200166119959541bdbdb60ca1b81525060189060046200042b929190620006ff565b503480156200043957600080fd5b506040516200534238038062005342833981810160405260408110156200045f57600080fd5b508051602090910151604080516103008101918290528291601890819081845b8154815260200190600101908083116200047f57508793505050506001600160a01b038116620004f6576040805162461bcd60e51b815260206004820152601960248201527f4f776e657220616464726573732063616e6e6f74206265203000000000000000604482015290519081900360640190fd5b600080546001600160a01b0319166001600160a01b038316908117825560408051928352602083019190915280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a1506000546001600160a01b0316620005a1576040805162461bcd60e51b815260206004820152601160248201527013dddb995c881b5d5cdd081899481cd95d607a1b604482015290519081900360640190fd5b60016004556000546001600160a01b0316620005f8576040805162461bcd60e51b815260206004820152601160248201527013dddb995c881b5d5cdd081899481cd95d607a1b604482015290519081900360640190fd5b60005b6018811015620006605760008282601881106200061457fe5b602002015114620006515760078282601881106200062e57fe5b602090810291909101518254600181018455600093845291909220015562000657565b62000660565b600101620005fb565b5050600580546001600160a01b0319166001600160a01b039290921691909117905550504262794a000160105562000762565b6000808211620006ea576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b6000828481620006f657fe5b04949350505050565b826018810192821562000730579160200282015b828111156200073057825182559160200191906001019062000713565b506200073e92915062000742565b5090565b6200075f91905b808211156200073e576000815560010162000749565b90565b614bd080620007726000396000f3fe6080604052600436106103815760003560e01c80637c3a00fd116101d1578063ab49848c11610102578063e3235c91116100a0578063ee5f3f5c1161006f578063ee5f3f5c14610d43578063eea8f5da14610d58578063f45f08fb14610d6d578063f53dfb8414610da657610381565b8063e3235c9114610cda578063e3c1e58c14610cef578063e40108ed14610d04578063e5829d2014610d1957610381565b8063c6c9d828116100dc578063c6c9d82814610c38578063d05951a014610c62578063dcaf9c4414610c8c578063e220a81114610ca157610381565b8063ab49848c14610ba9578063b410a03414610bf7578063bb8c6d6c14610c0c57610381565b8063946ce8cd1161016f578063a2e1734211610149578063a2e1734214610a89578063a5d5db0c14610ab9578063a76cdfa514610ae5578063aa754a2a14610b0f57610381565b8063946ce8cd146109c65780639f7d5688146109f0578063a1c5158614610a0557610381565b806389c937de116101ab57806389c937de146109395780638da5cb5b146109725780638fdc8f3b1461098757806391b4ded9146109b157610381565b80637c3a00fd146108695780637cc1f8671461087e57806380a5d3d8146108fa57610381565b80633be99e6f116102b65780635c975abb11610254578063631e144411610223578063631e1444146107dc578063675969be1461080f578063767a7b051461082457806379ba50971461085457610381565b80635c975abb1461070d5780635d1a2229146107365780635f84f3021461076057806360655ba71461078a57610381565b80634f069f66116102905780634f069f66146106785780634f11815c146106a257806353a47bb7146106db57806354e3e70d146106f057610381565b80633be99e6f146105f75780634189bb491461062a578063462b97251461063f57610381565b806323aa7f0f116103235780632f2bf15b116102fd5780632f2bf15b146104f0578063361e208614610573578063384585711461058857806339735e37146105c757610381565b806323aa7f0f146104b157806323f5589a146104c657806324bbab8b146104db57610381565b80631627540c1161035f5780631627540c1461041157806316c38b3c146104465780631775765f1461047257806317da255e1461048757610381565b806304f3bcec14610386578063089f7fb4146103b75780631474b279146103fc575b600080fd5b34801561039257600080fd5b5061039b610dd0565b604080516001600160a01b039092168252519081900360200190f35b3480156103c357600080fd5b506103ea600480360360208110156103da57600080fd5b50356001600160a01b0316610ddf565b60408051918252519081900360200190f35b34801561040857600080fd5b506103ea610df1565b34801561041d57600080fd5b506104446004803603602081101561043457600080fd5b50356001600160a01b0316610df7565b005b34801561045257600080fd5b506104446004803603602081101561046957600080fd5b50351515610e53565b34801561047e57600080fd5b506103ea610ecd565b34801561049357600080fd5b50610444600480360360208110156104aa57600080fd5b5035610ed3565b3480156104bd57600080fd5b506103ea610f16565b3480156104d257600080fd5b506103ea610f1c565b3480156104e757600080fd5b506103ea610f22565b3480156104fc57600080fd5b506105236004803603602081101561051357600080fd5b50356001600160a01b0316610f2c565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561055f578181015183820152602001610547565b505050509050019250505060405180910390f35b34801561057f57600080fd5b506103ea61111e565b34801561059457600080fd5b50610444600480360360608110156105ab57600080fd5b506001600160a01b038135169060208101359060400135611124565b3480156105d357600080fd5b506103ea600480360360408110156105ea57600080fd5b50803590602001356116ff565b34801561060357600080fd5b506104446004803603602081101561061a57600080fd5b50356001600160a01b03166117f2565b34801561063657600080fd5b506103ea61191f565b34801561064b57600080fd5b506103ea6004803603604081101561066257600080fd5b506001600160a01b038135169060200135611925565b34801561068457600080fd5b506104446004803603602081101561069b57600080fd5b5035611945565b3480156106ae57600080fd5b506103ea600480360360408110156106c557600080fd5b506001600160a01b038135169060200135611988565b3480156106e757600080fd5b5061039b6119af565b6103ea6004803603602081101561070657600080fd5b50356119be565b34801561071957600080fd5b50610722612001565b604080519115158252519081900360200190f35b34801561074257600080fd5b506104446004803603602081101561075957600080fd5b503561200a565b34801561076c57600080fd5b506104446004803603602081101561078357600080fd5b503561208d565b34801561079657600080fd5b506107c3600480360360408110156107ad57600080fd5b506001600160a01b0381351690602001356121d9565b6040805192835260208301919091528051918290030190f35b3480156107e857600080fd5b50610722600480360360208110156107ff57600080fd5b50356001600160a01b0316612249565b34801561081b57600080fd5b506103ea612364565b34801561083057600080fd5b506104446004803603604081101561084757600080fd5b508035906020013561236a565b34801561086057600080fd5b506104446126c2565b34801561087557600080fd5b506103ea61277e565b34801561088a57600080fd5b50610893612784565b604080519d8e5260208e019c909c528c8c019a909a5260608c019890985260808b019690965260a08a019490945260c089019290925260e0880152610100870152610120860152610140850152610160840152151561018083015251908190036101a00190f35b34801561090657600080fd5b506104446004803603606081101561091d57600080fd5b506001600160a01b0381351690602081013590604001356127ef565b34801561094557600080fd5b506103ea6004803603604081101561095c57600080fd5b506001600160a01b038135169060200135612b50565b34801561097e57600080fd5b5061039b612bb2565b34801561099357600080fd5b506103ea600480360360208110156109aa57600080fd5b5035612bc1565b3480156109bd57600080fd5b506103ea612c67565b3480156109d257600080fd5b50610444600480360360208110156109e957600080fd5b5035612c6d565b3480156109fc57600080fd5b506103ea612d6a565b348015610a1157600080fd5b50610a3e60048036036040811015610a2857600080fd5b506001600160a01b038135169060200135612d70565b604080516001600160a01b0390991689526020890197909752878701959095526060870193909352608086019190915260a085015260c084015260e083015251908190036101000190f35b348015610a9557600080fd5b506103ea60048036036040811015610aac57600080fd5b5080359060200135612e17565b61044460048036036040811015610acf57600080fd5b506001600160a01b038135169060200135612e45565b348015610af157600080fd5b5061044460048036036020811015610b0857600080fd5b503561300b565b348015610b1b57600080fd5b50610b4860048036036040811015610b3257600080fd5b506001600160a01b03813516906020013561304e565b604080516001600160a01b03909b168b5260208b0199909952898901979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015264ffffffffff1661012083015251908190036101400190f35b348015610bb557600080fd5b50610bbe6130cc565b604051808261030080838360005b83811015610be4578181015183820152602001610bcc565b5050505090500191505060405180910390f35b348015610c0357600080fd5b506103ea613116565b348015610c1857600080fd5b5061044460048036036020811015610c2f57600080fd5b5035151561313b565b348015610c4457600080fd5b506103ea60048036036020811015610c5b57600080fd5b50356131e5565b348015610c6e57600080fd5b5061044460048036036020811015610c8557600080fd5b5035613203565b348015610c9857600080fd5b506103ea61331b565b348015610cad57600080fd5b5061044460048036036040811015610cc457600080fd5b506001600160a01b038135169060200135613321565b348015610ce657600080fd5b506103ea6134d2565b348015610cfb57600080fd5b506107226134d7565b348015610d1057600080fd5b506103ea6134e0565b348015610d2557600080fd5b5061044460048036036020811015610d3c57600080fd5b50356134e6565b348015610d4f57600080fd5b506103ea6135ba565b348015610d6457600080fd5b506103ea6135c0565b348015610d7957600080fd5b506103ea60048036036040811015610d9057600080fd5b506001600160a01b0381351690602001356135c6565b348015610db257600080fd5b506103ea60048036036020811015610dc957600080fd5b50356135f0565b6005546001600160a01b031681565b60176020526000908152604090205481565b600e5481565b610dff61369d565b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b610e5b61369d565b60035460ff1615158115151415610e7157610eca565b6003805460ff1916821515179081905560ff1615610e8e57426002555b6003546040805160ff90921615158252517f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec59181900360200190a15b50565b60115481565b610edb61369d565b600d8190556040805182815290517f9f45df4d81199bea8f20e88707b6f7d36b8e8f20a7def01c113746f67557ffb69181900360200190a150565b60145481565b60125481565b6208aa8960eb1b81565b6001600160a01b03811660009081526016602090815260408083208054825181850281018501909352808352606094859484015b828210156110035760008481526020908190206040805161014081018252600a860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460e084015260088101546101008401526009015464ffffffffff166101208301529083529092019101610f60565b50505050905060608151604051908082528060200260200182016040528015611036578160200160208202803883390190505b5090506000805b83518110156110a45783818151811061105257fe5b602002602001015160c001516000141561109c5783818151811061107257fe5b602002602001015160a0015183838151811061108a57fe5b60209081029190910101526001909101905b60010161103d565b506060816040519080825280602002602001820160405280156110d1578160200160208202803883390190505b50905060005b82811015611112578381815181106110eb57fe5b60200260200101518282815181106110ff57fe5b60209081029190910101526001016110d7565b5093505050505b919050565b600b5481565b60048054600101908190556111376136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561118057600080fd5b505afa158015611194573d6000803e3d6000fd5b505050506040513d60208110156111aa57600080fd5b5051156111ec576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b6111f4613739565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b15801561122c57600080fd5b505afa158015611240573d6000803e3d6000fd5b505050508161124d613789565b6001600160a01b03166370a08231336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156112a257600080fd5b505afa1580156112b6573d6000803e3d6000fd5b505050506040513d60208110156112cc57600080fd5b5051101561131b576040805162461bcd60e51b81526020600482015260176024820152764e6f7420656e6f75676820735553442062616c616e636560481b604482015290519081900360640190fd5b6113236147ef565b61132d85856137d6565b905061133881613919565b6000806000611346846139b5565b925092509250601154831061138c5760405162461bcd60e51b81526004018080602001828103825260288152602001806148726028913960400191505060405180910390fd5b60006113c36113bd836113b18861010001518960400151613aa590919063ffffffff16565b9063ffffffff613aa516565b846116ff565b905060008782106113d457876113d6565b815b90506113e0613789565b6001600160a01b0316639dc29fac33836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561143f57600080fd5b505af1158015611453573d6000803e3d6000fd5b50505050600080600061148284611478888c6101000151613aa590919063ffffffff16565b8b60400151613aff565b509250925092506114938383613b78565b600061149d6136e8565b6001600160a01b031663654a60ac631cd554d160e21b876208aa8960eb1b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b1580156114fd57600080fd5b505afa158015611511573d6000803e3d6000fd5b505050506040513d602081101561152757600080fd5b505160125460408051630241ebdb60e61b815290519293506000926115cc926115bf9290917384d626b2bb4d0f064067e4bf80fce7055d8f3e7b9163907af6c0916004808301926020929190829003018186803b15801561158757600080fd5b505af415801561159b573d6000803e3d6000fd5b505050506040513d60208110156115b157600080fd5b50519063ffffffff613aa516565b839063ffffffff613c9716565b90506115f08b6115e9868e60400151613cc190919063ffffffff16565b8542613d1e565b6116108b61160b838e60200151613cc190919063ffffffff16565b613dfe565b50604051339082156108fc029083906000818181858888f1935050505015801561163e573d6000803e3d6000fd5b508e6001600160a01b03167fb6e43890aeea54fbe6c0ed628e78172a0ff30bbcb1d70d8b130b12c366bac4c58f33898560405180858152602001846001600160a01b03166001600160a01b0316815260200183815260200182815260200194505050505060405180910390a2505050505050505050505060045481146116f9576040805162461bcd60e51b815260206004820152601f60248201526000805160206148cb833981519152604482015290519081900360640190fd5b50505050565b6000807384d626b2bb4d0f064067e4bf80fce7055d8f3e7b63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b15801561174657600080fd5b505af415801561175a573d6000803e3d6000fd5b505050506040513d602081101561177057600080fd5b5051601154909150600061179a61178d868463ffffffff613f2316565b879063ffffffff613cc116565b905060006117d36117c6846117ba60125488613aa590919063ffffffff16565b9063ffffffff613f2316565b859063ffffffff613cc116565b90506117e5828263ffffffff613f2316565b9450505050505b92915050565b6117fa61369d565b600580546001600160a01b0319166001600160a01b03831617905560005b60075481101561191b5760006007828154811061183157fe5b600091825260209182902001546005546040805163dacb2d0160e01b81526004810184905260248101829052601760448201527f5265736f6c766572206d697373696e6720746172676574000000000000000000606482015290519294506001600160a01b039091169263dacb2d0192608480840193829003018186803b1580156118bb57600080fd5b505afa1580156118cf573d6000803e3d6000fd5b505050506040513d60208110156118e557600080fd5b505160009182526006602052604090912080546001600160a01b0319166001600160a01b03909216919091179055600101611818565b5050565b60155481565b600061192f6147ef565b61193984846137d6565b60600151949350505050565b61194d61369d565b600c8190556040805182815290517fbb72ce8874020b3b98429d653df927cac6618ac1932384b1446bf04bf9a1b7e59181900360200190a150565b60006119926147ef565b61199c84846137d6565b90506119a781613f4d565b949350505050565b6001546001600160a01b031681565b60035460009060ff1615611a035760405162461bcd60e51b815260040180806020018281038252603c815260200180614a7e603c913960400191505060405180910390fd5b6004805460010190819055611a166136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611a5f57600080fd5b505afa158015611a73573d6000803e3d6000fd5b505050506040513d6020811015611a8957600080fd5b505115611acb576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b611ad3613739565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015611b0b57600080fd5b505afa158015611b1f573d6000803e3d6000fd5b50505050600d54341015611b645760405162461bcd60e51b8152600401808060200182810382526048815260200180614b546048913960600191505060405180910390fd5b600f5460ff1615611bbc576040805162461bcd60e51b815260206004820152601e60248201527f4c6f616e7320617265206e6f77206265696e67206c6971756964617465640000604482015290519081900360640190fd5b600e543360009081526016602052604090205410611c0b5760405162461bcd60e51b8152600401808060200182810382526023815260200180614a0b6023913960400191505060405180910390fd5b6000611c1634612bc1565b905080841115611c575760405162461bcd60e51b81526004018080602001828103825260278152602001806149456027913960400191505060405180910390fd5b6000611c6285613fb4565b90506000611c76868363ffffffff613cc116565b9050600c54611c9087601354613aa590919063ffffffff16565b1115611ccd5760405162461bcd60e51b81526004018080602001828103825260238152602001806149e86023913960400191505060405180910390fd5b611cd5613fcb565b9450611cdf6147ef565b5060408051610140810182523381523460208201529081018790526060810183905242608082015260a08101869052600060c0820181905260095460e083015261010082018190526101208201528215611e2c57611d3b613789565b6001600160a01b031663867904b473feefeefeefeefeefeefeefeefeefeefeefeefeef856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611dae57600080fd5b505af1158015611dc2573d6000803e3d6000fd5b50505050611dce614003565b6001600160a01b03166322bf55ef846040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611e1357600080fd5b505af1158015611e27573d6000803e3d6000fd5b505050505b336000908152601660209081526040808320805460018082018355918552938390208551600a9095020180546001600160a01b0319166001600160a01b0390951694909417845591840151918301919091558201516002820155606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e0820151600782015561010082015160088201556101208201516009909101805464ffffffffff191664ffffffffff909216919091179055601354611ef49088613aa5565b601355611eff613789565b6001600160a01b031663867904b433846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611f5e57600080fd5b505af1158015611f72573d6000803e3d6000fd5b505060408051898152602081018b905281513394507f58d170de3a12438e22d81380f353b2fcac86f0a708a1374deaa5c6322a95992f93509081900390910190a2505050506004548114611ffb576040805162461bcd60e51b815260206004820152601f60248201526000805160206148cb833981519152604482015290519081900360640190fd5b50919050565b60035460ff1681565b61201261369d565b6103e881106120525760405162461bcd60e51b81526004018080602001828103825260338152602001806149b56033913960400191505060405180910390fd5b600e8190556040805182815290517f59822dc2d999f6f0618e8b0db5cfc8496084574c769b09609d9b5f4394a310b69181900360200190a150565b61209561369d565b6301e1338081116120d75760405162461bcd60e51b8152600401808060200182810382526037815260200180614b1d6037913960400191505060405180910390fd5b7384d626b2bb4d0f064067e4bf80fce7055d8f3e7b63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b15801561211b57600080fd5b505af415801561212f573d6000803e3d6000fd5b505050506040513d602081101561214557600080fd5b50518111156121855760405162461bcd60e51b8152600401808060200182810382526025815260200180614aba6025913960400191505060405180910390fd5b600981905561219e816301e1338063ffffffff61404e16565b600a5560095460408051918252517fa90e14be5aa57b910aa6dc16c31ff1b5cda380ae25a793b0d3f74df6131a7d749181900360200190a150565b6000806121e46147ef565b6121ee85856137d6565b9050600061220e8261010001518360400151613aa590919063ffffffff16565b90506122376122258261222085613f4d565b612e17565b6101008401519063ffffffff613aa516565b93508160600151925050509250929050565b6005546000906001600160a01b0383811691161461226957506000611119565b60005b60075481101561235b5760006007828154811061228557fe5b6000918252602080832090910154808352600682526040928390205460055484516321f8a72160e01b81526004810184905294519295506001600160a01b03918216949116926321f8a72192602480840193829003018186803b1580156122eb57600080fd5b505afa1580156122ff573d6000803e3d6000fd5b505050506040513d602081101561231557600080fd5b50516001600160a01b031614158061234257506000818152600660205260409020546001600160a01b0316155b1561235257600092505050611119565b5060010161226c565b50600192915050565b600d5481565b60035460ff16156123ac5760405162461bcd60e51b815260040180806020018281038252603c815260200180614a7e603c913960400191505060405180910390fd5b60048054600101908190556123bf6136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561240857600080fd5b505afa15801561241c573d6000803e3d6000fd5b505050506040513d602081101561243257600080fd5b505115612474576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b600082116124b35760405162461bcd60e51b815260040180806020018281038252602981526020018061496c6029913960400191505060405180910390fd5b6124bb613739565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b1580156124f357600080fd5b505afa158015612507573d6000803e3d6000fd5b5050600f5460ff161591506125659050576040805162461bcd60e51b815260206004820152601e60248201527f4c6f616e7320617265206e6f77206265696e67206c6971756964617465640000604482015290519081900360640190fd5b61256d6147ef565b61257733856137d6565b905061258281613919565b602081015160009061259a908563ffffffff613cc116565b90506125a46147ef565b6125ae8383613dfe565b905060006125bb826139b5565b5050905060115481116125ff5760405162461bcd60e51b815260040180806020018281038252603181526020018061489a6031913960400191505060405180910390fd5b604051339087156108fc029088906000818181858888f1935050505015801561262c573d6000803e3d6000fd5b50602080830151604080518a8152928301899052828101919091525133917ffae26280bca25d80f1501a9e363c73d3845e651c9aaae54f1fc09a9dcd5f3303919081900360600190a25050505060045481146126bd576040805162461bcd60e51b815260206004820152601f60248201526000805160206148cb833981519152604482015290519081900360640190fd5b505050565b6001546001600160a01b0316331461270b5760405162461bcd60e51b81526004018080602001828103825260358152602001806148eb6035913960400191505060405180910390fd5b600054600154604080516001600160a01b03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b60095481565b6008546000808080808080808080808061279c613116565b9b506009549a50600a549950600b549850600c549750600d5496506013549550601454945060155493504792506010549150600f60009054906101000a900460ff169050909192939495969798999a9b9c565b6127f76136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561284057600080fd5b505afa158015612854573d6000803e3d6000fd5b505050506040513d602081101561286a57600080fd5b5051156128ac576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b6128b4613739565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b1580156128ec57600080fd5b505afa158015612900573d6000803e3d6000fd5b505050508061290d613789565b6001600160a01b03166370a08231336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561296257600080fd5b505afa158015612976573d6000803e3d6000fd5b505050506040513d602081101561298c57600080fd5b505110156129db576040805162461bcd60e51b81526020600482015260176024820152764e6f7420656e6f75676820735553442062616c616e636560481b604482015290519081900360640190fd5b6129e36147ef565b6129ed84846137d6565b90506129f881613919565b6000612a168261010001518360400151613aa590919063ffffffff16565b90506000612a278261222085613f4d565b90506000612a4382856101000151613aa590919063ffffffff16565b9050600080600080612a5a89868a60400151613aff565b9350935093509350612a6a613789565b6001600160a01b0316639dc29fac338b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015612ac957600080fd5b505af1158015612add573d6000803e3d6000fd5b50505050612aeb8484613b78565b612af788828442613d1e565b604080518b8152602081018b905280820183905290516001600160a01b038d16917f2cebe3c4a7e8e81ca2035a6cb3ee450bb6401d9b6636652e183583f047049572919081900360600190a25050505050505050505050565b6000612b5a6147ef565b612b6484846137d6565b90506000612b90612b878361010001518460400151613aa590919063ffffffff16565b61222084613f4d565b610100830151909150612ba9908263ffffffff613aa516565b95945050505050565b6000546001600160a01b031681565b60006117ec612bce6136e8565b6001600160a01b031663ac82f6086208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015612c1757600080fd5b505afa158015612c2b573d6000803e3d6000fd5b505050506040513d6020811015612c4157600080fd5b5051612c5b612c4e613116565b859063ffffffff613c9716565b9063ffffffff613c9716565b60025481565b612c7561369d565b7384d626b2bb4d0f064067e4bf80fce7055d8f3e7b63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015612cb957600080fd5b505af4158015612ccd573d6000803e3d6000fd5b505050506040513d6020811015612ce357600080fd5b50518111612d2f576040805162461bcd60e51b8152602060048201526014602482015273526174696f206c657373207468616e203130302560601b604482015290519081900360640190fd5b60118190556040805182815290517f5568be83e5cf7405adf8fb39305e2cdf49c43336606d23c3e0d3fe54e205150a9181900360200190a150565b60105481565b600080600080600080600080612d846147ef565b612d8e8b8b6137d6565b9050806000015198508060200151975080604001519650806080015195508060a0015194508060c001519350612dee612ddc612b878361010001518460400151613aa590919063ffffffff16565b6101008301519063ffffffff613aa516565b9250612e07816060015184613aa590919063ffffffff16565b9150509295985092959890939650565b6000612e3e612e3183600a546140b890919063ffffffff16565b849063ffffffff61411116565b9392505050565b60035460ff1615612e875760405162461bcd60e51b815260040180806020018281038252603c815260200180614a7e603c913960400191505060405180910390fd5b60003411612ec65760405162461bcd60e51b81526004018080602001828103825260258152602001806149206025913960400191505060405180910390fd5b612ece613739565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015612f0657600080fd5b505afa158015612f1a573d6000803e3d6000fd5b5050600f5460ff16159150612f789050576040805162461bcd60e51b815260206004820152601e60248201527f4c6f616e7320617265206e6f77206265696e67206c6971756964617465640000604482015290519081900360640190fd5b612f806147ef565b612f8a83836137d6565b9050612f9581613919565b6020810151600090612fad903463ffffffff613aa516565b9050612fb98282613dfe565b506040805184815234602082015280820183905290516001600160a01b038616917f0b1992dffc262be88559dcaf96464e9d661d8bfca7e82f2bb73e31932a82187c919081900360600190a250505050565b61301361369d565b600b8190556040805182815290517fe7bd72551c54d568cd97b00dc52d2787b5c5d4f0070d3582c1e8ba25141f799c9181900360200190a150565b6016602052816000526040600020818154811061306757fe5b60009182526020909120600a909102018054600182015460028301546003840154600485015460058601546006870154600788015460088901546009909901546001600160a01b039098169a50959850939692959194909392909164ffffffffff168a565b6130d4614852565b60005b60075481101561311257600781815481106130ee57fe5b906000526020600020015482826018811061310557fe5b60200201526001016130d7565b5090565b600061313660085468056bc75e2d6310000061412690919063ffffffff16565b905090565b61314361369d565b6010544211613199576040805162461bcd60e51b815260206004820152601b60248201527f4265666f7265206c69717569646174696f6e20646561646c696e650000000000604482015290519081900360640190fd5b600f805460ff191682151517908190556040805160ff90921615158252517faa52cf15c1fbb778214c66f64726e141551158858d1c06ca0392c6c5869c8567916020908290030190a150565b600781815481106131f257fe5b600091825260209091200154905081565b60048054600101908190556132166136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561325f57600080fd5b505afa158015613273573d6000803e3d6000fd5b505050506040513d602081101561328957600080fd5b5051156132cb576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b6132d73383600061413b565b600454811461191b576040805162461bcd60e51b815260206004820152601f60248201526000805160206148cb833981519152604482015290519081900360640190fd5b60085481565b60048054600101908190556133346136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561337d57600080fd5b505afa158015613391573d6000803e3d6000fd5b505050506040513d60208110156133a757600080fd5b5051156133e9576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b600f5460ff16613440576040805162461bcd60e51b815260206004820152601760248201527f4c69717569646174696f6e206973206e6f74206f70656e000000000000000000604482015290519081900360640190fd5b61344c8383600161413b565b6040805183815233602082015281516001600160a01b038616927fde21b2a43b0a2c2109c049fb1e4bb8653fd67d0ffd74fdcb662db381f1eeab38928290030190a260045481146126bd576040805162461bcd60e51b815260206004820152601f60248201526000805160206148cb833981519152604482015290519081900360640190fd5b601881565b600f5460ff1681565b600a5481565b6134ee61369d565b683635c9adc5dea00000811115613537576040805162461bcd60e51b81526020600482015260086024820152670a8dede40d0d2ced60c31b604482015290519081900360640190fd5b68056bc75e2d6310000081101561357f576040805162461bcd60e51b8152602060048201526007602482015266546f6f206c6f7760c81b604482015290519081900360640190fd5b60088190556040805182815290517ffb0ebe8c7316e6a251494c38876d13d9a3a029273fce7964c12aa2ce078695309181900360200190a150565b60135481565b600c5481565b60006135d06147ef565b6135da84846137d6565b90506135e5816139b5565b509095945050505050565b60006117ec68056bc75e2d63100000613691612c4e61360d6136e8565b6001600160a01b031663ac82f6086208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561365657600080fd5b505afa15801561366a573d6000803e3d6000fd5b505050506040513d602081101561368057600080fd5b50516008549063ffffffff61412616565b9063ffffffff61412616565b6000546001600160a01b031633146136e65760405162461bcd60e51b815260040180806020018281038252602f815260200180614a2e602f913960400191505060405180910390fd5b565b60006131366c45786368616e6765526174657360981b6040518060400160405280601d81526020017f4d697373696e672045786368616e67655261746573206164647265737300000081525061464e565b60006131366b53797374656d53746174757360a01b6040518060400160405280601c81526020017f4d697373696e672053797374656d53746174757320616464726573730000000081525061464e565b60006131366814de5b9d1a1cd554d160ba1b6040518060400160405280601981526020017f4d697373696e672053796e74687355534420616464726573730000000000000081525061464e565b6137de6147ef565b6001600160a01b0383166000908152601660209081526040808320805482518185028101850190935280835260609492939192909184015b828210156138b95760008481526020908190206040805161014081018252600a860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460e084015260088101546101008401526009015464ffffffffff166101208301529083529092019101613816565b509293506000925050505b815181101561391157838282815181106138da57fe5b602002602001015160a001511415613909578181815181106138f857fe5b6020026020010151925050506117ec565b6001016138c4565b505092915050565b60008160a0015111613968576040805162461bcd60e51b8152602060048201526013602482015272131bd85b88191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b60c081015115610eca576040805162461bcd60e51b8152602060048201526013602482015272131bd85b88185b1c9958591e4818db1bdcd959606a1b604482015290519081900360640190fd5b6000806000806139d78561010001518660400151613aa590919063ffffffff16565b90506139e68161222087613f4d565b9150613a796139f36136e8565b6001600160a01b031663ac82f6086208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015613a3c57600080fd5b505afa158015613a50573d6000803e3d6000fd5b505050506040513d6020811015613a6657600080fd5b505160208701519063ffffffff613c9716565b9250613a9b613a8e828463ffffffff613aa516565b849063ffffffff613f2316565b9350509193909250565b600082820183811015612e3e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000808381868015801590613b145750600087115b15613b4f57868111613b265780613b28565b865b9450613b3a838663ffffffff613cc116565b9250613b4c818663ffffffff613cc116565b90505b8591508015613b6e57613b68828263ffffffff613cc116565b91508093505b5093509350935093565b8115613c7757613b86613789565b6001600160a01b031663867904b473feefeefeefeefeefeefeefeefeefeefeefeefeef846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015613bf957600080fd5b505af1158015613c0d573d6000803e3d6000fd5b50505050613c19614003565b6001600160a01b03166322bf55ef836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015613c5e57600080fd5b505af1158015613c72573d6000803e3d6000fd5b505050505b801561191b57601354613c90908263ffffffff613cc116565b6013555050565b6000670de0b6b3a7640000613cb2848463ffffffff6140b816565b81613cb957fe5b049392505050565b600082821115613d18576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b83516001600160a01b03166000908152601660205260408120905b8154811015613df6578560a00151828281548110613d5357fe5b90600052602060002090600a0201600501541415613dee5784828281548110613d7857fe5b90600052602060002090600a02016002018190555083828281548110613d9a57fe5b90600052602060002090600a02016008018190555082828281548110613dbc57fe5b90600052602060002090600a020160090160006101000a81548164ffffffffff021916908364ffffffffff1602179055505b600101613d39565b505050505050565b613e066147ef565b82516001600160a01b03166000908152601660205260408120905b8154811015613911578460a00151828281548110613e3b57fe5b90600052602060002090600a0201600501541415613f1b5783828281548110613e6057fe5b90600052602060002090600a020160010181905550818181548110613e8157fe5b60009182526020918290206040805161014081018252600a90930290910180546001600160a01b031683526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e0820152600882015461010082015260099091015464ffffffffff1661012082015292506117ec915050565b600101613e21565b6000612e3e82613f4185670de0b6b3a764000063ffffffff6140b816565b9063ffffffff61404e16565b600080600083610120015164ffffffffff1611613f6e578260800151613f7c565b82610120015164ffffffffff165b905060008360c0015111613f9f57613f9a428263ffffffff613cc116565b612e3e565b60c0830151612e3e908263ffffffff613cc116565b60006117ec600b548361411190919063ffffffff16565b601554600090613fe290600163ffffffff613aa516565b601555601454613ff990600163ffffffff613aa516565b6014819055905090565b600061313666119959541bdbdb60ca1b6040518060400160405280601781526020017f4d697373696e6720466565506f6f6c206164647265737300000000000000000081525061464e565b60008082116140a4576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b60008284816140af57fe5b04949350505050565b6000826140c7575060006117ec565b828202828482816140d457fe5b0414612e3e5760405162461bcd60e51b8152600401808060200182810382526021815260200180614a5d6021913960400191505060405180910390fd5b6000612e3e8383670de0b6b3a76400006146f8565b6000612e3e8383670de0b6b3a7640000614735565b614143613739565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561417b57600080fd5b505afa15801561418f573d6000803e3d6000fd5b5050505061419b6147ef565b6141a584846137d6565b90506141b081613919565b60006141d1612b878361010001518460400151613aa590919063ffffffff16565b905060006141ec828460400151613aa590919063ffffffff16565b9050600061420883856101000151613aa590919063ffffffff16565b905081614213613789565b6001600160a01b03166370a08231336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561426857600080fd5b505afa15801561427c573d6000803e3d6000fd5b505050506040513d602081101561429257600080fd5b505110156142d15760405162461bcd60e51b815260040180806020018281038252603e815260200180614adf603e913960400191505060405180910390fd5b6142da8461475b565b6143086142f98561010001518660400151613cc190919063ffffffff16565b6013549063ffffffff613cc116565b601355614313613789565b6001600160a01b0316639dc29fac33846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561437257600080fd5b505af1158015614386573d6000803e3d6000fd5b50505050614392613789565b6001600160a01b031663867904b473feefeefeefeefeefeefeefeefeefeefeefeefeef836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561440557600080fd5b505af1158015614419573d6000803e3d6000fd5b50505050614425614003565b6001600160a01b03166322bf55ef826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561446a57600080fd5b505af115801561447e573d6000803e3d6000fd5b50505050602084015185156145c75760006144976136e8565b6001600160a01b031663654a60ac631cd554d160e21b866208aa8960eb1b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b1580156144f757600080fd5b505afa15801561450b573d6000803e3d6000fd5b505050506040513d602081101561452157600080fd5b505160125460408051630241ebdb60e61b81529051929350600092614581926115bf9290917384d626b2bb4d0f064067e4bf80fce7055d8f3e7b9163907af6c0916004808301926020929190829003018186803b15801561158757600080fd5b9050614593838263ffffffff613cc116565b604051909350339082156108fc029083906000818181858888f193505050501580156145c3573d6000803e3d6000fd5b5050505b84516040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015614600573d6000803e3d6000fd5b50604080518881526020810184905281516001600160a01b038b16927f3cc9f5d298758bad94536f27fa6a3033c2793e0a387a2d78e72550a3b8dacf1e928290030190a25050505050505050565b6000828152600660205260408120546001600160a01b031682816146f05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156146b557818101518382015260200161469d565b50505050905090810190601f1680156146e25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509392505050565b600080600a830461470f868663ffffffff6140b816565b8161471657fe5b0490506005600a825b061061472957600a015b600a9004949350505050565b60008061474f84613f4187600a870263ffffffff6140b816565b90506005600a8261471f565b80516001600160a01b03166000908152601660205260408120905b81548110156147d3578260a0015182828154811061479057fe5b90600052602060002090600a02016005015414156147cb57428282815481106147b557fe5b90600052602060002090600a0201600601819055505b600101614776565b506015546147e890600163ffffffff613cc116565b6015555050565b60405180610140016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600064ffffffffff1681525090565b604051806103000160405280601890602082028038833950919291505056fe436f6c6c61746572616c20726174696f2061626f7665206c69717569646174696f6e20726174696f436f6c6c61746572616c20726174696f2062656c6f77206c69717569646174696f6e2061667465722077697468647261775265656e7472616e637947756172643a207265656e7472616e742063616c6c00596f75206d757374206265206e6f6d696e61746564206265666f726520796f752063616e20616363657074206f776e6572736869704465706f73697420616d6f756e74206d7573742062652067726561746572207468616e20304c6f616e20616d6f756e742065786365656473206d617820626f72726f77696e6720706f776572416d6f756e7420746f207769746864726177206d7573742062652067726561746572207468616e2030426c6f636b656420617320455448207261746520697320696e76616c696400004f776e65722063616e6e6f742073657420686967686572207468616e204143434f554e545f4c4f414e5f4c494d49545f4341504c6f616e20416d6f756e7420657863656564732074686520737570706c79206361702e45616368206163636f756e74206973206c696d6974656420746f203530206c6f616e734f6e6c792074686520636f6e7472616374206f776e6572206d617920706572666f726d207468697320616374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775468697320616374696f6e2063616e6e6f7420626520706572666f726d6564207768696c652074686520636f6e747261637420697320706175736564496e7465726573742063616e6e6f74206265206d6f7265207468616e203130302520415052596f7520646f206e6f742068617665207468652072657175697265642053796e74682062616c616e636520746f20636c6f73652074686973206c6f616e2e496e74657265737420726174652063616e6e6f74206265206c657373207468617420746865205345434f4e44535f494e5f415f594541524e6f7420656e6f7567682045544820746f206372656174652074686973206c6f616e2e20506c656173652073656520746865206d696e4c6f616e436f6c6c61746572616c53697a65a265627a7a72315820e6b58a3e9729ae5feebbb211c3c89855eb0a1370b08ab5b3623dfe9c496e795b64736f6c63430005100032000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe00000000000000000000000061166014e3f04e40c953fe4eab9d9e40863c83ae
Deployed Bytecode
0x6080604052600436106103815760003560e01c80637c3a00fd116101d1578063ab49848c11610102578063e3235c91116100a0578063ee5f3f5c1161006f578063ee5f3f5c14610d43578063eea8f5da14610d58578063f45f08fb14610d6d578063f53dfb8414610da657610381565b8063e3235c9114610cda578063e3c1e58c14610cef578063e40108ed14610d04578063e5829d2014610d1957610381565b8063c6c9d828116100dc578063c6c9d82814610c38578063d05951a014610c62578063dcaf9c4414610c8c578063e220a81114610ca157610381565b8063ab49848c14610ba9578063b410a03414610bf7578063bb8c6d6c14610c0c57610381565b8063946ce8cd1161016f578063a2e1734211610149578063a2e1734214610a89578063a5d5db0c14610ab9578063a76cdfa514610ae5578063aa754a2a14610b0f57610381565b8063946ce8cd146109c65780639f7d5688146109f0578063a1c5158614610a0557610381565b806389c937de116101ab57806389c937de146109395780638da5cb5b146109725780638fdc8f3b1461098757806391b4ded9146109b157610381565b80637c3a00fd146108695780637cc1f8671461087e57806380a5d3d8146108fa57610381565b80633be99e6f116102b65780635c975abb11610254578063631e144411610223578063631e1444146107dc578063675969be1461080f578063767a7b051461082457806379ba50971461085457610381565b80635c975abb1461070d5780635d1a2229146107365780635f84f3021461076057806360655ba71461078a57610381565b80634f069f66116102905780634f069f66146106785780634f11815c146106a257806353a47bb7146106db57806354e3e70d146106f057610381565b80633be99e6f146105f75780634189bb491461062a578063462b97251461063f57610381565b806323aa7f0f116103235780632f2bf15b116102fd5780632f2bf15b146104f0578063361e208614610573578063384585711461058857806339735e37146105c757610381565b806323aa7f0f146104b157806323f5589a146104c657806324bbab8b146104db57610381565b80631627540c1161035f5780631627540c1461041157806316c38b3c146104465780631775765f1461047257806317da255e1461048757610381565b806304f3bcec14610386578063089f7fb4146103b75780631474b279146103fc575b600080fd5b34801561039257600080fd5b5061039b610dd0565b604080516001600160a01b039092168252519081900360200190f35b3480156103c357600080fd5b506103ea600480360360208110156103da57600080fd5b50356001600160a01b0316610ddf565b60408051918252519081900360200190f35b34801561040857600080fd5b506103ea610df1565b34801561041d57600080fd5b506104446004803603602081101561043457600080fd5b50356001600160a01b0316610df7565b005b34801561045257600080fd5b506104446004803603602081101561046957600080fd5b50351515610e53565b34801561047e57600080fd5b506103ea610ecd565b34801561049357600080fd5b50610444600480360360208110156104aa57600080fd5b5035610ed3565b3480156104bd57600080fd5b506103ea610f16565b3480156104d257600080fd5b506103ea610f1c565b3480156104e757600080fd5b506103ea610f22565b3480156104fc57600080fd5b506105236004803603602081101561051357600080fd5b50356001600160a01b0316610f2c565b60408051602080825283518183015283519192839290830191858101910280838360005b8381101561055f578181015183820152602001610547565b505050509050019250505060405180910390f35b34801561057f57600080fd5b506103ea61111e565b34801561059457600080fd5b50610444600480360360608110156105ab57600080fd5b506001600160a01b038135169060208101359060400135611124565b3480156105d357600080fd5b506103ea600480360360408110156105ea57600080fd5b50803590602001356116ff565b34801561060357600080fd5b506104446004803603602081101561061a57600080fd5b50356001600160a01b03166117f2565b34801561063657600080fd5b506103ea61191f565b34801561064b57600080fd5b506103ea6004803603604081101561066257600080fd5b506001600160a01b038135169060200135611925565b34801561068457600080fd5b506104446004803603602081101561069b57600080fd5b5035611945565b3480156106ae57600080fd5b506103ea600480360360408110156106c557600080fd5b506001600160a01b038135169060200135611988565b3480156106e757600080fd5b5061039b6119af565b6103ea6004803603602081101561070657600080fd5b50356119be565b34801561071957600080fd5b50610722612001565b604080519115158252519081900360200190f35b34801561074257600080fd5b506104446004803603602081101561075957600080fd5b503561200a565b34801561076c57600080fd5b506104446004803603602081101561078357600080fd5b503561208d565b34801561079657600080fd5b506107c3600480360360408110156107ad57600080fd5b506001600160a01b0381351690602001356121d9565b6040805192835260208301919091528051918290030190f35b3480156107e857600080fd5b50610722600480360360208110156107ff57600080fd5b50356001600160a01b0316612249565b34801561081b57600080fd5b506103ea612364565b34801561083057600080fd5b506104446004803603604081101561084757600080fd5b508035906020013561236a565b34801561086057600080fd5b506104446126c2565b34801561087557600080fd5b506103ea61277e565b34801561088a57600080fd5b50610893612784565b604080519d8e5260208e019c909c528c8c019a909a5260608c019890985260808b019690965260a08a019490945260c089019290925260e0880152610100870152610120860152610140850152610160840152151561018083015251908190036101a00190f35b34801561090657600080fd5b506104446004803603606081101561091d57600080fd5b506001600160a01b0381351690602081013590604001356127ef565b34801561094557600080fd5b506103ea6004803603604081101561095c57600080fd5b506001600160a01b038135169060200135612b50565b34801561097e57600080fd5b5061039b612bb2565b34801561099357600080fd5b506103ea600480360360208110156109aa57600080fd5b5035612bc1565b3480156109bd57600080fd5b506103ea612c67565b3480156109d257600080fd5b50610444600480360360208110156109e957600080fd5b5035612c6d565b3480156109fc57600080fd5b506103ea612d6a565b348015610a1157600080fd5b50610a3e60048036036040811015610a2857600080fd5b506001600160a01b038135169060200135612d70565b604080516001600160a01b0390991689526020890197909752878701959095526060870193909352608086019190915260a085015260c084015260e083015251908190036101000190f35b348015610a9557600080fd5b506103ea60048036036040811015610aac57600080fd5b5080359060200135612e17565b61044460048036036040811015610acf57600080fd5b506001600160a01b038135169060200135612e45565b348015610af157600080fd5b5061044460048036036020811015610b0857600080fd5b503561300b565b348015610b1b57600080fd5b50610b4860048036036040811015610b3257600080fd5b506001600160a01b03813516906020013561304e565b604080516001600160a01b03909b168b5260208b0199909952898901979097526060890195909552608088019390935260a087019190915260c086015260e085015261010084015264ffffffffff1661012083015251908190036101400190f35b348015610bb557600080fd5b50610bbe6130cc565b604051808261030080838360005b83811015610be4578181015183820152602001610bcc565b5050505090500191505060405180910390f35b348015610c0357600080fd5b506103ea613116565b348015610c1857600080fd5b5061044460048036036020811015610c2f57600080fd5b5035151561313b565b348015610c4457600080fd5b506103ea60048036036020811015610c5b57600080fd5b50356131e5565b348015610c6e57600080fd5b5061044460048036036020811015610c8557600080fd5b5035613203565b348015610c9857600080fd5b506103ea61331b565b348015610cad57600080fd5b5061044460048036036040811015610cc457600080fd5b506001600160a01b038135169060200135613321565b348015610ce657600080fd5b506103ea6134d2565b348015610cfb57600080fd5b506107226134d7565b348015610d1057600080fd5b506103ea6134e0565b348015610d2557600080fd5b5061044460048036036020811015610d3c57600080fd5b50356134e6565b348015610d4f57600080fd5b506103ea6135ba565b348015610d6457600080fd5b506103ea6135c0565b348015610d7957600080fd5b506103ea60048036036040811015610d9057600080fd5b506001600160a01b0381351690602001356135c6565b348015610db257600080fd5b506103ea60048036036020811015610dc957600080fd5b50356135f0565b6005546001600160a01b031681565b60176020526000908152604090205481565b600e5481565b610dff61369d565b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce229181900360200190a150565b610e5b61369d565b60035460ff1615158115151415610e7157610eca565b6003805460ff1916821515179081905560ff1615610e8e57426002555b6003546040805160ff90921615158252517f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec59181900360200190a15b50565b60115481565b610edb61369d565b600d8190556040805182815290517f9f45df4d81199bea8f20e88707b6f7d36b8e8f20a7def01c113746f67557ffb69181900360200190a150565b60145481565b60125481565b6208aa8960eb1b81565b6001600160a01b03811660009081526016602090815260408083208054825181850281018501909352808352606094859484015b828210156110035760008481526020908190206040805161014081018252600a860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460e084015260088101546101008401526009015464ffffffffff166101208301529083529092019101610f60565b50505050905060608151604051908082528060200260200182016040528015611036578160200160208202803883390190505b5090506000805b83518110156110a45783818151811061105257fe5b602002602001015160c001516000141561109c5783818151811061107257fe5b602002602001015160a0015183838151811061108a57fe5b60209081029190910101526001909101905b60010161103d565b506060816040519080825280602002602001820160405280156110d1578160200160208202803883390190505b50905060005b82811015611112578381815181106110eb57fe5b60200260200101518282815181106110ff57fe5b60209081029190910101526001016110d7565b5093505050505b919050565b600b5481565b60048054600101908190556111376136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561118057600080fd5b505afa158015611194573d6000803e3d6000fd5b505050506040513d60208110156111aa57600080fd5b5051156111ec576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b6111f4613739565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b15801561122c57600080fd5b505afa158015611240573d6000803e3d6000fd5b505050508161124d613789565b6001600160a01b03166370a08231336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b1580156112a257600080fd5b505afa1580156112b6573d6000803e3d6000fd5b505050506040513d60208110156112cc57600080fd5b5051101561131b576040805162461bcd60e51b81526020600482015260176024820152764e6f7420656e6f75676820735553442062616c616e636560481b604482015290519081900360640190fd5b6113236147ef565b61132d85856137d6565b905061133881613919565b6000806000611346846139b5565b925092509250601154831061138c5760405162461bcd60e51b81526004018080602001828103825260288152602001806148726028913960400191505060405180910390fd5b60006113c36113bd836113b18861010001518960400151613aa590919063ffffffff16565b9063ffffffff613aa516565b846116ff565b905060008782106113d457876113d6565b815b90506113e0613789565b6001600160a01b0316639dc29fac33836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561143f57600080fd5b505af1158015611453573d6000803e3d6000fd5b50505050600080600061148284611478888c6101000151613aa590919063ffffffff16565b8b60400151613aff565b509250925092506114938383613b78565b600061149d6136e8565b6001600160a01b031663654a60ac631cd554d160e21b876208aa8960eb1b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b1580156114fd57600080fd5b505afa158015611511573d6000803e3d6000fd5b505050506040513d602081101561152757600080fd5b505160125460408051630241ebdb60e61b815290519293506000926115cc926115bf9290917384d626b2bb4d0f064067e4bf80fce7055d8f3e7b9163907af6c0916004808301926020929190829003018186803b15801561158757600080fd5b505af415801561159b573d6000803e3d6000fd5b505050506040513d60208110156115b157600080fd5b50519063ffffffff613aa516565b839063ffffffff613c9716565b90506115f08b6115e9868e60400151613cc190919063ffffffff16565b8542613d1e565b6116108b61160b838e60200151613cc190919063ffffffff16565b613dfe565b50604051339082156108fc029083906000818181858888f1935050505015801561163e573d6000803e3d6000fd5b508e6001600160a01b03167fb6e43890aeea54fbe6c0ed628e78172a0ff30bbcb1d70d8b130b12c366bac4c58f33898560405180858152602001846001600160a01b03166001600160a01b0316815260200183815260200182815260200194505050505060405180910390a2505050505050505050505060045481146116f9576040805162461bcd60e51b815260206004820152601f60248201526000805160206148cb833981519152604482015290519081900360640190fd5b50505050565b6000807384d626b2bb4d0f064067e4bf80fce7055d8f3e7b63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b15801561174657600080fd5b505af415801561175a573d6000803e3d6000fd5b505050506040513d602081101561177057600080fd5b5051601154909150600061179a61178d868463ffffffff613f2316565b879063ffffffff613cc116565b905060006117d36117c6846117ba60125488613aa590919063ffffffff16565b9063ffffffff613f2316565b859063ffffffff613cc116565b90506117e5828263ffffffff613f2316565b9450505050505b92915050565b6117fa61369d565b600580546001600160a01b0319166001600160a01b03831617905560005b60075481101561191b5760006007828154811061183157fe5b600091825260209182902001546005546040805163dacb2d0160e01b81526004810184905260248101829052601760448201527f5265736f6c766572206d697373696e6720746172676574000000000000000000606482015290519294506001600160a01b039091169263dacb2d0192608480840193829003018186803b1580156118bb57600080fd5b505afa1580156118cf573d6000803e3d6000fd5b505050506040513d60208110156118e557600080fd5b505160009182526006602052604090912080546001600160a01b0319166001600160a01b03909216919091179055600101611818565b5050565b60155481565b600061192f6147ef565b61193984846137d6565b60600151949350505050565b61194d61369d565b600c8190556040805182815290517fbb72ce8874020b3b98429d653df927cac6618ac1932384b1446bf04bf9a1b7e59181900360200190a150565b60006119926147ef565b61199c84846137d6565b90506119a781613f4d565b949350505050565b6001546001600160a01b031681565b60035460009060ff1615611a035760405162461bcd60e51b815260040180806020018281038252603c815260200180614a7e603c913960400191505060405180910390fd5b6004805460010190819055611a166136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015611a5f57600080fd5b505afa158015611a73573d6000803e3d6000fd5b505050506040513d6020811015611a8957600080fd5b505115611acb576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b611ad3613739565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015611b0b57600080fd5b505afa158015611b1f573d6000803e3d6000fd5b50505050600d54341015611b645760405162461bcd60e51b8152600401808060200182810382526048815260200180614b546048913960600191505060405180910390fd5b600f5460ff1615611bbc576040805162461bcd60e51b815260206004820152601e60248201527f4c6f616e7320617265206e6f77206265696e67206c6971756964617465640000604482015290519081900360640190fd5b600e543360009081526016602052604090205410611c0b5760405162461bcd60e51b8152600401808060200182810382526023815260200180614a0b6023913960400191505060405180910390fd5b6000611c1634612bc1565b905080841115611c575760405162461bcd60e51b81526004018080602001828103825260278152602001806149456027913960400191505060405180910390fd5b6000611c6285613fb4565b90506000611c76868363ffffffff613cc116565b9050600c54611c9087601354613aa590919063ffffffff16565b1115611ccd5760405162461bcd60e51b81526004018080602001828103825260238152602001806149e86023913960400191505060405180910390fd5b611cd5613fcb565b9450611cdf6147ef565b5060408051610140810182523381523460208201529081018790526060810183905242608082015260a08101869052600060c0820181905260095460e083015261010082018190526101208201528215611e2c57611d3b613789565b6001600160a01b031663867904b473feefeefeefeefeefeefeefeefeefeefeefeefeef856040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611dae57600080fd5b505af1158015611dc2573d6000803e3d6000fd5b50505050611dce614003565b6001600160a01b03166322bf55ef846040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015611e1357600080fd5b505af1158015611e27573d6000803e3d6000fd5b505050505b336000908152601660209081526040808320805460018082018355918552938390208551600a9095020180546001600160a01b0319166001600160a01b0390951694909417845591840151918301919091558201516002820155606082015160038201556080820151600482015560a0820151600582015560c0820151600682015560e0820151600782015561010082015160088201556101208201516009909101805464ffffffffff191664ffffffffff909216919091179055601354611ef49088613aa5565b601355611eff613789565b6001600160a01b031663867904b433846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015611f5e57600080fd5b505af1158015611f72573d6000803e3d6000fd5b505060408051898152602081018b905281513394507f58d170de3a12438e22d81380f353b2fcac86f0a708a1374deaa5c6322a95992f93509081900390910190a2505050506004548114611ffb576040805162461bcd60e51b815260206004820152601f60248201526000805160206148cb833981519152604482015290519081900360640190fd5b50919050565b60035460ff1681565b61201261369d565b6103e881106120525760405162461bcd60e51b81526004018080602001828103825260338152602001806149b56033913960400191505060405180910390fd5b600e8190556040805182815290517f59822dc2d999f6f0618e8b0db5cfc8496084574c769b09609d9b5f4394a310b69181900360200190a150565b61209561369d565b6301e1338081116120d75760405162461bcd60e51b8152600401808060200182810382526037815260200180614b1d6037913960400191505060405180910390fd5b7384d626b2bb4d0f064067e4bf80fce7055d8f3e7b63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b15801561211b57600080fd5b505af415801561212f573d6000803e3d6000fd5b505050506040513d602081101561214557600080fd5b50518111156121855760405162461bcd60e51b8152600401808060200182810382526025815260200180614aba6025913960400191505060405180910390fd5b600981905561219e816301e1338063ffffffff61404e16565b600a5560095460408051918252517fa90e14be5aa57b910aa6dc16c31ff1b5cda380ae25a793b0d3f74df6131a7d749181900360200190a150565b6000806121e46147ef565b6121ee85856137d6565b9050600061220e8261010001518360400151613aa590919063ffffffff16565b90506122376122258261222085613f4d565b612e17565b6101008401519063ffffffff613aa516565b93508160600151925050509250929050565b6005546000906001600160a01b0383811691161461226957506000611119565b60005b60075481101561235b5760006007828154811061228557fe5b6000918252602080832090910154808352600682526040928390205460055484516321f8a72160e01b81526004810184905294519295506001600160a01b03918216949116926321f8a72192602480840193829003018186803b1580156122eb57600080fd5b505afa1580156122ff573d6000803e3d6000fd5b505050506040513d602081101561231557600080fd5b50516001600160a01b031614158061234257506000818152600660205260409020546001600160a01b0316155b1561235257600092505050611119565b5060010161226c565b50600192915050565b600d5481565b60035460ff16156123ac5760405162461bcd60e51b815260040180806020018281038252603c815260200180614a7e603c913960400191505060405180910390fd5b60048054600101908190556123bf6136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561240857600080fd5b505afa15801561241c573d6000803e3d6000fd5b505050506040513d602081101561243257600080fd5b505115612474576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b600082116124b35760405162461bcd60e51b815260040180806020018281038252602981526020018061496c6029913960400191505060405180910390fd5b6124bb613739565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b1580156124f357600080fd5b505afa158015612507573d6000803e3d6000fd5b5050600f5460ff161591506125659050576040805162461bcd60e51b815260206004820152601e60248201527f4c6f616e7320617265206e6f77206265696e67206c6971756964617465640000604482015290519081900360640190fd5b61256d6147ef565b61257733856137d6565b905061258281613919565b602081015160009061259a908563ffffffff613cc116565b90506125a46147ef565b6125ae8383613dfe565b905060006125bb826139b5565b5050905060115481116125ff5760405162461bcd60e51b815260040180806020018281038252603181526020018061489a6031913960400191505060405180910390fd5b604051339087156108fc029088906000818181858888f1935050505015801561262c573d6000803e3d6000fd5b50602080830151604080518a8152928301899052828101919091525133917ffae26280bca25d80f1501a9e363c73d3845e651c9aaae54f1fc09a9dcd5f3303919081900360600190a25050505060045481146126bd576040805162461bcd60e51b815260206004820152601f60248201526000805160206148cb833981519152604482015290519081900360640190fd5b505050565b6001546001600160a01b0316331461270b5760405162461bcd60e51b81526004018080602001828103825260358152602001806148eb6035913960400191505060405180910390fd5b600054600154604080516001600160a01b03938416815292909116602083015280517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b60095481565b6008546000808080808080808080808061279c613116565b9b506009549a50600a549950600b549850600c549750600d5496506013549550601454945060155493504792506010549150600f60009054906101000a900460ff169050909192939495969798999a9b9c565b6127f76136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561284057600080fd5b505afa158015612854573d6000803e3d6000fd5b505050506040513d602081101561286a57600080fd5b5051156128ac576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b6128b4613739565b6001600160a01b031663086dabd16040518163ffffffff1660e01b815260040160006040518083038186803b1580156128ec57600080fd5b505afa158015612900573d6000803e3d6000fd5b505050508061290d613789565b6001600160a01b03166370a08231336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561296257600080fd5b505afa158015612976573d6000803e3d6000fd5b505050506040513d602081101561298c57600080fd5b505110156129db576040805162461bcd60e51b81526020600482015260176024820152764e6f7420656e6f75676820735553442062616c616e636560481b604482015290519081900360640190fd5b6129e36147ef565b6129ed84846137d6565b90506129f881613919565b6000612a168261010001518360400151613aa590919063ffffffff16565b90506000612a278261222085613f4d565b90506000612a4382856101000151613aa590919063ffffffff16565b9050600080600080612a5a89868a60400151613aff565b9350935093509350612a6a613789565b6001600160a01b0316639dc29fac338b6040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015612ac957600080fd5b505af1158015612add573d6000803e3d6000fd5b50505050612aeb8484613b78565b612af788828442613d1e565b604080518b8152602081018b905280820183905290516001600160a01b038d16917f2cebe3c4a7e8e81ca2035a6cb3ee450bb6401d9b6636652e183583f047049572919081900360600190a25050505050505050505050565b6000612b5a6147ef565b612b6484846137d6565b90506000612b90612b878361010001518460400151613aa590919063ffffffff16565b61222084613f4d565b610100830151909150612ba9908263ffffffff613aa516565b95945050505050565b6000546001600160a01b031681565b60006117ec612bce6136e8565b6001600160a01b031663ac82f6086208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015612c1757600080fd5b505afa158015612c2b573d6000803e3d6000fd5b505050506040513d6020811015612c4157600080fd5b5051612c5b612c4e613116565b859063ffffffff613c9716565b9063ffffffff613c9716565b60025481565b612c7561369d565b7384d626b2bb4d0f064067e4bf80fce7055d8f3e7b63907af6c06040518163ffffffff1660e01b815260040160206040518083038186803b158015612cb957600080fd5b505af4158015612ccd573d6000803e3d6000fd5b505050506040513d6020811015612ce357600080fd5b50518111612d2f576040805162461bcd60e51b8152602060048201526014602482015273526174696f206c657373207468616e203130302560601b604482015290519081900360640190fd5b60118190556040805182815290517f5568be83e5cf7405adf8fb39305e2cdf49c43336606d23c3e0d3fe54e205150a9181900360200190a150565b60105481565b600080600080600080600080612d846147ef565b612d8e8b8b6137d6565b9050806000015198508060200151975080604001519650806080015195508060a0015194508060c001519350612dee612ddc612b878361010001518460400151613aa590919063ffffffff16565b6101008301519063ffffffff613aa516565b9250612e07816060015184613aa590919063ffffffff16565b9150509295985092959890939650565b6000612e3e612e3183600a546140b890919063ffffffff16565b849063ffffffff61411116565b9392505050565b60035460ff1615612e875760405162461bcd60e51b815260040180806020018281038252603c815260200180614a7e603c913960400191505060405180910390fd5b60003411612ec65760405162461bcd60e51b81526004018080602001828103825260258152602001806149206025913960400191505060405180910390fd5b612ece613739565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b158015612f0657600080fd5b505afa158015612f1a573d6000803e3d6000fd5b5050600f5460ff16159150612f789050576040805162461bcd60e51b815260206004820152601e60248201527f4c6f616e7320617265206e6f77206265696e67206c6971756964617465640000604482015290519081900360640190fd5b612f806147ef565b612f8a83836137d6565b9050612f9581613919565b6020810151600090612fad903463ffffffff613aa516565b9050612fb98282613dfe565b506040805184815234602082015280820183905290516001600160a01b038616917f0b1992dffc262be88559dcaf96464e9d661d8bfca7e82f2bb73e31932a82187c919081900360600190a250505050565b61301361369d565b600b8190556040805182815290517fe7bd72551c54d568cd97b00dc52d2787b5c5d4f0070d3582c1e8ba25141f799c9181900360200190a150565b6016602052816000526040600020818154811061306757fe5b60009182526020909120600a909102018054600182015460028301546003840154600485015460058601546006870154600788015460088901546009909901546001600160a01b039098169a50959850939692959194909392909164ffffffffff168a565b6130d4614852565b60005b60075481101561311257600781815481106130ee57fe5b906000526020600020015482826018811061310557fe5b60200201526001016130d7565b5090565b600061313660085468056bc75e2d6310000061412690919063ffffffff16565b905090565b61314361369d565b6010544211613199576040805162461bcd60e51b815260206004820152601b60248201527f4265666f7265206c69717569646174696f6e20646561646c696e650000000000604482015290519081900360640190fd5b600f805460ff191682151517908190556040805160ff90921615158252517faa52cf15c1fbb778214c66f64726e141551158858d1c06ca0392c6c5869c8567916020908290030190a150565b600781815481106131f257fe5b600091825260209091200154905081565b60048054600101908190556132166136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561325f57600080fd5b505afa158015613273573d6000803e3d6000fd5b505050506040513d602081101561328957600080fd5b5051156132cb576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b6132d73383600061413b565b600454811461191b576040805162461bcd60e51b815260206004820152601f60248201526000805160206148cb833981519152604482015290519081900360640190fd5b60085481565b60048054600101908190556133346136e8565b6001600160a01b0316632528f0fe6208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561337d57600080fd5b505afa158015613391573d6000803e3d6000fd5b505050506040513d60208110156133a757600080fd5b5051156133e9576040805162461bcd60e51b815260206004820152601e6024820152600080516020614995833981519152604482015290519081900360640190fd5b600f5460ff16613440576040805162461bcd60e51b815260206004820152601760248201527f4c69717569646174696f6e206973206e6f74206f70656e000000000000000000604482015290519081900360640190fd5b61344c8383600161413b565b6040805183815233602082015281516001600160a01b038616927fde21b2a43b0a2c2109c049fb1e4bb8653fd67d0ffd74fdcb662db381f1eeab38928290030190a260045481146126bd576040805162461bcd60e51b815260206004820152601f60248201526000805160206148cb833981519152604482015290519081900360640190fd5b601881565b600f5460ff1681565b600a5481565b6134ee61369d565b683635c9adc5dea00000811115613537576040805162461bcd60e51b81526020600482015260086024820152670a8dede40d0d2ced60c31b604482015290519081900360640190fd5b68056bc75e2d6310000081101561357f576040805162461bcd60e51b8152602060048201526007602482015266546f6f206c6f7760c81b604482015290519081900360640190fd5b60088190556040805182815290517ffb0ebe8c7316e6a251494c38876d13d9a3a029273fce7964c12aa2ce078695309181900360200190a150565b60135481565b600c5481565b60006135d06147ef565b6135da84846137d6565b90506135e5816139b5565b509095945050505050565b60006117ec68056bc75e2d63100000613691612c4e61360d6136e8565b6001600160a01b031663ac82f6086208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b15801561365657600080fd5b505afa15801561366a573d6000803e3d6000fd5b505050506040513d602081101561368057600080fd5b50516008549063ffffffff61412616565b9063ffffffff61412616565b6000546001600160a01b031633146136e65760405162461bcd60e51b815260040180806020018281038252602f815260200180614a2e602f913960400191505060405180910390fd5b565b60006131366c45786368616e6765526174657360981b6040518060400160405280601d81526020017f4d697373696e672045786368616e67655261746573206164647265737300000081525061464e565b60006131366b53797374656d53746174757360a01b6040518060400160405280601c81526020017f4d697373696e672053797374656d53746174757320616464726573730000000081525061464e565b60006131366814de5b9d1a1cd554d160ba1b6040518060400160405280601981526020017f4d697373696e672053796e74687355534420616464726573730000000000000081525061464e565b6137de6147ef565b6001600160a01b0383166000908152601660209081526040808320805482518185028101850190935280835260609492939192909184015b828210156138b95760008481526020908190206040805161014081018252600a860290920180546001600160a01b03168352600180820154848601526002820154928401929092526003810154606084015260048101546080840152600581015460a0840152600681015460c0840152600781015460e084015260088101546101008401526009015464ffffffffff166101208301529083529092019101613816565b509293506000925050505b815181101561391157838282815181106138da57fe5b602002602001015160a001511415613909578181815181106138f857fe5b6020026020010151925050506117ec565b6001016138c4565b505092915050565b60008160a0015111613968576040805162461bcd60e51b8152602060048201526013602482015272131bd85b88191bd95cc81b9bdd08195e1a5cdd606a1b604482015290519081900360640190fd5b60c081015115610eca576040805162461bcd60e51b8152602060048201526013602482015272131bd85b88185b1c9958591e4818db1bdcd959606a1b604482015290519081900360640190fd5b6000806000806139d78561010001518660400151613aa590919063ffffffff16565b90506139e68161222087613f4d565b9150613a796139f36136e8565b6001600160a01b031663ac82f6086208aa8960eb1b6040518263ffffffff1660e01b81526004018082815260200191505060206040518083038186803b158015613a3c57600080fd5b505afa158015613a50573d6000803e3d6000fd5b505050506040513d6020811015613a6657600080fd5b505160208701519063ffffffff613c9716565b9250613a9b613a8e828463ffffffff613aa516565b849063ffffffff613f2316565b9350509193909250565b600082820183811015612e3e576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b6000808381868015801590613b145750600087115b15613b4f57868111613b265780613b28565b865b9450613b3a838663ffffffff613cc116565b9250613b4c818663ffffffff613cc116565b90505b8591508015613b6e57613b68828263ffffffff613cc116565b91508093505b5093509350935093565b8115613c7757613b86613789565b6001600160a01b031663867904b473feefeefeefeefeefeefeefeefeefeefeefeefeef846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b158015613bf957600080fd5b505af1158015613c0d573d6000803e3d6000fd5b50505050613c19614003565b6001600160a01b03166322bf55ef836040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b158015613c5e57600080fd5b505af1158015613c72573d6000803e3d6000fd5b505050505b801561191b57601354613c90908263ffffffff613cc116565b6013555050565b6000670de0b6b3a7640000613cb2848463ffffffff6140b816565b81613cb957fe5b049392505050565b600082821115613d18576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b83516001600160a01b03166000908152601660205260408120905b8154811015613df6578560a00151828281548110613d5357fe5b90600052602060002090600a0201600501541415613dee5784828281548110613d7857fe5b90600052602060002090600a02016002018190555083828281548110613d9a57fe5b90600052602060002090600a02016008018190555082828281548110613dbc57fe5b90600052602060002090600a020160090160006101000a81548164ffffffffff021916908364ffffffffff1602179055505b600101613d39565b505050505050565b613e066147ef565b82516001600160a01b03166000908152601660205260408120905b8154811015613911578460a00151828281548110613e3b57fe5b90600052602060002090600a0201600501541415613f1b5783828281548110613e6057fe5b90600052602060002090600a020160010181905550818181548110613e8157fe5b60009182526020918290206040805161014081018252600a90930290910180546001600160a01b031683526001810154938301939093526002830154908201526003820154606082015260048201546080820152600582015460a0820152600682015460c0820152600782015460e0820152600882015461010082015260099091015464ffffffffff1661012082015292506117ec915050565b600101613e21565b6000612e3e82613f4185670de0b6b3a764000063ffffffff6140b816565b9063ffffffff61404e16565b600080600083610120015164ffffffffff1611613f6e578260800151613f7c565b82610120015164ffffffffff165b905060008360c0015111613f9f57613f9a428263ffffffff613cc116565b612e3e565b60c0830151612e3e908263ffffffff613cc116565b60006117ec600b548361411190919063ffffffff16565b601554600090613fe290600163ffffffff613aa516565b601555601454613ff990600163ffffffff613aa516565b6014819055905090565b600061313666119959541bdbdb60ca1b6040518060400160405280601781526020017f4d697373696e6720466565506f6f6c206164647265737300000000000000000081525061464e565b60008082116140a4576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b60008284816140af57fe5b04949350505050565b6000826140c7575060006117ec565b828202828482816140d457fe5b0414612e3e5760405162461bcd60e51b8152600401808060200182810382526021815260200180614a5d6021913960400191505060405180910390fd5b6000612e3e8383670de0b6b3a76400006146f8565b6000612e3e8383670de0b6b3a7640000614735565b614143613739565b6001600160a01b0316637c3125416040518163ffffffff1660e01b815260040160006040518083038186803b15801561417b57600080fd5b505afa15801561418f573d6000803e3d6000fd5b5050505061419b6147ef565b6141a584846137d6565b90506141b081613919565b60006141d1612b878361010001518460400151613aa590919063ffffffff16565b905060006141ec828460400151613aa590919063ffffffff16565b9050600061420883856101000151613aa590919063ffffffff16565b905081614213613789565b6001600160a01b03166370a08231336040518263ffffffff1660e01b815260040180826001600160a01b03166001600160a01b0316815260200191505060206040518083038186803b15801561426857600080fd5b505afa15801561427c573d6000803e3d6000fd5b505050506040513d602081101561429257600080fd5b505110156142d15760405162461bcd60e51b815260040180806020018281038252603e815260200180614adf603e913960400191505060405180910390fd5b6142da8461475b565b6143086142f98561010001518660400151613cc190919063ffffffff16565b6013549063ffffffff613cc116565b601355614313613789565b6001600160a01b0316639dc29fac33846040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561437257600080fd5b505af1158015614386573d6000803e3d6000fd5b50505050614392613789565b6001600160a01b031663867904b473feefeefeefeefeefeefeefeefeefeefeefeefeef836040518363ffffffff1660e01b815260040180836001600160a01b03166001600160a01b0316815260200182815260200192505050600060405180830381600087803b15801561440557600080fd5b505af1158015614419573d6000803e3d6000fd5b50505050614425614003565b6001600160a01b03166322bf55ef826040518263ffffffff1660e01b815260040180828152602001915050600060405180830381600087803b15801561446a57600080fd5b505af115801561447e573d6000803e3d6000fd5b50505050602084015185156145c75760006144976136e8565b6001600160a01b031663654a60ac631cd554d160e21b866208aa8960eb1b6040518463ffffffff1660e01b815260040180848152602001838152602001828152602001935050505060206040518083038186803b1580156144f757600080fd5b505afa15801561450b573d6000803e3d6000fd5b505050506040513d602081101561452157600080fd5b505160125460408051630241ebdb60e61b81529051929350600092614581926115bf9290917384d626b2bb4d0f064067e4bf80fce7055d8f3e7b9163907af6c0916004808301926020929190829003018186803b15801561158757600080fd5b9050614593838263ffffffff613cc116565b604051909350339082156108fc029083906000818181858888f193505050501580156145c3573d6000803e3d6000fd5b5050505b84516040516001600160a01b039091169082156108fc029083906000818181858888f19350505050158015614600573d6000803e3d6000fd5b50604080518881526020810184905281516001600160a01b038b16927f3cc9f5d298758bad94536f27fa6a3033c2793e0a387a2d78e72550a3b8dacf1e928290030190a25050505050505050565b6000828152600660205260408120546001600160a01b031682816146f05760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b838110156146b557818101518382015260200161469d565b50505050905090810190601f1680156146e25780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b509392505050565b600080600a830461470f868663ffffffff6140b816565b8161471657fe5b0490506005600a825b061061472957600a015b600a9004949350505050565b60008061474f84613f4187600a870263ffffffff6140b816565b90506005600a8261471f565b80516001600160a01b03166000908152601660205260408120905b81548110156147d3578260a0015182828154811061479057fe5b90600052602060002090600a02016005015414156147cb57428282815481106147b557fe5b90600052602060002090600a0201600601819055505b600101614776565b506015546147e890600163ffffffff613cc116565b6015555050565b60405180610140016040528060006001600160a01b031681526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600064ffffffffff1681525090565b604051806103000160405280601890602082028038833950919291505056fe436f6c6c61746572616c20726174696f2061626f7665206c69717569646174696f6e20726174696f436f6c6c61746572616c20726174696f2062656c6f77206c69717569646174696f6e2061667465722077697468647261775265656e7472616e637947756172643a207265656e7472616e742063616c6c00596f75206d757374206265206e6f6d696e61746564206265666f726520796f752063616e20616363657074206f776e6572736869704465706f73697420616d6f756e74206d7573742062652067726561746572207468616e20304c6f616e20616d6f756e742065786365656473206d617820626f72726f77696e6720706f776572416d6f756e7420746f207769746864726177206d7573742062652067726561746572207468616e2030426c6f636b656420617320455448207261746520697320696e76616c696400004f776e65722063616e6e6f742073657420686967686572207468616e204143434f554e545f4c4f414e5f4c494d49545f4341504c6f616e20416d6f756e7420657863656564732074686520737570706c79206361702e45616368206163636f756e74206973206c696d6974656420746f203530206c6f616e734f6e6c792074686520636f6e7472616374206f776e6572206d617920706572666f726d207468697320616374696f6e536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f775468697320616374696f6e2063616e6e6f7420626520706572666f726d6564207768696c652074686520636f6e747261637420697320706175736564496e7465726573742063616e6e6f74206265206d6f7265207468616e203130302520415052596f7520646f206e6f742068617665207468652072657175697265642053796e74682062616c616e636520746f20636c6f73652074686973206c6f616e2e496e74657265737420726174652063616e6e6f74206265206c657373207468617420746865205345434f4e44535f494e5f415f594541524e6f7420656e6f7567682045544820746f206372656174652074686973206c6f616e2e20506c656173652073656520746865206d696e4c6f616e436f6c6c61746572616c53697a65a265627a7a72315820e6b58a3e9729ae5feebbb211c3c89855eb0a1370b08ab5b3623dfe9c496e795b64736f6c63430005100032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe00000000000000000000000061166014e3f04e40c953fe4eab9d9e40863c83ae
-----Decoded View---------------
Arg [0] : _owner (address): 0xDe910777C787903F78C89e7a0bf7F4C435cBB1Fe
Arg [1] : _resolver (address): 0x61166014E3f04E40C953fe4EAb9D9E40863C83AE
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000de910777c787903f78c89e7a0bf7f4c435cbb1fe
Arg [1] : 00000000000000000000000061166014e3f04e40c953fe4eab9d9e40863c83ae
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
ETH | Ether (ETH) | 100.00% | $3,468.56 | 0.000000000000000013 | <$0.000001 |
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.