My Name Tag:
Not Available, login to update
ContractCreator:
GENESIS at txn GENESIS_15e7d4972a3e477878a5867a47617122be2d1ff0
Txn Hash | Method |
Block
|
From
|
To
|
Value | ||||
---|---|---|---|---|---|---|---|---|---|
0xdce8e32ca00f7e85a40e1a34539c610156b41c0d7ccea8cff8754d82b0ed90b5 | Decrement Shorts | 16251835 | 609 days 4 hrs ago | 0x493906c46d7f53c22b6f47fc5a6fccb51bcb1f39 | IN | Synthetix: Collateral Manager | 0 ETH | 0.000100737335 | |
0x53b9e8ef75855a7526c4381daedd775dd772e0efc1f66d30a202cd1937af3871 | Nominate New Own... | 422728 | 855 days 4 hrs ago | 0x3c05b1239b223c969540fefc0270227a2b00e047 | IN | Synthetix: Collateral Manager | 0 ETH | 0.000782890116 | |
GENESIS_15e7d4972a3e477878a5867a47617122be2d1ff0 | 0x60806040 | 0 | 1169 days 3 hrs ago | GENESIS | IN | Create: CollateralManager | 0 ETH | 0 |
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Source Code Verified (Genesis Bytecode Match Only)
Contract Name:
CollateralManager
Compiler Version
v0.5.16
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity)
/** *Submitted for verification at Optimistic.Etherscan.io on 2021-10-12 */ /* ____ __ __ __ _ / __/__ __ ___ / /_ / / ___ / /_ (_)__ __ _\ \ / // // _ \/ __// _ \/ -_)/ __// / \ \ / /___/ \_, //_//_/\__//_//_/\__/ \__//_/ /_\_\ /___/ * Synthetix: CollateralManager.sol * * Latest source (may be newer): https://github.com/Synthetixio/synthetix/blob/master/contracts/CollateralManager.sol * Docs: https://docs.synthetix.io/contracts/CollateralManager * * Contract Dependencies: * - IAddressResolver * - ICollateralManager * - MixinResolver * - Owned * - Pausable * - State * Libraries: * - AddressSetLib * - Bytes32SetLib * - SafeDecimalMath * - SafeMath * * MIT License * =========== * * Copyright (c) 2021 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/source/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/source/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"); _; } } // https://docs.synthetix.io/contracts/source/interfaces/iaddressresolver 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); } // https://docs.synthetix.io/contracts/source/interfaces/isynth 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; } // https://docs.synthetix.io/contracts/source/interfaces/iissuer 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 getSynths(bytes32[] calldata currencyKeys) external view returns (ISynth[] memory); function synthsByAddress(address synthAddress) external view returns (bytes32); function totalIssuedSynths(bytes32 currencyKey, bool excludeOtherCollateral) 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 burnForRedemption( address deprecatedSynthProxy, address account, uint balance ) external; function liquidateDelinquentAccount( address account, uint susdAmount, address liquidator ) external returns (uint totalRedeemed, uint amountToLiquidate); } // Inheritance // Internal references // https://docs.synthetix.io/contracts/source/contracts/addressresolver contract AddressResolver is Owned, IAddressResolver { mapping(bytes32 => address) public repository; constructor(address _owner) public Owned(_owner) {} /* ========== RESTRICTED 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++) { bytes32 name = names[i]; address destination = destinations[i]; repository[name] = destination; emit AddressImported(name, destination); } } /* ========= PUBLIC FUNCTIONS ========== */ function rebuildCaches(MixinResolver[] calldata destinations) external { for (uint i = 0; i < destinations.length; i++) { destinations[i].rebuildCache(); } } /* ========== VIEWS ========== */ function areAddressesImported(bytes32[] calldata names, address[] calldata destinations) external view returns (bool) { for (uint i = 0; i < names.length; i++) { if (repository[names[i]] != destinations[i]) { return false; } } return true; } 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)); } /* ========== EVENTS ========== */ event AddressImported(bytes32 name, address destination); } // Internal references // https://docs.synthetix.io/contracts/source/contracts/mixinresolver contract MixinResolver { AddressResolver public resolver; mapping(bytes32 => address) private addressCache; constructor(address _resolver) internal { resolver = AddressResolver(_resolver); } /* ========== INTERNAL FUNCTIONS ========== */ function combineArrays(bytes32[] memory first, bytes32[] memory second) internal pure returns (bytes32[] memory combination) { combination = new bytes32[](first.length + second.length); for (uint i = 0; i < first.length; i++) { combination[i] = first[i]; } for (uint j = 0; j < second.length; j++) { combination[first.length + j] = second[j]; } } /* ========== PUBLIC FUNCTIONS ========== */ // Note: this function is public not external in order for it to be overridden and invoked via super in subclasses function resolverAddressesRequired() public view returns (bytes32[] memory addresses) {} function rebuildCache() public { bytes32[] memory requiredAddresses = resolverAddressesRequired(); // The resolver must call this function whenver it updates its state for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[i]; // Note: can only be invoked once the resolver has all the targets needed added address destination = resolver.requireAndGetAddress(name, string(abi.encodePacked("Resolver missing target: ", name))); addressCache[name] = destination; emit CacheUpdated(name, destination); } } /* ========== VIEWS ========== */ function isResolverCached() external view returns (bool) { bytes32[] memory requiredAddresses = resolverAddressesRequired(); for (uint i = 0; i < requiredAddresses.length; i++) { bytes32 name = requiredAddresses[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; } /* ========== INTERNAL FUNCTIONS ========== */ function requireAndGetAddress(bytes32 name) internal view returns (address) { address _foundAddress = addressCache[name]; require(_foundAddress != address(0), string(abi.encodePacked("Missing address: ", name))); return _foundAddress; } /* ========== EVENTS ========== */ event CacheUpdated(bytes32 name, address destination); } interface ICollateralManager { // Manager information function hasCollateral(address collateral) external view returns (bool); function isSynthManaged(bytes32 currencyKey) external view returns (bool); // State information function long(bytes32 synth) external view returns (uint amount); function short(bytes32 synth) external view returns (uint amount); function totalLong() external view returns (uint susdValue, bool anyRateIsInvalid); function totalShort() external view returns (uint susdValue, bool anyRateIsInvalid); function getBorrowRate() external view returns (uint borrowRate, bool anyRateIsInvalid); function getShortRate(bytes32 synth) external view returns (uint shortRate, bool rateIsInvalid); function getRatesAndTime(uint index) external view returns ( uint entryRate, uint lastRate, uint lastUpdated, uint newIndex ); function getShortRatesAndTime(bytes32 currency, uint index) external view returns ( uint entryRate, uint lastRate, uint lastUpdated, uint newIndex ); function exceedsDebtLimit(uint amount, bytes32 currency) external view returns (bool canIssue, bool anyRateIsInvalid); function areSynthsAndCurrenciesSet(bytes32[] calldata requiredSynthNamesInResolver, bytes32[] calldata synthKeys) external view returns (bool); function areShortableSynthsSet(bytes32[] calldata requiredSynthNamesInResolver, bytes32[] calldata synthKeys) external view returns (bool); // Loans function getNewLoanId() external returns (uint id); // Manager mutative function addCollaterals(address[] calldata collaterals) external; function removeCollaterals(address[] calldata collaterals) external; function addSynths(bytes32[] calldata synthNamesInResolver, bytes32[] calldata synthKeys) external; function removeSynths(bytes32[] calldata synths, bytes32[] calldata synthKeys) external; function addShortableSynths(bytes32[] calldata requiredSynthNamesInResolver, bytes32[] calldata synthKeys) external; function removeShortableSynths(bytes32[] calldata synths) external; // State mutative function incrementLongs(bytes32 synth, uint amount) external; function decrementLongs(bytes32 synth, uint amount) external; function incrementShorts(bytes32 synth, uint amount) external; function decrementShorts(bytes32 synth, uint amount) external; function accrueInterest( uint interestIndex, bytes32 currency, bool isShort ) external returns (uint difference, uint index); function updateBorrowRatesCollateral(uint rate) external; function updateShortRatesCollateral(bytes32 currency, uint rate) external; } // https://docs.synthetix.io/contracts/source/libraries/addresssetlib/ library AddressSetLib { struct AddressSet { address[] elements; mapping(address => uint) indices; } function contains(AddressSet storage set, address candidate) internal view returns (bool) { if (set.elements.length == 0) { return false; } uint index = set.indices[candidate]; return index != 0 || set.elements[0] == candidate; } function getPage( AddressSet storage set, uint index, uint pageSize ) internal view returns (address[] memory) { // NOTE: This implementation should be converted to slice operators if the compiler is updated to v0.6.0+ uint endIndex = index + pageSize; // The check below that endIndex <= index handles overflow. // If the page extends past the end of the list, truncate it. if (endIndex > set.elements.length) { endIndex = set.elements.length; } if (endIndex <= index) { return new address[](0); } uint n = endIndex - index; // We already checked for negative overflow. address[] memory page = new address[](n); for (uint i; i < n; i++) { page[i] = set.elements[i + index]; } return page; } function add(AddressSet storage set, address element) internal { // Adding to a set is an idempotent operation. if (!contains(set, element)) { set.indices[element] = set.elements.length; set.elements.push(element); } } function remove(AddressSet storage set, address element) internal { require(contains(set, element), "Element not in set."); // Replace the removed element with the last element of the list. uint index = set.indices[element]; uint lastIndex = set.elements.length - 1; // We required that element is in the list, so it is not empty. if (index != lastIndex) { // No need to shift the last element if it is the one we want to delete. address shiftedElement = set.elements[lastIndex]; set.elements[index] = shiftedElement; set.indices[shiftedElement] = index; } set.elements.pop(); delete set.indices[element]; } } // https://docs.synthetix.io/contracts/source/libraries/bytes32setlib/ library Bytes32SetLib { struct Bytes32Set { bytes32[] elements; mapping(bytes32 => uint) indices; } function contains(Bytes32Set storage set, bytes32 candidate) internal view returns (bool) { if (set.elements.length == 0) { return false; } uint index = set.indices[candidate]; return index != 0 || set.elements[0] == candidate; } function getPage( Bytes32Set storage set, uint index, uint pageSize ) internal view returns (bytes32[] memory) { // NOTE: This implementation should be converted to slice operators if the compiler is updated to v0.6.0+ uint endIndex = index + pageSize; // The check below that endIndex <= index handles overflow. // If the page extends past the end of the list, truncate it. if (endIndex > set.elements.length) { endIndex = set.elements.length; } if (endIndex <= index) { return new bytes32[](0); } uint n = endIndex - index; // We already checked for negative overflow. bytes32[] memory page = new bytes32[](n); for (uint i; i < n; i++) { page[i] = set.elements[i + index]; } return page; } function add(Bytes32Set storage set, bytes32 element) internal { // Adding to a set is an idempotent operation. if (!contains(set, element)) { set.indices[element] = set.elements.length; set.elements.push(element); } } function remove(Bytes32Set storage set, bytes32 element) internal { require(contains(set, element), "Element not in set."); // Replace the removed element with the last element of the list. uint index = set.indices[element]; uint lastIndex = set.elements.length - 1; // We required that element is in the list, so it is not empty. if (index != lastIndex) { // No need to shift the last element if it is the one we want to delete. bytes32 shiftedElement = set.elements[lastIndex]; set.elements[index] = shiftedElement; set.indices[shiftedElement] = index; } set.elements.pop(); delete set.indices[element]; } } /** * @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/source/libraries/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; } // Computes `a - b`, setting the value to 0 if b > a. function floorsub(uint a, uint b) internal pure returns (uint) { return b >= a ? 0 : a - b; } } // Inheritance // https://docs.synthetix.io/contracts/source/contracts/state contract State is Owned { // the address of the contract that can modify variables // this can only be changed by the owner of this contract address public associatedContract; constructor(address _associatedContract) internal { // This contract is abstract, and thus cannot be instantiated directly require(owner != address(0), "Owner must be set"); associatedContract = _associatedContract; emit AssociatedContractUpdated(_associatedContract); } /* ========== SETTERS ========== */ // Change the associated contract to a new address function setAssociatedContract(address _associatedContract) external onlyOwner { associatedContract = _associatedContract; emit AssociatedContractUpdated(_associatedContract); } /* ========== MODIFIERS ========== */ modifier onlyAssociatedContract { require(msg.sender == associatedContract, "Only the associated contract can perform this action"); _; } /* ========== EVENTS ========== */ event AssociatedContractUpdated(address associatedContract); } pragma experimental ABIEncoderV2; // Inheritance // Libraries contract CollateralManagerState is Owned, State { using SafeMath for uint; using SafeDecimalMath for uint; struct Balance { uint long; uint short; } uint public totalLoans; uint[] public borrowRates; uint public borrowRatesLastUpdated; mapping(bytes32 => uint[]) public shortRates; mapping(bytes32 => uint) public shortRatesLastUpdated; // The total amount of long and short for a synth, mapping(bytes32 => Balance) public totalIssuedSynths; constructor(address _owner, address _associatedContract) public Owned(_owner) State(_associatedContract) { borrowRates.push(0); borrowRatesLastUpdated = block.timestamp; } function incrementTotalLoans() external onlyAssociatedContract returns (uint) { totalLoans = totalLoans.add(1); return totalLoans; } function long(bytes32 synth) external view onlyAssociatedContract returns (uint) { return totalIssuedSynths[synth].long; } function short(bytes32 synth) external view onlyAssociatedContract returns (uint) { return totalIssuedSynths[synth].short; } function incrementLongs(bytes32 synth, uint256 amount) external onlyAssociatedContract { totalIssuedSynths[synth].long = totalIssuedSynths[synth].long.add(amount); } function decrementLongs(bytes32 synth, uint256 amount) external onlyAssociatedContract { totalIssuedSynths[synth].long = totalIssuedSynths[synth].long.sub(amount); } function incrementShorts(bytes32 synth, uint256 amount) external onlyAssociatedContract { totalIssuedSynths[synth].short = totalIssuedSynths[synth].short.add(amount); } function decrementShorts(bytes32 synth, uint256 amount) external onlyAssociatedContract { totalIssuedSynths[synth].short = totalIssuedSynths[synth].short.sub(amount); } // Borrow rates, one array here for all currencies. function getRateAt(uint index) public view returns (uint) { return borrowRates[index]; } function getRatesLength() public view returns (uint) { return borrowRates.length; } function updateBorrowRates(uint rate) external onlyAssociatedContract { borrowRates.push(rate); borrowRatesLastUpdated = block.timestamp; } function ratesLastUpdated() public view returns (uint) { return borrowRatesLastUpdated; } function getRatesAndTime(uint index) external view returns ( uint entryRate, uint lastRate, uint lastUpdated, uint newIndex ) { newIndex = getRatesLength(); entryRate = getRateAt(index); lastRate = getRateAt(newIndex - 1); lastUpdated = ratesLastUpdated(); } // Short rates, one array per currency. function addShortCurrency(bytes32 currency) external onlyAssociatedContract { if (shortRates[currency].length > 0) {} else { shortRates[currency].push(0); shortRatesLastUpdated[currency] = block.timestamp; } } function removeShortCurrency(bytes32 currency) external onlyAssociatedContract { delete shortRates[currency]; } function getShortRateAt(bytes32 currency, uint index) internal view returns (uint) { return shortRates[currency][index]; } function getShortRatesLength(bytes32 currency) public view returns (uint) { return shortRates[currency].length; } function updateShortRates(bytes32 currency, uint rate) external onlyAssociatedContract { shortRates[currency].push(rate); shortRatesLastUpdated[currency] = block.timestamp; } function shortRateLastUpdated(bytes32 currency) internal view returns (uint) { return shortRatesLastUpdated[currency]; } function getShortRatesAndTime(bytes32 currency, uint index) external view returns ( uint entryRate, uint lastRate, uint lastUpdated, uint newIndex ) { newIndex = getShortRatesLength(currency); entryRate = getShortRateAt(currency, index); lastRate = getShortRateAt(currency, newIndex - 1); lastUpdated = shortRateLastUpdated(currency); } } // 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 rateAndInvalid(bytes32 currencyKey) external view returns (uint rate, bool isInvalid); 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; } // https://docs.synthetix.io/contracts/source/interfaces/ierc20 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); } // Inheritance // Libraries // Internal references contract CollateralManager is ICollateralManager, Owned, Pausable, MixinResolver { /* ========== LIBRARIES ========== */ using SafeMath for uint; using SafeDecimalMath for uint; using AddressSetLib for AddressSetLib.AddressSet; using Bytes32SetLib for Bytes32SetLib.Bytes32Set; /* ========== CONSTANTS ========== */ bytes32 private constant sUSD = "sUSD"; uint private constant SECONDS_IN_A_YEAR = 31556926 * 1e18; // Flexible storage names bytes32 public constant CONTRACT_NAME = "CollateralManager"; bytes32 internal constant COLLATERAL_SYNTHS = "collateralSynth"; /* ========== STATE VARIABLES ========== */ // Stores debt balances and borrow rates. CollateralManagerState public state; // The set of all collateral contracts. AddressSetLib.AddressSet internal _collaterals; // The set of all available currency keys. Bytes32SetLib.Bytes32Set internal _currencyKeys; // The set of all synths issuable by the various collateral contracts Bytes32SetLib.Bytes32Set internal _synths; // Map from currency key to synth contract name. mapping(bytes32 => bytes32) public synthsByKey; // The set of all synths that are shortable. Bytes32SetLib.Bytes32Set internal _shortableSynths; mapping(bytes32 => bytes32) public shortableSynthsByKey; // The factor that will scale the utilisation ratio. uint public utilisationMultiplier = 1e18; // The maximum amount of debt in sUSD that can be issued by non snx collateral. uint public maxDebt; // The rate that determines the skew limit maximum. uint public maxSkewRate; // The base interest rate applied to all borrows. uint public baseBorrowRate; // The base interest rate applied to all shorts. uint public baseShortRate; /* ---------- Address Resolver Configuration ---------- */ bytes32 private constant CONTRACT_ISSUER = "Issuer"; bytes32 private constant CONTRACT_EXRATES = "ExchangeRates"; bytes32[24] private addressesToCache = [CONTRACT_ISSUER, CONTRACT_EXRATES]; /* ========== CONSTRUCTOR ========== */ constructor( CollateralManagerState _state, address _owner, address _resolver, uint _maxDebt, uint _maxSkewRate, uint _baseBorrowRate, uint _baseShortRate ) public Owned(_owner) Pausable() MixinResolver(_resolver) { owner = msg.sender; state = _state; setMaxDebt(_maxDebt); setMaxSkewRate(_maxSkewRate); setBaseBorrowRate(_baseBorrowRate); setBaseShortRate(_baseShortRate); owner = _owner; } /* ========== VIEWS ========== */ function resolverAddressesRequired() public view returns (bytes32[] memory addresses) { bytes32[] memory staticAddresses = new bytes32[](2); staticAddresses[0] = CONTRACT_ISSUER; staticAddresses[1] = CONTRACT_EXRATES; bytes32[] memory shortAddresses; uint length = _shortableSynths.elements.length; if (length > 0) { shortAddresses = new bytes32[](length); for (uint i = 0; i < length; i++) { shortAddresses[i] = _shortableSynths.elements[i]; } } bytes32[] memory synthAddresses = combineArrays(shortAddresses, _synths.elements); if (synthAddresses.length > 0) { addresses = combineArrays(synthAddresses, staticAddresses); } else { addresses = staticAddresses; } } // helper function to check whether synth "by key" is a collateral issued by multi-collateral function isSynthManaged(bytes32 currencyKey) external view returns (bool) { return synthsByKey[currencyKey] != bytes32(0); } /* ---------- Related Contracts ---------- */ function _issuer() internal view returns (IIssuer) { return IIssuer(requireAndGetAddress(CONTRACT_ISSUER)); } function _exchangeRates() internal view returns (IExchangeRates) { return IExchangeRates(requireAndGetAddress(CONTRACT_EXRATES)); } function _synth(bytes32 synthName) internal view returns (ISynth) { return ISynth(requireAndGetAddress(synthName)); } /* ---------- Manager Information ---------- */ function hasCollateral(address collateral) public view returns (bool) { return _collaterals.contains(collateral); } function hasAllCollaterals(address[] memory collaterals) public view returns (bool) { for (uint i = 0; i < collaterals.length; i++) { if (!hasCollateral(collaterals[i])) { return false; } } return true; } /* ---------- State Information ---------- */ function long(bytes32 synth) external view returns (uint amount) { return state.long(synth); } function short(bytes32 synth) external view returns (uint amount) { return state.short(synth); } function totalLong() public view returns (uint susdValue, bool anyRateIsInvalid) { bytes32[] memory synths = _currencyKeys.elements; if (synths.length > 0) { for (uint i = 0; i < synths.length; i++) { bytes32 synth = synths[i]; if (synth == sUSD) { susdValue = susdValue.add(state.long(synth)); } else { (uint rate, bool invalid) = _exchangeRates().rateAndInvalid(synth); uint amount = state.long(synth).multiplyDecimal(rate); susdValue = susdValue.add(amount); if (invalid) { anyRateIsInvalid = true; } } } } } function totalShort() public view returns (uint susdValue, bool anyRateIsInvalid) { bytes32[] memory synths = _shortableSynths.elements; if (synths.length > 0) { for (uint i = 0; i < synths.length; i++) { bytes32 synth = _synth(synths[i]).currencyKey(); (uint rate, bool invalid) = _exchangeRates().rateAndInvalid(synth); uint amount = state.short(synth).multiplyDecimal(rate); susdValue = susdValue.add(amount); if (invalid) { anyRateIsInvalid = true; } } } } function totalLongAndShort() public view returns (uint susdValue, bool anyRateIsInvalid) { bytes32[] memory currencyKeys = _currencyKeys.elements; if (currencyKeys.length > 0) { (uint[] memory rates, bool invalid) = _exchangeRates().ratesAndInvalidForCurrencies(currencyKeys); for (uint i = 0; i < rates.length; i++) { uint longAmount = state.long(currencyKeys[i]).multiplyDecimal(rates[i]); uint shortAmount = state.short(currencyKeys[i]).multiplyDecimal(rates[i]); susdValue = susdValue.add(longAmount).add(shortAmount); if (invalid) { anyRateIsInvalid = true; } } } } function getBorrowRate() public view returns (uint borrowRate, bool anyRateIsInvalid) { // get the snx backed debt. uint snxDebt = _issuer().totalIssuedSynths(sUSD, true); // now get the non snx backed debt. (uint nonSnxDebt, bool ratesInvalid) = totalLong(); // the total. uint totalDebt = snxDebt.add(nonSnxDebt); // now work out the utilisation ratio, and divide through to get a per second value. uint utilisation = nonSnxDebt.divideDecimal(totalDebt).divideDecimal(SECONDS_IN_A_YEAR); // scale it by the utilisation multiplier. uint scaledUtilisation = utilisation.multiplyDecimal(utilisationMultiplier); // finally, add the base borrow rate. borrowRate = scaledUtilisation.add(baseBorrowRate); anyRateIsInvalid = ratesInvalid; } function getShortRate(bytes32 synthKey) public view returns (uint shortRate, bool rateIsInvalid) { rateIsInvalid = _exchangeRates().rateIsInvalid(synthKey); // Get the long and short supply. uint longSupply = IERC20(address(_synth(shortableSynthsByKey[synthKey]))).totalSupply(); uint shortSupply = state.short(synthKey); // In this case, the market is skewed long so its free to short. if (longSupply > shortSupply) { return (0, rateIsInvalid); } // Otherwise workout the skew towards the short side. uint skew = shortSupply.sub(longSupply); // Divide through by the size of the market. uint proportionalSkew = skew.divideDecimal(longSupply.add(shortSupply)).divideDecimal(SECONDS_IN_A_YEAR); // Enforce a skew limit maximum. uint maxSkewLimit = proportionalSkew.multiplyDecimal(maxSkewRate); // Finally, add the base short rate. shortRate = maxSkewLimit.add(baseShortRate); } function getRatesAndTime(uint index) public view returns ( uint entryRate, uint lastRate, uint lastUpdated, uint newIndex ) { (entryRate, lastRate, lastUpdated, newIndex) = state.getRatesAndTime(index); } function getShortRatesAndTime(bytes32 currency, uint index) public view returns ( uint entryRate, uint lastRate, uint lastUpdated, uint newIndex ) { (entryRate, lastRate, lastUpdated, newIndex) = state.getShortRatesAndTime(currency, index); } function exceedsDebtLimit(uint amount, bytes32 currency) external view returns (bool canIssue, bool anyRateIsInvalid) { uint usdAmount = _exchangeRates().effectiveValue(currency, amount, sUSD); (uint longAndShortValue, bool invalid) = totalLongAndShort(); return (longAndShortValue.add(usdAmount) <= maxDebt, invalid); } /* ========== MUTATIVE FUNCTIONS ========== */ /* ---------- SETTERS ---------- */ function setUtilisationMultiplier(uint _utilisationMultiplier) public onlyOwner { require(_utilisationMultiplier > 0, "Must be greater than 0"); utilisationMultiplier = _utilisationMultiplier; emit UtilisationMultiplierUpdated(utilisationMultiplier); } function setMaxDebt(uint _maxDebt) public onlyOwner { require(_maxDebt > 0, "Must be greater than 0"); maxDebt = _maxDebt; emit MaxDebtUpdated(maxDebt); } function setMaxSkewRate(uint _maxSkewRate) public onlyOwner { maxSkewRate = _maxSkewRate; emit MaxSkewRateUpdated(maxSkewRate); } function setBaseBorrowRate(uint _baseBorrowRate) public onlyOwner { baseBorrowRate = _baseBorrowRate; emit BaseBorrowRateUpdated(baseBorrowRate); } function setBaseShortRate(uint _baseShortRate) public onlyOwner { baseShortRate = _baseShortRate; emit BaseShortRateUpdated(baseShortRate); } /* ---------- LOANS ---------- */ function getNewLoanId() external onlyCollateral returns (uint id) { id = state.incrementTotalLoans(); } /* ---------- MANAGER ---------- */ function addCollaterals(address[] calldata collaterals) external onlyOwner { for (uint i = 0; i < collaterals.length; i++) { if (!_collaterals.contains(collaterals[i])) { _collaterals.add(collaterals[i]); emit CollateralAdded(collaterals[i]); } } } function removeCollaterals(address[] calldata collaterals) external onlyOwner { for (uint i = 0; i < collaterals.length; i++) { if (_collaterals.contains(collaterals[i])) { _collaterals.remove(collaterals[i]); emit CollateralRemoved(collaterals[i]); } } } function addSynths(bytes32[] calldata synthNamesInResolver, bytes32[] calldata synthKeys) external onlyOwner { require(synthNamesInResolver.length == synthKeys.length, "Input array length mismatch"); for (uint i = 0; i < synthNamesInResolver.length; i++) { if (!_synths.contains(synthNamesInResolver[i])) { bytes32 synthName = synthNamesInResolver[i]; _synths.add(synthName); _currencyKeys.add(synthKeys[i]); synthsByKey[synthKeys[i]] = synthName; emit SynthAdded(synthName); } } rebuildCache(); } function areSynthsAndCurrenciesSet(bytes32[] calldata requiredSynthNamesInResolver, bytes32[] calldata synthKeys) external view returns (bool) { if (_synths.elements.length != requiredSynthNamesInResolver.length) { return false; } for (uint i = 0; i < requiredSynthNamesInResolver.length; i++) { if (!_synths.contains(requiredSynthNamesInResolver[i])) { return false; } if (synthsByKey[synthKeys[i]] != requiredSynthNamesInResolver[i]) { return false; } } return true; } function removeSynths(bytes32[] calldata synthNamesInResolver, bytes32[] calldata synthKeys) external onlyOwner { require(synthNamesInResolver.length == synthKeys.length, "Input array length mismatch"); for (uint i = 0; i < synthNamesInResolver.length; i++) { if (_synths.contains(synthNamesInResolver[i])) { // Remove it from the the address set lib. _synths.remove(synthNamesInResolver[i]); _currencyKeys.remove(synthKeys[i]); delete synthsByKey[synthKeys[i]]; emit SynthRemoved(synthNamesInResolver[i]); } } } function addShortableSynths(bytes32[] calldata requiredSynthNamesInResolver, bytes32[] calldata synthKeys) external onlyOwner { require(requiredSynthNamesInResolver.length == synthKeys.length, "Input array length mismatch"); for (uint i = 0; i < requiredSynthNamesInResolver.length; i++) { bytes32 synth = requiredSynthNamesInResolver[i]; if (!_shortableSynths.contains(synth)) { // Add it to the address set lib. _shortableSynths.add(synth); shortableSynthsByKey[synthKeys[i]] = synth; emit ShortableSynthAdded(synth); // now the associated synth key to the CollateralManagerState state.addShortCurrency(synthKeys[i]); } } rebuildCache(); } function areShortableSynthsSet(bytes32[] calldata requiredSynthNamesInResolver, bytes32[] calldata synthKeys) external view returns (bool) { require(requiredSynthNamesInResolver.length == synthKeys.length, "Input array length mismatch"); if (_shortableSynths.elements.length != requiredSynthNamesInResolver.length) { return false; } // now check everything added to external state contract for (uint i = 0; i < synthKeys.length; i++) { if (state.getShortRatesLength(synthKeys[i]) == 0) { return false; } } return true; } function removeShortableSynths(bytes32[] calldata synths) external onlyOwner { for (uint i = 0; i < synths.length; i++) { if (_shortableSynths.contains(synths[i])) { // Remove it from the the address set lib. _shortableSynths.remove(synths[i]); bytes32 synthKey = _synth(synths[i]).currencyKey(); delete shortableSynthsByKey[synthKey]; state.removeShortCurrency(synthKey); emit ShortableSynthRemoved(synths[i]); } } } /* ---------- STATE MUTATIONS ---------- */ function updateBorrowRates(uint rate) internal { state.updateBorrowRates(rate); } function updateShortRates(bytes32 currency, uint rate) internal { state.updateShortRates(currency, rate); } function updateBorrowRatesCollateral(uint rate) external onlyCollateral { state.updateBorrowRates(rate); } function updateShortRatesCollateral(bytes32 currency, uint rate) external onlyCollateral { state.updateShortRates(currency, rate); } function incrementLongs(bytes32 synth, uint amount) external onlyCollateral { state.incrementLongs(synth, amount); } function decrementLongs(bytes32 synth, uint amount) external onlyCollateral { state.decrementLongs(synth, amount); } function incrementShorts(bytes32 synth, uint amount) external onlyCollateral { state.incrementShorts(synth, amount); } function decrementShorts(bytes32 synth, uint amount) external onlyCollateral { state.decrementShorts(synth, amount); } function accrueInterest( uint interestIndex, bytes32 currency, bool isShort ) external onlyCollateral returns (uint difference, uint index) { // 1. Get the rates we need. (uint entryRate, uint lastRate, uint lastUpdated, uint newIndex) = isShort ? getShortRatesAndTime(currency, interestIndex) : getRatesAndTime(interestIndex); // 2. Get the instantaneous rate. (uint rate, bool invalid) = isShort ? getShortRate(currency) : getBorrowRate(); require(!invalid, "Invalid rate"); // 3. Get the time since we last updated the rate. // TODO: consider this in the context of l2 time. uint timeDelta = block.timestamp.sub(lastUpdated).mul(1e18); // 4. Get the latest cumulative rate. F_n+1 = F_n + F_last uint latestCumulative = lastRate.add(rate.multiplyDecimal(timeDelta)); // 5. Return the rate differential and the new interest index. difference = latestCumulative.sub(entryRate); index = newIndex; // 5. Update rates with the lastest cumulative rate. This also updates the time. isShort ? updateShortRates(currency, latestCumulative) : updateBorrowRates(latestCumulative); } /* ========== MODIFIERS ========== */ modifier onlyCollateral { bool isMultiCollateral = hasCollateral(msg.sender); require(isMultiCollateral, "Only collateral contracts"); _; } // ========== EVENTS ========== event MaxDebtUpdated(uint maxDebt); event MaxSkewRateUpdated(uint maxSkewRate); event LiquidationPenaltyUpdated(uint liquidationPenalty); event BaseBorrowRateUpdated(uint baseBorrowRate); event BaseShortRateUpdated(uint baseShortRate); event UtilisationMultiplierUpdated(uint utilisationMultiplier); event CollateralAdded(address collateral); event CollateralRemoved(address collateral); event SynthAdded(bytes32 synth); event SynthRemoved(bytes32 synth); event ShortableSynthAdded(bytes32 synth); event ShortableSynthRemoved(bytes32 synth); }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract CollateralManagerState","name":"_state","type":"address"},{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_resolver","type":"address"},{"internalType":"uint256","name":"_maxDebt","type":"uint256"},{"internalType":"uint256","name":"_maxSkewRate","type":"uint256"},{"internalType":"uint256","name":"_baseBorrowRate","type":"uint256"},{"internalType":"uint256","name":"_baseShortRate","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"baseBorrowRate","type":"uint256"}],"name":"BaseBorrowRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"baseShortRate","type":"uint256"}],"name":"BaseShortRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"name","type":"bytes32"},{"indexed":false,"internalType":"address","name":"destination","type":"address"}],"name":"CacheUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collateral","type":"address"}],"name":"CollateralAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"collateral","type":"address"}],"name":"CollateralRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"liquidationPenalty","type":"uint256"}],"name":"LiquidationPenaltyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxDebt","type":"uint256"}],"name":"MaxDebtUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"maxSkewRate","type":"uint256"}],"name":"MaxSkewRateUpdated","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"synth","type":"bytes32"}],"name":"ShortableSynthAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"synth","type":"bytes32"}],"name":"ShortableSynthRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"synth","type":"bytes32"}],"name":"SynthAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"synth","type":"bytes32"}],"name":"SynthRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"utilisationMultiplier","type":"uint256"}],"name":"UtilisationMultiplierUpdated","type":"event"},{"constant":true,"inputs":[],"name":"CONTRACT_NAME","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"acceptOwnership","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"interestIndex","type":"uint256"},{"internalType":"bytes32","name":"currency","type":"bytes32"},{"internalType":"bool","name":"isShort","type":"bool"}],"name":"accrueInterest","outputs":[{"internalType":"uint256","name":"difference","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"collaterals","type":"address[]"}],"name":"addCollaterals","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32[]","name":"requiredSynthNamesInResolver","type":"bytes32[]"},{"internalType":"bytes32[]","name":"synthKeys","type":"bytes32[]"}],"name":"addShortableSynths","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32[]","name":"synthNamesInResolver","type":"bytes32[]"},{"internalType":"bytes32[]","name":"synthKeys","type":"bytes32[]"}],"name":"addSynths","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32[]","name":"requiredSynthNamesInResolver","type":"bytes32[]"},{"internalType":"bytes32[]","name":"synthKeys","type":"bytes32[]"}],"name":"areShortableSynthsSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32[]","name":"requiredSynthNamesInResolver","type":"bytes32[]"},{"internalType":"bytes32[]","name":"synthKeys","type":"bytes32[]"}],"name":"areSynthsAndCurrenciesSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"baseBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"baseShortRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"synth","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"decrementLongs","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"synth","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"decrementShorts","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"currency","type":"bytes32"}],"name":"exceedsDebtLimit","outputs":[{"internalType":"bool","name":"canIssue","type":"bool"},{"internalType":"bool","name":"anyRateIsInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"getBorrowRate","outputs":[{"internalType":"uint256","name":"borrowRate","type":"uint256"},{"internalType":"bool","name":"anyRateIsInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"getNewLoanId","outputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRatesAndTime","outputs":[{"internalType":"uint256","name":"entryRate","type":"uint256"},{"internalType":"uint256","name":"lastRate","type":"uint256"},{"internalType":"uint256","name":"lastUpdated","type":"uint256"},{"internalType":"uint256","name":"newIndex","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"synthKey","type":"bytes32"}],"name":"getShortRate","outputs":[{"internalType":"uint256","name":"shortRate","type":"uint256"},{"internalType":"bool","name":"rateIsInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"currency","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getShortRatesAndTime","outputs":[{"internalType":"uint256","name":"entryRate","type":"uint256"},{"internalType":"uint256","name":"lastRate","type":"uint256"},{"internalType":"uint256","name":"lastUpdated","type":"uint256"},{"internalType":"uint256","name":"newIndex","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address[]","name":"collaterals","type":"address[]"}],"name":"hasAllCollaterals","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"address","name":"collateral","type":"address"}],"name":"hasCollateral","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"synth","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"incrementLongs","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"synth","type":"bytes32"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"incrementShorts","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"isResolverCached","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"currencyKey","type":"bytes32"}],"name":"isSynthManaged","outputs":[{"internalType":"bool","name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastPauseTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"synth","type":"bytes32"}],"name":"long","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxDebt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxSkewRate","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":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":[],"name":"rebuildCache","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"address[]","name":"collaterals","type":"address[]"}],"name":"removeCollaterals","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32[]","name":"synths","type":"bytes32[]"}],"name":"removeShortableSynths","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32[]","name":"synthNamesInResolver","type":"bytes32[]"},{"internalType":"bytes32[]","name":"synthKeys","type":"bytes32[]"}],"name":"removeSynths","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":[],"name":"resolverAddressesRequired","outputs":[{"internalType":"bytes32[]","name":"addresses","type":"bytes32[]"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_baseBorrowRate","type":"uint256"}],"name":"setBaseBorrowRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_baseShortRate","type":"uint256"}],"name":"setBaseShortRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_maxDebt","type":"uint256"}],"name":"setMaxDebt","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"_maxSkewRate","type":"uint256"}],"name":"setMaxSkewRate","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":"uint256","name":"_utilisationMultiplier","type":"uint256"}],"name":"setUtilisationMultiplier","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"synth","type":"bytes32"}],"name":"short","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"shortableSynthsByKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"state","outputs":[{"internalType":"contract CollateralManagerState","name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"synthsByKey","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalLong","outputs":[{"internalType":"uint256","name":"susdValue","type":"uint256"},{"internalType":"bool","name":"anyRateIsInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalLongAndShort","outputs":[{"internalType":"uint256","name":"susdValue","type":"uint256"},{"internalType":"bool","name":"anyRateIsInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"totalShort","outputs":[{"internalType":"uint256","name":"susdValue","type":"uint256"},{"internalType":"bool","name":"anyRateIsInvalid","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"updateBorrowRatesCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"internalType":"bytes32","name":"currency","type":"bytes32"},{"internalType":"uint256","name":"rate","type":"uint256"}],"name":"updateShortRatesCollateral","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"utilisationMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"}]
Contract Creation Code
6080604052670de0b6b3a7640000601062000019620004ed565b5050604051604080820190526524b9b9bab2b960d11b81526c45786368616e6765526174657360981b60208201526200005790601590600262000551565b5034801562000070576000806200006d6200059f565b50505b506040516200539b3803806200539b833981016040819052620000939162000706565b84866001600160a01b038116620000d25760405162461bcd60e51b8152600401620000be9062000937565b60405180910390620000cf6200059f565b50505b806000600181620000e26200060c565b816001600160a01b0302191690836001600160a01b031602179062000106620004ed565b5050507fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c6000826040516200013d929190620008db565b60405180910390a15060008080620001546200060c565b906101000a90046001600160a01b03166001600160a01b03161415620001a25760405162461bcd60e51b81526004016200018e9062000925565b604051809103906200019f6200059f565b50505b80600361010081620001b36200060c565b816001600160a01b0302191690836001600160a01b0316021790620001d7620004ed565b505050505a620001e662000659565b6000600181620001f56200060c565b816001600160a01b0302191690836001600160a01b031602179062000219620004ed565b50505086600560006101000a81620002306200060c565b816001600160a01b0302191690836001600160a01b031602179062000254620004ed565b5050506200026884620002e860201b60201c565b6200027c836001600160e01b036200038a16565b62000290826001600160e01b03620003db16565b620002a4816001600160e01b036200042c16565b856000600181620002b46200060c565b816001600160a01b0302191690836001600160a01b0316021790620002d8620004ed565b50505050505050505050620009cd565b620002fb6001600160e01b036200047d16565b60008111620003325760405162461bcd60e51b81526004016200031e9062000901565b604051809103906200032f6200059f565b50505b8080601162000340620004ed565b5050507f3620cc91bd75c6d3d752b529a1b98b38789dd2b81a13ece55801abc83531a77f6011620003706200060c565b6040516200037f919062000949565b60405180910390a150565b6200039d6001600160e01b036200047d16565b80806012620003ab620004ed565b5050507f465c1047eec44dfecb260ee7e6187823a7cbdd80f19082eb56c35967b16d8e266012620003706200060c565b620003ee6001600160e01b036200047d16565b80806013620003fc620004ed565b5050507f08f9599493340b8255c7698bded59e30079641f4a9531613ec020557392470046013620003706200060c565b6200043f6001600160e01b036200047d16565b808060146200044d620004ed565b5050507fe2695216766f2a627e90e17041ac2f085fd60ea503345b039f815c69bcbcccc96014620003706200060c565b6000806200048a6200060c565b906101000a90046001600160a01b03166001600160a01b03165a620004ae62000659565b6001600160a01b031614620004eb5760405162461bcd60e51b8152600401620004d79062000913565b60405180910390620004e86200059f565b50505b565b6322bd64c0598160e01b8152836004820152846024820152600081604483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b60005b60408110156200054c5760008282015260200162000533565b505050565b82601881019282156200058d579160200282015b828111156200058d578251826200057b620004ed565b50509160200191906001019062000565565b506200059b929150620006a0565b5090565b632a2a7adb598160e01b8152600481016020815285602082015260005b86811015620005d9578086015182820160400152602001620005bc565b506020828760640184336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b505050565b6303daa959598160e01b8152836004820152602081602483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051600082529350602062000533565b6373509064598160e01b8152602081600483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051600082529350602062000533565b620006ca91905b808211156200059b5760008082620006be620004ed565b505050600101620006a7565b90565b600081519050620006de8162000995565b92915050565b600081519050620006de81620009b7565b600081519050620006de81620009c2565b600080600080600080600060e0888a0312156200072d576000806200072a6200059f565b50505b60006200073b8a8a620006e4565b97505060206200074e8a828b01620006cd565b9650506040620007618a828b01620006cd565b9550506060620007748a828b01620006f5565b9450506080620007878a828b01620006f5565b93505060a06200079a8a828b01620006f5565b92505060c0620007ad8a828b01620006f5565b91505092959891949750929550565b620007c78162000988565b82525050565b620007c78162000962565b6000620007e760168362000959565b7f4d7573742062652067726561746572207468616e203000000000000000000000815260200192915050565b600062000822602f8362000959565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b60006200087560118362000959565b7013dddb995c881b5d5cdd081899481cd95d607a1b815260200192915050565b6000620008a460198362000959565b7f4f776e657220616464726573732063616e6e6f74206265203000000000000000815260200192915050565b620007c781620006ca565b60408101620008eb8285620007bc565b620008fa6020830184620007cd565b9392505050565b60208082528101620006de81620007d8565b60208082528101620006de8162000813565b60208082528101620006de8162000866565b60208082528101620006de8162000895565b60208101620006de8284620008d0565b90815260200190565b6000620006de826200097c565b6000620006de8262000962565b6001600160a01b031690565b6000620006de826200096f565b620009a08162000962565b8114620009b4576000806200054c6200059f565b50565b620009a0816200096f565b620009a081620006ca565b6149be80620009dd6000396000f3fe6080604052348015610019576000806100166139ca565b50505b506004361061034b5760003560e01c80638da5cb5b116101c1578063bbb601cd1161010d578063e31f27c1116100ab578063eb94bbde11610085578063eb94bbde146106b9578063edc77dc2146106cc578063ee81f790146106d4578063ffa749cd146106e75761034b565b8063e31f27c114610680578063e32261fe14610693578063e50a31b3146106a65761034b565b8063c9e18015116100e7578063c9e180151461064a578063ca969f2314610652578063d0064c0014610665578063d2f004751461066d5761034b565b8063bbb601cd14610627578063bf3866821461063a578063c19d93fb146106425761034b565b8063af07aa9d1161017a578063b4d6cb4011610154578063b4d6cb40146105d8578063b9e2451c146105f9578063ba1c5e801461060c578063baa38036146106145761034b565b8063af07aa9d146105aa578063b38988f7146105bd578063b3b46732146105d05761034b565b80638da5cb5b1461055957806391b4ded91461056157806393a72fbe146105695780639f7eac371461057c578063a894a14b1461058f578063ad79a858146105a25761034b565b8063614d08f81161029b57806379ba509711610239578063899ffef411610213578063899ffef4146105165780638b173e811461052b5780638d1341901461053e5780638d6ad02d146105515761034b565b806379ba5097146104da57806380054666146104e25780638471db13146105035761034b565b806372e18b6a1161027557806372e18b6a1461049957806374185360146104ac578063744d646e146104b45780637687402a146104c75761034b565b8063614d08f81461046b5780636526941b14610473578063710388d1146104865761034b565b806323d60e2e116103085780634db7764c116102e25780634db7764c146104335780635246f2b91461043b57806353a47bb71461044e5780635c975abb146104635761034b565b806323d60e2e146103eb5780632af64bd3146103fe57806338245377146104135761034b565b806303f048b01461035957806304f3bcec146103855780630c9c81a11461039a5780631627540c146103af57806316c38b3c146103c25780631e33fc6b146103d5575b6000806103566139ca565b50505b61036c610367366004614150565b6106fa565b60405161037c9493929190614880565b60405180910390f35b61038d6107c8565b60405161037c91906147b1565b6103ad6103a8366004614150565b6107e7565b005b6103ad6103bd366004613f2b565b610841565b6103ad6103d0366004614102565b6108aa565b6103dd610979565b60405161037c929190614740565b6103ad6103f9366004614014565b610ca2565b610406610de4565b60405161037c91906146fb565b610426610421366004614150565b610f66565b60405161037c9190614724565b610426610f81565b6103ad61044936600461419e565b610f8b565b610456611070565b60405161037c91906146c1565b61040661107c565b610426611095565b6103ad610481366004614150565b6110ad565b6103ad610494366004614014565b611121565b6104066104a7366004614014565b611250565b6103ad6112fa565b6104066104c2366004613fcd565b611492565b6103ad6104d536600461419e565b6114dc565b6103ad611564565b6104f56104f03660046141ff565b6116c4565b60405161037c92919061476e565b610406610511366004614150565b61181f565b61051e61183e565b60405161037c91906146ea565b6103ad610539366004614150565b6119ea565b6103ad61054c366004614150565b611a2c565b610426611b0e565b610456611b18565b610426611b23565b610406610577366004614014565b611b2d565b6103ad61058a366004614150565b611c69565b6103ad61059d366004614014565b611cdd565b6103dd611e86565b61036c6105b836600461419e565b6120e6565b6104066105cb366004613f2b565b6121b7565b6104266121d0565b6105eb6105e636600461419e565b6122c9565b60405161037c929190614709565b610426610607366004614150565b6123bb565b6103dd6123d3565b6103ad610622366004614150565b612524565b6103ad610635366004613f79565b612566565b610426612641565b61038d61264b565b610426612657565b6103ad610660366004613f79565b612661565b610426612887565b61042661067b366004614150565b612891565b6103ad61068e36600461419e565b61294d565b6104266106a1366004614150565b6129d5565b6103ad6106b436600461419e565b612a1d565b6103ad6106c736600461419e565b612aa5565b6103dd612b2d565b6103dd6106e2366004614150565b612d69565b6103ad6106f5366004613f79565b61300e565b600080808080600561070a613a35565b906101000a90046001600160a01b03166001600160a01b03166303f048b0866040518263ffffffff1660e01b81526004016107459190614724565b6080604051808303818680610758613a90565b15801561076d5760008061076a6139ca565b50505b505a610777613adc565b5050505050158015610796573d6000803e3d60006107936139ca565b50505b50505050604051601f3d908101601f191682016040526107b99190810190614255565b92989197509550909350915050565b600160036107d4613a35565b906101000a90046001600160a01b031681565b6107ef6130c7565b808060136107fb613bc7565b5050507f08f9599493340b8255c7698bded59e30079641f4a9531613ec020557392470046013610829613a35565b6040516108369190614724565b60405180910390a150565b6108496130c7565b8060018080610856613a35565b816001600160a01b0302191690836001600160a01b0316021790610878613bc7565b5050507f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce228160405161083691906146c1565b6108b26130c7565b600060036108be613a35565b906101000a900460ff16151581151514156108d857610976565b8060036001816108e6613a35565b8160ff021916908315150217906108fb613bc7565b505050600360009061090b613a35565b906101000a900460ff1615610932575a610923613c15565b80600261092e613bc7565b5050505b7f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec56000600361095f613a35565b906101000a900460ff1660405161083691906146fb565b50565b6000806060600880610989613a35565b8060200260200160405190810160405281815291906020830182806109ac613a35565b80156109de57602002820191906000526020600020905b816109cc613a35565b815260200190600101908083116109c3575b50505050509050600081511115610c9d5760005b8151811015610c9b576000828281518110610a0957fe5b60200260200101519050631cd554d160e21b811415610af457610aed60006005610a31613a35565b906101000a90046001600160a01b03166001600160a01b031663d2f00475836040518263ffffffff1660e01b8152600401610a6c9190614724565b6020604051808303818680610a7f613a90565b158015610a9457600080610a916139ca565b50505b505a610a9e613adc565b5050505050158015610abd573d6000803e3d6000610aba6139ca565b50505b50505050604051601f3d908101601f19168201604052610ae09190810190614177565b869063ffffffff61312b16565b9450610c92565b600080610aff613169565b6001600160a01b0316630c71cd23846040518263ffffffff1660e01b8152600401610b2a9190614724565b60408051808303818680610b3c613a90565b158015610b5157600080610b4e6139ca565b50505b505a610b5b613adc565b5050505050158015610b7a573d6000803e3d6000610b776139ca565b50505b50505050604051601f3d908101601f19168201604052610b9d91908101906141d7565b915091506000610c6f836005600090610bb4613a35565b906101000a90046001600160a01b03166001600160a01b031663d2f00475876040518263ffffffff1660e01b8152600401610bef9190614724565b6020604051808303818680610c02613a90565b158015610c1757600080610c146139ca565b50505b505a610c21613adc565b5050505050158015610c40573d6000803e3d6000610c3d6139ca565b50505b50505050604051601f3d908101601f19168201604052610c639190810190614177565b9063ffffffff61318916565b9050610c81888263ffffffff61312b16565b97508115610c8e57600196505b5050505b506001016109f2565b505b509091565b610caa6130c7565b828114610cdb5760405162461bcd60e51b8152600401610cc9906147d0565b60405180910390610cd86139ca565b50505b60005b83811015610dd557610d0c858583818110610cf557fe5b90506020020135600a6131b390919063ffffffff16565b610dcd576000858583818110610d1e57fe5b905060200201359050610d3b81600a61322290919063ffffffff16565b610d61848484818110610d4a57fe5b90506020020135600861322290919063ffffffff16565b80600c6000868686818110610d7257fe5b9050602002013581526020019081526020016000208190610d91613bc7565b5050507f87f8a613724bd8be7a9139e4c83bc8d58fedee7206e2d7077849f5988d78759981604051610dc39190614724565b60405180910390a1505b600101610cde565b50610dde6112fa565b50505050565b60006060610df061183e565b905060005b8151811015610f5c576000828281518110610e0c57fe5b60200260200101516000818152600460205290915060409020600090610e30613a35565b6001600160a01b036101009290920a90041660016003610e4e613a35565b906101000a90046001600160a01b03166001600160a01b03166321f8a721836040518263ffffffff1660e01b8152600401610e899190614724565b6020604051808303818680610e9c613a90565b158015610eb157600080610eae6139ca565b50505b505a610ebb613adc565b5050505050158015610eda573d6000803e3d6000610ed76139ca565b50505b50505050604051601f3d908101601f19168201604052610efd9190810190613f52565b6001600160a01b0316141580610f4257506000818152600460205260408120600090610f27613a35565b906101000a90046001600160a01b03166001600160a01b0316145b15610f535760009350505050610f63565b50600101610df5565b5060019150505b90565b600c6020528060005260406000209050610f7e613a35565b81565b6014610f7e613a35565b6000610f995a6105cb613c5b565b905080610fca5760405162461bcd60e51b8152600401610fb890614860565b60405180910390610fc76139ca565b50505b60006005610fd6613a35565b906101000a90046001600160a01b03166001600160a01b0316635246f2b984846040518363ffffffff1660e01b815260040161101392919061476e565b60006040518083038160008780611028613a90565b15801561103d5760008061103a6139ca565b50505b505a611047613ca1565b505050505050158015611067573d6000803e3d60006110646139ca565b50505b50505050505050565b600060016107d4613a35565b60006003611088613a35565b906101000a900460ff1681565b7021b7b63630ba32b930b626b0b730b3b2b960791b81565b6110b56130c7565b600081116110e75760405162461bcd60e51b81526004016110d590614830565b604051809103906110e46139ca565b50505b808060116110f3613bc7565b5050507f3620cc91bd75c6d3d752b529a1b98b38789dd2b81a13ece55801abc83531a77f6011610829613a35565b6111296130c7565b82811461115a5760405162461bcd60e51b8152600401611148906147d0565b604051809103906111576139ca565b50505b60005b8381101561124957611174858583818110610cf557fe5b156112415761119f85858381811061118857fe5b90506020020135600a61329490919063ffffffff16565b6111c58383838181106111ae57fe5b90506020020135600861329490919063ffffffff16565b600c60008484848181106111d557fe5b9050602002013581526020019081526020016000206000906111f5613bc7565b50507f788aff97f65e6ddeee9246c47d08b819813066c87876a912c79baddffb138f0a85858381811061122457fe5b905060200201356040516112389190614724565b60405180910390a15b60010161115d565b5050505050565b600083600a8061125e613a35565b90501461126d575060006112f2565b60005b848110156112ec57611287868683818110610cf557fe5b6112955760009150506112f2565b8585828181106112a157fe5b90506020020135600c60008686858181106112b857fe5b9050602002013581526020019081526020016000206112d5613a35565b146112e45760009150506112f2565b600101611270565b50600190505b949350505050565b606061130461183e565b905060005b815181101561148e57600082828151811061132057fe5b60200260200101519050600060016003611338613a35565b906101000a90046001600160a01b03166001600160a01b031663dacb2d01838460405160200161136891906146b6565b6040516020818303038152906040526040518363ffffffff1660e01b815260040161139492919061474e565b60206040518083038186806113a7613a90565b1580156113bc576000806113b96139ca565b50505b505a6113c6613adc565b50505050501580156113e5573d6000803e3d60006113e26139ca565b50505b50505050604051601f3d908101601f191682016040526114089190810190613f52565b60008381526004602052909150819060409020600181611426613a35565b816001600160a01b0302191690836001600160a01b0316021790611448613bc7565b5050507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68828260405161147c929190614732565b60405180910390a15050600101611309565b5050565b6000805b82518110156114d1576114bb8382815181106114ae57fe5b60200260200101516121b7565b6114c95760009150506114d7565b600101611496565b50600190505b919050565b60006114ea5a6105cb613c5b565b90508061151b5760405162461bcd60e51b815260040161150990614860565b604051809103906115186139ca565b50505b60006005611527613a35565b906101000a90046001600160a01b03166001600160a01b0316632462063984846040518363ffffffff1660e01b815260040161101392919061476e565b60006001611570613a35565b906101000a90046001600160a01b03166001600160a01b03165a611592613c5b565b6001600160a01b0316146115ca5760405162461bcd60e51b81526004016115b8906147e0565b604051809103906115c76139ca565b50505b7fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c6000806115f6613a35565b906101000a90046001600160a01b03166001600090611613613a35565b906101000a90046001600160a01b03166040516116319291906146cf565b60405180910390a160006001611645613a35565b906101000a90046001600160a01b03166000806101000a81611665613a35565b816001600160a01b0302191690836001600160a01b0316021790611687613bc7565b5050506000600160006101000a8161169d613a35565b816001600160a01b0302191690836001600160a01b03160217906116bf613bc7565b505050565b60008060006116d55a6105cb613c5b565b9050806117065760405162461bcd60e51b81526004016116f490614860565b604051809103906117036139ca565b50505b6000806000808761171f5761171a8a6106fa565b611729565b611729898b6120e6565b935093509350935060008089611746576117416123d3565b61174f565b61174f8b612d69565b9150915080156117835760405162461bcd60e51b815260040161177190614870565b604051809103906117806139ca565b50505b60006117b6670de0b6b3a76400006117aa875a61179e613c15565b9063ffffffff6133c916565b9063ffffffff61340316565b905060006117da6117cd858463ffffffff61318916565b889063ffffffff61312b16565b90506117ec818963ffffffff6133c916565b9a508499508b611804576117ff8161343d565b61180e565b61180e8d826134d5565b505050505050505050935093915050565b6000818152600c6020528060408120611836613a35565b141592915050565b606080600260405190808252806020026020018201604052801561186c578160200160208202803883390190505b5090506524b9b9bab2b960d11b8160008151811061188657fe5b6020026020010181815250506c45786368616e6765526174657360981b816001815181106118b057fe5b602090810291909101015260606000600d806118ca613a35565b915050801561195257806040519080825280602002602001820160405280156118fd578160200160208202803883390190505b50915060005b8181101561195057600d8181611917613a35565b811061191f57fe5b90600052602060002001611931613a35565b83828151811061193d57fe5b6020908102919091010152600101611903565b505b60606119c283600a80611963613a35565b806020026020016040519081016040528181529190602083018280611986613a35565b80156119b857602002820191906000526020600020905b816119a6613a35565b8152602001906001019080831161199d575b505050505061351e565b90506000815111156119df576119d8818561351e565b94506119e3565b8394505b5050505090565b6119f26130c7565b808060146119fe613bc7565b5050507fe2695216766f2a627e90e17041ac2f085fd60ea503345b039f815c69bcbcccc96014610829613a35565b6000611a3a5a6105cb613c5b565b905080611a6b5760405162461bcd60e51b8152600401611a5990614860565b60405180910390611a686139ca565b50505b60006005611a77613a35565b906101000a90046001600160a01b03166001600160a01b031663f53037b6836040518263ffffffff1660e01b8152600401611ab29190614724565b60006040518083038160008780611ac7613a90565b158015611adc57600080611ad96139ca565b50505b505a611ae6613ca1565b505050505050158015611b06573d6000803e3d6000611b036139ca565b50505b505050505050565b6012610f7e613a35565b6000806107d4613a35565b6002610f7e613a35565b6000838214611b605760405162461bcd60e51b8152600401611b4e906147d0565b60405180910390611b5d6139ca565b50505b83600d80611b6c613a35565b905014611b7b575060006112f2565b60005b828110156112ec5760006005611b92613a35565b906101000a90046001600160a01b03166001600160a01b031663a0356f6e858584818110611bbc57fe5b905060200201356040518263ffffffff1660e01b8152600401611bdf9190614724565b6020604051808303818680611bf2613a90565b158015611c0757600080611c046139ca565b50505b505a611c11613adc565b5050505050158015611c30573d6000803e3d6000611c2d6139ca565b50505b50505050604051601f3d908101601f19168201604052611c539190810190614177565b611c615760009150506112f2565b600101611b7e565b611c716130c7565b60008111611ca35760405162461bcd60e51b8152600401611c9190614830565b60405180910390611ca06139ca565b50505b80806010611caf613bc7565b5050507fcf53b24098da84a81615c6450c76443db743815230079981717af7ff9d647fd46010610829613a35565b611ce56130c7565b828114611d165760405162461bcd60e51b8152600401611d04906147d0565b60405180910390611d136139ca565b50505b60005b83811015610dd5576000858583818110611d2f57fe5b905060200201359050611d4c81600d6131b390919063ffffffff16565b611e7d57611d61600d8263ffffffff61322216565b80600f6000868686818110611d7257fe5b9050602002013581526020019081526020016000208190611d91613bc7565b5050507fa71e21d8a72d99830e0d382f042d37e6a20c8a33ec3185affcaf6586e9a0187a81604051611dc39190614724565b60405180910390a160006005611dd7613a35565b906101000a90046001600160a01b03166001600160a01b031663ed039154858585818110611e0157fe5b905060200201356040518263ffffffff1660e01b8152600401611e249190614724565b60006040518083038160008780611e39613a90565b158015611e4e57600080611e4b6139ca565b50505b505a611e58613ca1565b505050505050158015611e78573d6000803e3d6000611e756139ca565b50505b505050505b50600101611d19565b6000806060600d80611e96613a35565b806020026020016040519081016040528181529190602083018280611eb9613a35565b8015611eeb57602002820191906000526020600020905b81611ed9613a35565b81526020019060010190808311611ed0575b50505050509050600081511115610c9d5760005b8151811015610c9b576000611f26838381518110611f1957fe5b60200260200101516135da565b6001600160a01b031663dbd06c856040518163ffffffff1660e01b81526004016020604051808303818680611f59613a90565b158015611f6e57600080611f6b6139ca565b50505b505a611f78613adc565b5050505050158015611f97573d6000803e3d6000611f946139ca565b50505b50505050604051601f3d908101601f19168201604052611fba9190810190614177565b9050600080611fc7613169565b6001600160a01b0316630c71cd23846040518263ffffffff1660e01b8152600401611ff29190614724565b60408051808303818680612004613a90565b158015612019576000806120166139ca565b50505b505a612023613adc565b5050505050158015612042573d6000803e3d600061203f6139ca565b50505b50505050604051601f3d908101601f1916820160405261206591908101906141d7565b9150915060006120b783600560009061207c613a35565b906101000a90046001600160a01b03166001600160a01b031663e32261fe876040518263ffffffff1660e01b8152600401610bef9190614724565b90506120c9888263ffffffff61312b16565b975081156120d657600196505b505060019092019150611eff9050565b60008080808060056120f6613a35565b906101000a90046001600160a01b03166001600160a01b031663af07aa9d87876040518363ffffffff1660e01b815260040161213392919061476e565b6080604051808303818680612146613a90565b15801561215b576000806121586139ca565b50505b505a612165613adc565b5050505050158015612184573d6000803e3d60006121816139ca565b50505b50505050604051601f3d908101601f191682016040526121a79190810190614255565b9299919850965090945092505050565b60006121ca60068363ffffffff6135e516565b92915050565b6000806121df5a6105cb613c5b565b9050806122105760405162461bcd60e51b81526004016121fe90614860565b6040518091039061220d6139ca565b50505b6000600561221c613a35565b906101000a90046001600160a01b03166001600160a01b0316638c5825036040518163ffffffff1660e01b815260040160206040518083038160008780612261613a90565b158015612276576000806122736139ca565b50505b505a612280613ca1565b5050505050501580156122a0573d6000803e3d600061229d6139ca565b50505b50505050604051601f3d908101601f191682016040526122c39190810190614177565b91505090565b60008060006122d6613169565b6001600160a01b031663654a60ac8587631cd554d160e21b6040518463ffffffff1660e01b815260040161230c93929190614789565b602060405180830381868061231f613a90565b158015612334576000806123316139ca565b50505b505a61233e613adc565b505050505015801561235d573d6000803e3d600061235a6139ca565b50505b50505050604051601f3d908101601f191682016040526123809190810190614177565b905060008061238d612b2d565b91509150601161239b613a35565b6123ab838563ffffffff61312b16565b11159450925050505b9250929050565b600f6020528060005260406000209050610f7e613a35565b60008060006123e061367c565b6001600160a01b0316637b1001b7631cd554d160e21b60016040518363ffffffff1660e01b8152600401612415929190614740565b6020604051808303818680612428613a90565b15801561243d5760008061243a6139ca565b50505b505a612447613adc565b5050505050158015612466573d6000803e3d60006124636139ca565b50505b50505050604051601f3d908101601f191682016040526124899190810190614177565b9050600080612496610979565b909250905060006124ad848463ffffffff61312b16565b905060006124dc6a1a1a7062e5185d7e3800006124d0868563ffffffff61369016565b9063ffffffff61369016565b905060006124fa60106124ed613a35565b839063ffffffff61318916565b90506125166013612509613a35565b829063ffffffff61312b16565b989397509295505050505050565b61252c6130c7565b80806012612538613bc7565b5050507f465c1047eec44dfecb260ee7e6187823a7cbdd80f19082eb56c35967b16d8e266012610829613a35565b61256e6130c7565b60005b818110156116bf576125ab83838381811061258857fe5b905060200201602061259d9190810190613f2b565b60069063ffffffff6135e516565b612639576125e18383838181106125be57fe5b90506020020160206125d39190810190613f2b565b60069063ffffffff6136ba16565b7f7db05e63d635a68c62fd7fd8f3107ae8ab584a383e102d1bd8a40f4c977e465f83838381811061260e57fe5b90506020020160206126239190810190613f2b565b60405161263091906146c1565b60405180910390a15b600101612571565b6013610f7e613a35565b600060056107d4613a35565b6010610f7e613a35565b6126696130c7565b60005b818110156116bf5761269a83838381811061268357fe5b90506020020135600d6131b390919063ffffffff16565b1561287f576126c58383838181106126ae57fe5b90506020020135600d61329490919063ffffffff16565b60006126e28484848181106126d657fe5b905060200201356135da565b6001600160a01b031663dbd06c856040518163ffffffff1660e01b81526004016020604051808303818680612715613a90565b15801561272a576000806127276139ca565b50505b505a612734613adc565b5050505050158015612753573d6000803e3d60006127506139ca565b50505b50505050604051601f3d908101601f191682016040526127769190810190614177565b6000818152600f60205290915060409020600090612792613bc7565b505060056000906127a1613a35565b906101000a90046001600160a01b03166001600160a01b0316636431e0bd826040518263ffffffff1660e01b81526004016127dc9190614724565b600060405180830381600087806127f1613a90565b158015612806576000806128036139ca565b50505b505a612810613ca1565b505050505050158015612830573d6000803e3d600061282d6139ca565b50505b505050507f23caa21d7c1015aa7051e1ae4a09f99de36dab4545dfec5f4dde3a54173a123b84848481811061286157fe5b905060200201356040516128759190614724565b60405180910390a1505b60010161266c565b6011610f7e613a35565b600080600561289e613a35565b906101000a90046001600160a01b03166001600160a01b031663d2f00475836040518263ffffffff1660e01b81526004016128d99190614724565b60206040518083038186806128ec613a90565b158015612901576000806128fe6139ca565b50505b505a61290b613adc565b505050505015801561292a573d6000803e3d60006129276139ca565b50505b50505050604051601f3d908101601f191682016040526121ca9190810190614177565b600061295b5a6105cb613c5b565b90508061298c5760405162461bcd60e51b815260040161297a90614860565b604051809103906129896139ca565b50505b60006005612998613a35565b906101000a90046001600160a01b03166001600160a01b031663e31f27c184846040518363ffffffff1660e01b815260040161101392919061476e565b60008060056129e2613a35565b906101000a90046001600160a01b03166001600160a01b031663e32261fe836040518263ffffffff1660e01b81526004016128d99190614724565b6000612a2b5a6105cb613c5b565b905080612a5c5760405162461bcd60e51b8152600401612a4a90614860565b60405180910390612a596139ca565b50505b60006005612a68613a35565b906101000a90046001600160a01b03166001600160a01b031663e50a31b384846040518363ffffffff1660e01b815260040161101392919061476e565b6000612ab35a6105cb613c5b565b905080612ae45760405162461bcd60e51b8152600401612ad290614860565b60405180910390612ae16139ca565b50505b60006005612af0613a35565b906101000a90046001600160a01b03166001600160a01b031663eb94bbde84846040518363ffffffff1660e01b815260040161101392919061476e565b6000806060600880612b3d613a35565b806020026020016040519081016040528181529190602083018280612b60613a35565b8015612b9257602002820191906000526020600020905b81612b80613a35565b81526020019060010190808311612b77575b50505050509050600081511115610c9d5760606000612baf613169565b6001600160a01b031663c8e5bbd5846040518263ffffffff1660e01b8152600401612bda91906146ea565b6000604051808303818680612bed613a90565b158015612c0257600080612bff6139ca565b50505b505a612c0c613adc565b5050505050158015612c2b573d6000803e3d6000612c286139ca565b50505b505050506040513d6000823e601f3d908101601f19168201604052612c53919081019061409f565b909250905060005b8251811015612d61576000612cd7848381518110612c7557fe5b602002602001015160006005612c89613a35565b906101000a90046001600160a01b03166001600160a01b031663d2f00475888681518110612cb357fe5b60200260200101516040518263ffffffff1660e01b8152600401610bef9190614724565b90506000612d28858481518110612cea57fe5b602002602001015160006005612cfe613a35565b906101000a90046001600160a01b03166001600160a01b031663e32261fe898781518110612cb357fe5b9050612d4a81612d3e8a8563ffffffff61312b16565b9063ffffffff61312b16565b97508315612d5757600196505b5050600101612c5b565b505050509091565b600080612d74613169565b6001600160a01b0316632528f0fe846040518263ffffffff1660e01b8152600401612d9f9190614724565b6020604051808303818680612db2613a90565b158015612dc757600080612dc46139ca565b50505b505a612dd1613adc565b5050505050158015612df0573d6000803e3d6000612ded6139ca565b50505b50505050604051601f3d908101601f19168201604052612e139190810190614129565b6000848152600f602052909150612e3460408220612e2f613a35565b6135da565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b81526004016020604051808303818680612e67613a90565b158015612e7c57600080612e796139ca565b50505b505a612e86613adc565b5050505050158015612ea5573d6000803e3d6000612ea26139ca565b50505b50505050604051601f3d908101601f19168201604052612ec89190810190614177565b90506000806005612ed7613a35565b906101000a90046001600160a01b03166001600160a01b031663e32261fe866040518263ffffffff1660e01b8152600401612f129190614724565b6020604051808303818680612f25613a90565b158015612f3a57600080612f376139ca565b50505b505a612f44613adc565b5050505050158015612f63573d6000803e3d6000612f606139ca565b50505b50505050604051601f3d908101601f19168201604052612f869190810190614177565b905080821115612f9c5750600092506130099050565b6000612fae828463ffffffff6133c916565b90506000612fe16a1a1a7062e5185d7e3800006124d0612fd4878763ffffffff61312b16565b859063ffffffff61369016565b90506000612ff260126124ed613a35565b90506130016014612509613a35565b965050505050505b915091565b6130166130c7565b60005b818110156116bf5761303083838381811061258857fe5b156130bf5761306783838381811061304457fe5b90506020020160206130599190810190613f2b565b60069063ffffffff61375b16565b7fd89d2ee68ab04dca0193f48a4aff55e20fa5ec0429a8a8c1c51b8dad6178a59383838381811061309457fe5b90506020020160206130a99190810190613f2b565b6040516130b691906146c1565b60405180910390a15b600101613019565b6000806130d2613a35565b906101000a90046001600160a01b03166001600160a01b03165a6130f4613c5b565b6001600160a01b0316146131295760405162461bcd60e51b815260040161311a90614840565b6040518091039061148e6139ca565b565b6000828201838110156131625760405162461bcd60e51b8152600401613150906147f0565b6040518091039061315f6139ca565b50505b9392505050565b60006131846c45786368616e6765526174657360981b6138fc565b905090565b6000670de0b6b3a76400006131a4848463ffffffff61340316565b816131ab57fe5b049392505050565b600082806131bf613a35565b151590506131cf575060006121ca565b600082815260018401602052604081206131e7613a35565b9050801515806112f2575082846000816131ff613a35565b811061320757fe5b90600052602060002001613219613a35565b14949350505050565b61322c82826131b3565b61148e57818061323a613a35565b600083815260018501602052909150604090208190613257613bc7565b508291508390508060018161326a613a35565b018082613275613bc7565b5050600092835291600019830191506020902091929101611249613bc7565b61329e82826131b3565b6132cc5760405162461bcd60e51b81526004016132ba90614800565b604051809103906132c96139ca565b50505b600081815260018301602052604081206132e4613a35565b90506000600184806132f4613a35565b905003905080821461337557600084828161330d613a35565b811061331557fe5b90600052602060002001613327613a35565b905080858481613335613a35565b811061333d57fe5b906000526020600020018190613351613bc7565b5050506000818152600186016020528390604090208190613370613bc7565b505050505b838061337f613a35565b8061338657fe5b600190038181906000526020600020016000906133a1613bc7565b5050906133ac613bc7565b505060008381526001850160205260409020600090611b06613bc7565b6000828211156133fd5760405162461bcd60e51b81526004016133eb90614810565b604051809103906133fa6139ca565b50505b50900390565b600082613412575060006121ca565b8282028284828161341f57fe5b04146131625760405162461bcd60e51b815260040161315090614850565b60006005613449613a35565b906101000a90046001600160a01b03166001600160a01b031663f53037b6826040518263ffffffff1660e01b81526004016134849190614724565b60006040518083038160008780613499613a90565b1580156134ae576000806134ab6139ca565b50505b505a6134b8613ca1565b505050505050158015611249573d6000803e3d60006110676139ca565b600060056134e1613a35565b906101000a90046001600160a01b03166001600160a01b0316632462063983836040518363ffffffff1660e01b8152600401611ab292919061476e565b6060815183510160405190808252806020026020018201604052801561354e578160200160208202803883390190505b50905060005b83518110156135905783818151811061356957fe5b602002602001015182828151811061357d57fe5b6020908102919091010152600101613554565b5060005b82518110156135d3578281815181106135a957fe5b60200260200101518282865101815181106135c057fe5b6020908102919091010152600101613594565b5092915050565b60006121ca826138fc565b600082806135f1613a35565b15159050613601575060006121ca565b6001600160a01b03821660009081526001840160205260408120613623613a35565b9050801515806112f257506001600160a01b03831684600081613644613a35565b811061364c57fe5b90600052602060002001600090613661613a35565b6001600160a01b036101009290920a90041614949350505050565b60006131846524b9b9bab2b960d11b6138fc565b6000613162826136ae85670de0b6b3a764000063ffffffff61340316565b9063ffffffff61398316565b6136c482826135e5565b61148e5781806136d2613a35565b6001600160a01b0383166000908152600185016020529091506040902081906136f9613bc7565b508291508390508060018161370c613a35565b018082613717613bc7565b5050600092835291600019830191506020902091929101600181613739613a35565b816001600160a01b0302191690836001600160a01b0316021790611b06613bc7565b61376582826135e5565b6137935760405162461bcd60e51b815260040161378190614800565b604051809103906137906139ca565b50505b6001600160a01b038116600090815260018301602052604081206137b5613a35565b90506000600184806137c5613a35565b90500390508082146138895760008482816137de613a35565b81106137e657fe5b906000526020600020016000906137fb613a35565b906101000a90046001600160a01b031690508085600001848161381c613a35565b811061382457fe5b90600052602060002001600181613839613a35565b816001600160a01b0302191690836001600160a01b031602179061385b613bc7565b5050506001600160a01b0381166000908152600186016020528390604090208190613884613bc7565b505050505b8380613893613a35565b8061389a57fe5b600190038181906000526020600020016001816138b5613a35565b906001600160a01b03021916906138ca613bc7565b5050906138d5613bc7565b50506001600160a01b03831660009081526001850160205260409020600090611b06613bc7565b600081815260046020528060408120600090613916613a35565b6001600160a01b036101009290920a90041690508015158360405160200161393e9190614696565b604051602081830303815290604052906135d35760405162461bcd60e51b815260040161396b91906147bf565b6040518091039061397a6139ca565b50505092915050565b60008082116139b65760405162461bcd60e51b81526004016139a490614820565b604051809103906139b36139ca565b50505b60008284816139c157fe5b04949350505050565b632a2a7adb598160e01b8152600481016020815285602082015260005b86811015613a025780860151828201604001526020016139e7565b506020828760640184336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b505050565b6303daa959598160e01b8152836004820152602081602483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b8051935060005b60408110156116bf57600082820152602001613a79565b638435035b598160e01b8152836004820152602081602483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b80516000825293506020613a79565b638540661f598160e01b8152613b0d565b80808311156121ca575090919050565b80808310156121ca575090919050565b836004820152846024820152606060448201528660648201526084810160005b88811015613b45578088015182820152602001613b2d565b506060828960a40184336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b815160408301513d6000853e8b8b82606087013350600060045af15059613b9a8d3d613afd565b8c01613ba68187613aed565b5b82811015613bbb5760008152602001613ba7565b50929c50505050505050565b6322bd64c0598160e01b8152836004820152846024820152600081604483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b600081526020613a79565b63bdbf8c36598160e01b8152602081600483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b80516000825293506020613a79565b6373509064598160e01b8152602081600483336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b80516000825293506020613a79565b6385979f76598160e01b8152836004820152846024820152606060448201528760648201526084810160005b89811015613ce5578089015182820152602001613ccd565b506060828a60a40184336000905af158600e01573d6000803e3d6000fd5b3d6001141558600a015760016000f35b815160408301513d6000853e8c8c82606087013350600060045af15059613d3a8e3d613afd565b8d01613d468187613aed565b5b82811015613d5b5760008152602001613d47565b50929d50505050505050565b80356121ca81614992565b6000815190506121ca81614992565b60008083601f840112613d9c57600080613d996139ca565b50505b50813567ffffffffffffffff811115613dbd57600080613dba6139ca565b50505b6020830191508360208202830111156123b457600080613ddb6139ca565b50509250929050565b600082601f830112613dfe57600080613dfb6139ca565b50505b8135613e11613e0c826148f2565b6148be565b91508181835260208401935060208101905083856020840282011115613e3f57600080613e3c6139ca565b50505b60005b83811015613e6b5781613e558882613d67565b8452506020928301929190910190600101613e42565b5050505092915050565b600082601f830112613e8f57600080613e8c6139ca565b50505b8151613e9d613e0c826148f2565b91508181835260208401935060208101905083856020840282011115613ecb57600080613ec86139ca565b50505b60005b83811015613e6b5781613ee18882613f1c565b8452506020928301929190910190600101613ece565b80356121ca816149ac565b6000815190506121ca816149ac565b80356121ca816149b5565b6000815190506121ca816149b5565b600060208284031215613f4657600080613f436139ca565b50505b60006112f28484613d67565b600060208284031215613f6d57600080613f6a6139ca565b50505b60006112f28484613d72565b60008060208385031215613f9557600080613f926139ca565b50505b823567ffffffffffffffff811115613fb557600080613fb26139ca565b50505b613fc185828601613d81565b92509250509250929050565b600060208284031215613fe857600080613fe56139ca565b50505b813567ffffffffffffffff811115614008576000806140056139ca565b50505b6112f284828501613de4565b60008060008060408587031215614033576000806140306139ca565b50505b843567ffffffffffffffff811115614053576000806140506139ca565b50505b61405f87828801613d81565b9450945050602085013567ffffffffffffffff811115614087576000806140846139ca565b50505b61409387828801613d81565b95989497509550505050565b600080604083850312156140bb576000806140b86139ca565b50505b825167ffffffffffffffff8111156140db576000806140d86139ca565b50505b6140e785828601613e75565b92505060206140f885828601613f02565b9150509250929050565b60006020828403121561411d5760008061411a6139ca565b50505b60006112f28484613ef7565b600060208284031215614144576000806141416139ca565b50505b60006112f28484613f02565b60006020828403121561416b576000806141686139ca565b50505b60006112f28484613f11565b6000602082840312156141925760008061418f6139ca565b50505b60006112f28484613f1c565b600080604083850312156141ba576000806141b76139ca565b50505b60006141c68585613f11565b92505060206140f885828601613f11565b600080604083850312156141f3576000806141f06139ca565b50505b60006140e78585613f1c565b60008060006060848603121561421d5760008061421a6139ca565b50505b60006142298686613f11565b935050602061423a86828701613f11565b925050604061424b86828701613ef7565b9150509250925092565b60008060008060808587031215614274576000806142716139ca565b50505b60006142808787613f1c565b945050602061429187828801613f1c565b93505060406142a287828801613f1c565b92505060606142b387828801613f1c565b91505092959194509250565b60006142cb8383614344565b505060200190565b6142dc81614935565b82525050565b60006142ed82614922565b6142f7818561492c565b93506143028361491c565b8060005b8381101561433057815161431a88826142bf565b97506143258361491c565b925050600101614306565b509495945050505050565b6142dc81614940565b6142dc81610f63565b6142dc61435982610f63565b610f63565b6142dc81614951565b600061437282614922565b61437c818561492c565b935061438c81856020860161495c565b61439581614988565b9093019392505050565b60006143ac601b8361492c565b7f496e707574206172726179206c656e677468206d69736d617463680000000000815260200192915050565b60006143e560358361492c565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527402063616e20616363657074206f776e65727368697605c1b602082015260400192915050565b600061443c601b8361492c565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b600061447560138361492c565b7222b632b6b2b73a103737ba1034b71039b2ba1760691b815260200192915050565b60006144a4601e8361492c565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b60006144dd601a8361492c565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000815260200192915050565b60006145166011836114d7565b70026b4b9b9b4b7339030b2323932b9b99d1607d1b815260110192915050565b600061454360168361492c565b7504d7573742062652067726561746572207468616e20360541b815260200192915050565b6000614575602f8361492c565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b60006145c660218361492c565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b600061460960198361492c565b7f4f6e6c7920636f6c6c61746572616c20636f6e74726163747300000000000000815260200192915050565b60006146426019836114d7565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b600061467b600c8361492c565b6b496e76616c6964207261746560a01b815260200192915050565b60006146a182614509565b91506146ad828461434d565b50602001919050565b60006146a182614635565b602081016121ca82846142d3565b604081016146dd82856142d3565b61316260208301846142d3565b6020808252810161316281846142e2565b602081016121ca828461433b565b60408101614717828561433b565b613162602083018461433b565b602081016121ca8284614344565b604081016146dd8285614344565b604081016147178285614344565b6040810161475c8285614344565b81810360208301526112f28184614367565b6040810161477c8285614344565b6131626020830184614344565b606081016147978286614344565b6147a46020830185614344565b6112f26040830184614344565b602081016121ca828461435e565b602080825281016131628184614367565b602080825281016121ca8161439f565b602080825281016121ca816143d8565b602080825281016121ca8161442f565b602080825281016121ca81614468565b602080825281016121ca81614497565b602080825281016121ca816144d0565b602080825281016121ca81614536565b602080825281016121ca81614568565b602080825281016121ca816145b9565b602080825281016121ca816145fc565b602080825281016121ca8161466e565b6080810161488e8287614344565b61489b6020830186614344565b6148a86040830185614344565b6148b56060830184614344565b95945050505050565b6000604051905081810181811067ffffffffffffffff821117156148ea576000806148e76139ca565b50505b604052919050565b600067ffffffffffffffff8211156149125760008061490f6139ca565b50505b5060209081020190565b60200190565b6000815192915050565b90815260200190565b60006121ca82614945565b151590565b6001600160a01b031690565b60006121ca82614935565b60005b8381101561497757808201518382015260200161495f565b83811115610dde5750506000910152565b601f01601f191690565b61499b81614935565b8114610976576000806116bf6139ca565b61499b81614940565b61499b81610f6356000000000000000000000000ba10526cd8742acc73aedef5f7dbb2477bf869220000000000000000000000003c05b1239b223c969540fefc0270227a2b00e0470000000000000000000000001cb059b7e74fd21665968c908806143e744d5f300000000000000000000000000000000000000000003e09de2596099e2b00000000000000000000000000000000000000000000000000000002c68af0bb140000000000000000000000000000000000000000000000000000000000000971a92f000000000000000000000000000000000000000000000000000000000971a92f
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103425760003560e01c80638da5cb5b116101b8578063bbb601cd11610104578063e31f27c1116100a2578063eb94bbde1161007c578063eb94bbde146106a7578063edc77dc2146106ba578063ee81f790146106c2578063ffa749cd146106d557610342565b8063e31f27c11461066e578063e32261fe14610681578063e50a31b31461069457610342565b8063c9e18015116100de578063c9e1801514610638578063ca969f2314610640578063d0064c0014610653578063d2f004751461065b57610342565b8063bbb601cd14610615578063bf38668214610628578063c19d93fb1461063057610342565b8063af07aa9d11610171578063b4d6cb401161014b578063b4d6cb40146105c6578063b9e2451c146105e7578063ba1c5e80146105fa578063baa380361461060257610342565b8063af07aa9d14610598578063b38988f7146105ab578063b3b46732146105be57610342565b80638da5cb5b1461054757806391b4ded91461054f57806393a72fbe146105575780639f7eac371461056a578063a894a14b1461057d578063ad79a8581461059057610342565b8063614d08f81161029257806379ba509711610230578063899ffef41161020a578063899ffef4146105045780638b173e81146105195780638d1341901461052c5780638d6ad02d1461053f57610342565b806379ba5097146104c857806380054666146104d05780638471db13146104f157610342565b806372e18b6a1161026c57806372e18b6a14610487578063741853601461049a578063744d646e146104a25780637687402a146104b557610342565b8063614d08f8146104595780636526941b14610461578063710388d11461047457610342565b806323d60e2e116102ff5780634db7764c116102d95780634db7764c146104215780635246f2b91461042957806353a47bb71461043c5780635c975abb1461045157610342565b806323d60e2e146103d95780632af64bd3146103ec578063382453771461040157610342565b806303f048b01461034757806304f3bcec146103735780630c9c81a1146103885780631627540c1461039d57806316c38b3c146103b05780631e33fc6b146103c3575b600080fd5b61035a61035536600461317d565b6106e8565b60405161036a9493929190613877565b60405180910390f35b61037b61077f565b60405161036a91906137a8565b61039b61039636600461317d565b610793565b005b61039b6103ab366004612fcd565b6107db565b61039b6103be366004613141565b61082e565b6103cb6108a3565b60405161036a929190613737565b61039b6103e7366004613080565b610b1e565b6103f4610c4e565b60405161036a91906136f2565b61041461040f36600461317d565b610d6b565b60405161036a919061371b565b610414610d7d565b61039b6104373660046131b9565b610d83565b610444610e16565b60405161036a91906136b8565b6103f4610e25565b610414610e2e565b61039b61046f36600461317d565b610e46565b61039b610482366004613080565b610ea3565b6103f4610495366004613080565b610fb7565b61039b611051565b6103f46104b036600461304b565b6111a7565b61039b6104c33660046131b9565b6111f1565b61039b61124d565b6104e36104de366004613208565b6112e9565b60405161036a929190613765565b6103f46104ff36600461317d565b611414565b61050c611428565b60405161036a91906136e1565b61039b61052736600461317d565b611595565b61039b61053a36600461317d565b6115d2565b610414611662565b610444611668565b610414611677565b6103f4610565366004613080565b61167d565b61039b61057836600461317d565b611760565b61039b61058b366004613080565b6117bd565b6103cb61190c565b61035a6105a63660046131b9565b611afa565b6103f46105b9366004612fcd565b611b95565b610414611bae565b6105d96105d43660046131b9565b611c67565b60405161036a929190613700565b6104146105f536600461317d565b611d2f565b6103cb611d41565b61039b61061036600461317d565b611e64565b61039b610623366004613009565b611ea1565b610414611f81565b61037b611f87565b610414611f96565b61039b61064e366004613009565b611f9c565b610414612155565b61041461066936600461317d565b61215b565b61039b61067c3660046131b9565b6121dc565b61041461068f36600461317d565b612238565b61039b6106a23660046131b9565b612269565b61039b6106b53660046131b9565b6122c5565b6103cb612321565b6103cb6106d036600461317d565b612515565b61039b6106e3366004613009565b612745565b600554604051623f048b60e41b81526000918291829182916001600160a01b03909116906303f048b09061072090889060040161371b565b60806040518083038186803b15801561073857600080fd5b505afa15801561074c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506107709190810190613255565b92989197509550909350915050565b60035461010090046001600160a01b031681565b61079b6127fe565b60138190556040517f08f9599493340b8255c7698bded59e30079641f4a9531613ec02055739247004906107d090839061371b565b60405180910390a150565b6107e36127fe565b600180546001600160a01b0319166001600160a01b0383161790556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce22906107d09083906136b8565b6108366127fe565b60035460ff161515811515141561084c576108a0565b6003805460ff1916821515179081905560ff161561086957426002555b6003546040517f8fb6c181ee25a520cf3dd6565006ef91229fcfe5a989566c2a3b8c115570cec5916107d09160ff909116906136f2565b50565b600880546040805160208084028201810190925282815260009384936060938301828280156108f157602002820191906000526020600020905b8154815260200190600101908083116108dd575b50505050509050600081511115610b195760005b8151811015610b1757600082828151811061091c57fe5b60200260200101519050631cd554d160e21b8114156109cb5760055460405163d2f0047560e01b81526109c4916001600160a01b03169063d2f004759061096790859060040161371b565b60206040518083038186803b15801561097f57600080fd5b505afa158015610993573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506109b7919081019061319b565b869063ffffffff61282a16565b9450610b0e565b6000806109d6612856565b6001600160a01b0316630c71cd23846040518263ffffffff1660e01b8152600401610a01919061371b565b604080518083038186803b158015610a1857600080fd5b505afa158015610a2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610a5091908101906131e9565b60055460405163d2f0047560e01b8152929450909250600091610aeb9185916001600160a01b039091169063d2f0047590610a8f90899060040161371b565b60206040518083038186803b158015610aa757600080fd5b505afa158015610abb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610adf919081019061319b565b9063ffffffff61287616565b9050610afd888263ffffffff61282a16565b97508115610b0a57600196505b5050505b50600101610905565b505b509091565b610b266127fe565b828114610b4e5760405162461bcd60e51b8152600401610b45906137c7565b60405180910390fd5b60005b83811015610c3f57610b7f858583818110610b6857fe5b90506020020135600a6128a090919063ffffffff16565b610c37576000858583818110610b9157fe5b905060200201359050610bae81600a6128f090919063ffffffff16565b610bd4848484818110610bbd57fe5b9050602002013560086128f090919063ffffffff16565b80600c6000868686818110610be557fe5b905060200201358152602001908152602001600020819055507f87f8a613724bd8be7a9139e4c83bc8d58fedee7206e2d7077849f5988d78759981604051610c2d919061371b565b60405180910390a1505b600101610b51565b50610c48611051565b50505050565b60006060610c5a611428565b905060005b8151811015610d61576000828281518110610c7657fe5b60209081029190910181015160008181526004928390526040908190205460035491516321f8a72160e01b81529294506001600160a01b039081169361010090920416916321f8a72191610ccc9186910161371b565b60206040518083038186803b158015610ce457600080fd5b505afa158015610cf8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610d1c9190810190612feb565b6001600160a01b0316141580610d4757506000818152600460205260409020546001600160a01b0316155b15610d585760009350505050610d68565b50600101610c5f565b5060019150505b90565b600c6020526000908152604090205481565b60145481565b6000610d8e33611b95565b905080610dad5760405162461bcd60e51b8152600401610b4590613857565b600554604051635246f2b960e01b81526001600160a01b0390911690635246f2b990610ddf9086908690600401613765565b600060405180830381600087803b158015610df957600080fd5b505af1158015610e0d573d6000803e3d6000fd5b50505050505050565b6001546001600160a01b031681565b60035460ff1681565b7021b7b63630ba32b930b626b0b730b3b2b960791b81565b610e4e6127fe565b60008111610e6e5760405162461bcd60e51b8152600401610b4590613827565b60118190556040517f3620cc91bd75c6d3d752b529a1b98b38789dd2b81a13ece55801abc83531a77f906107d090839061371b565b610eab6127fe565b828114610eca5760405162461bcd60e51b8152600401610b45906137c7565b60005b83811015610fb057610ee4858583818110610b6857fe5b15610fa857610f0f858583818110610ef857fe5b90506020020135600a61292890919063ffffffff16565b610f35838383818110610f1e57fe5b90506020020135600861292890919063ffffffff16565b600c6000848484818110610f4557fe5b905060200201358152602001908152602001600020600090557f788aff97f65e6ddeee9246c47d08b819813066c87876a912c79baddffb138f0a858583818110610f8b57fe5b90506020020135604051610f9f919061371b565b60405180910390a15b600101610ecd565b5050505050565b600a546000908414610fcb57506000611049565b60005b8481101561104357610fe5868683818110610b6857fe5b610ff3576000915050611049565b858582818110610fff57fe5b90506020020135600c600086868581811061101657fe5b905060200201358152602001908152602001600020541461103b576000915050611049565b600101610fce565b50600190505b949350505050565b606061105b611428565b905060005b81518110156111a357600082828151811061107757fe5b602002602001015190506000600360019054906101000a90046001600160a01b03166001600160a01b031663dacb2d0183846040516020016110b991906136ad565b6040516020818303038152906040526040518363ffffffff1660e01b81526004016110e5929190613745565b60206040518083038186803b1580156110fd57600080fd5b505afa158015611111573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506111359190810190612feb565b6000838152600460205260409081902080546001600160a01b0319166001600160a01b038416179055519091507f88a93678a3692f6789d9546fc621bf7234b101ddb7d4fe479455112831b8aa68906111919084908490613729565b60405180910390a15050600101611060565b5050565b6000805b82518110156111e6576111d08382815181106111c357fe5b6020026020010151611b95565b6111de5760009150506111ec565b6001016111ab565b50600190505b919050565b60006111fc33611b95565b90508061121b5760405162461bcd60e51b8152600401610b4590613857565b600554604051632462063960e01b81526001600160a01b0390911690632462063990610ddf9086908690600401613765565b6001546001600160a01b031633146112775760405162461bcd60e51b8152600401610b45906137d7565b6000546001546040517fb532073b38c83145e3e5135377a08bf9aab55bc0fd7c1179cd4fb995d2a5159c926112ba926001600160a01b03918216929116906136c6565b60405180910390a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b60008060006112f733611b95565b9050806113165760405162461bcd60e51b8152600401610b4590613857565b6000806000808761132f5761132a8a6106e8565b611339565b611339898b611afa565b93509350935093506000808961135657611351611d41565b61135f565b61135f8b612515565b9150915080156113815760405162461bcd60e51b8152600401610b4590613867565b60006113ab670de0b6b3a764000061139f428863ffffffff6129fc16565b9063ffffffff612a2416565b905060006113cf6113c2858463ffffffff61287616565b889063ffffffff61282a16565b90506113e1818963ffffffff6129fc16565b9a508499508b6113f9576113f481612a5e565b611403565b6114038d82612abc565b505050505050505050935093915050565b6000908152600c6020526040902054151590565b6040805160028082526060808301845292839291906020830190803883390190505090506524b9b9bab2b960d11b8160008151811061146357fe5b6020026020010181815250506c45786368616e6765526174657360981b8160018151811061148d57fe5b6020908102919091010152600d54606090801561151657806040519080825280602002602001820160405280156114ce578160200160208202803883390190505b50915060005b8181101561151457600d8054829081106114ea57fe5b906000526020600020015483828151811061150157fe5b60209081029190910101526001016114d4565b505b600a80546040805160208084028201810190925282815260609361156f93879383018282801561156557602002820191906000526020600020905b815481526020019060010190808311611551575b5050505050612aee565b80519091501561158a576115838185612aee565b945061158e565b8394505b5050505090565b61159d6127fe565b60148190556040517fe2695216766f2a627e90e17041ac2f085fd60ea503345b039f815c69bcbcccc9906107d090839061371b565b60006115dd33611b95565b9050806115fc5760405162461bcd60e51b8152600401610b4590613857565b600554604051637a981bdb60e11b81526001600160a01b039091169063f53037b69061162c90859060040161371b565b600060405180830381600087803b15801561164657600080fd5b505af115801561165a573d6000803e3d6000fd5b505050505050565b60125481565b6000546001600160a01b031681565b60025481565b600083821461169e5760405162461bcd60e51b8152600401610b45906137c7565b600d5484146116af57506000611049565b60005b82811015611043576005546001600160a01b031663a0356f6e8585848181106116d757fe5b905060200201356040518263ffffffff1660e01b81526004016116fa919061371b565b60206040518083038186803b15801561171257600080fd5b505afa158015611726573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061174a919081019061319b565b611758576000915050611049565b6001016116b2565b6117686127fe565b600081116117885760405162461bcd60e51b8152600401610b4590613827565b60108190556040517fcf53b24098da84a81615c6450c76443db743815230079981717af7ff9d647fd4906107d090839061371b565b6117c56127fe565b8281146117e45760405162461bcd60e51b8152600401610b45906137c7565b60005b83811015610c3f5760008585838181106117fd57fe5b90506020020135905061181a81600d6128a090919063ffffffff16565b6119035761182f600d8263ffffffff6128f016565b80600f600086868681811061184057fe5b905060200201358152602001908152602001600020819055507fa71e21d8a72d99830e0d382f042d37e6a20c8a33ec3185affcaf6586e9a0187a81604051611888919061371b565b60405180910390a16005546001600160a01b031663ed0391548585858181106118ad57fe5b905060200201356040518263ffffffff1660e01b81526004016118d0919061371b565b600060405180830381600087803b1580156118ea57600080fd5b505af11580156118fe573d6000803e3d6000fd5b505050505b506001016117e7565b600d805460408051602080840282018101909252828152600093849360609383018282801561195a57602002820191906000526020600020905b815481526020019060010190808311611946575b50505050509050600081511115610b195760005b8151811015610b1757600061199583838151811061198857fe5b6020026020010151612baa565b6001600160a01b031663dbd06c856040518163ffffffff1660e01b815260040160206040518083038186803b1580156119cd57600080fd5b505afa1580156119e1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a05919081019061319b565b9050600080611a12612856565b6001600160a01b0316630c71cd23846040518263ffffffff1660e01b8152600401611a3d919061371b565b604080518083038186803b158015611a5457600080fd5b505afa158015611a68573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611a8c91908101906131e9565b60055460405163719130ff60e11b8152929450909250600091611acb9185916001600160a01b039091169063e32261fe90610a8f90899060040161371b565b9050611add888263ffffffff61282a16565b97508115611aea57600196505b50506001909201915061196e9050565b60055460405163af07aa9d60e01b81526000918291829182916001600160a01b039091169063af07aa9d90611b359089908990600401613765565b60806040518083038186803b158015611b4d57600080fd5b505afa158015611b61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611b859190810190613255565b9299919850965090945092505050565b6000611ba860068363ffffffff612bb516565b92915050565b600080611bba33611b95565b905080611bd95760405162461bcd60e51b8152600401610b4590613857565b600560009054906101000a90046001600160a01b03166001600160a01b0316638c5825036040518163ffffffff1660e01b8152600401602060405180830381600087803b158015611c2957600080fd5b505af1158015611c3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611c61919081019061319b565b91505090565b6000806000611c74612856565b6001600160a01b031663654a60ac8587631cd554d160e21b6040518463ffffffff1660e01b8152600401611caa93929190613780565b60206040518083038186803b158015611cc257600080fd5b505afa158015611cd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611cfa919081019061319b565b9050600080611d07612321565b6011549193509150611d1f838563ffffffff61282a16565b11159450925050505b9250929050565b600f6020526000908152604090205481565b6000806000611d4e612c22565b6001600160a01b0316637b1001b7631cd554d160e21b60016040518363ffffffff1660e01b8152600401611d83929190613737565b60206040518083038186803b158015611d9b57600080fd5b505afa158015611daf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611dd3919081019061319b565b9050600080611de06108a3565b90925090506000611df7848463ffffffff61282a16565b90506000611e266a1a1a7062e5185d7e380000611e1a868563ffffffff612c3616565b9063ffffffff612c3616565b90506000611e3f6010548361287690919063ffffffff16565b9050611e566013548261282a90919063ffffffff16565b989397509295505050505050565b611e6c6127fe565b60128190556040517f465c1047eec44dfecb260ee7e6187823a7cbdd80f19082eb56c35967b16d8e26906107d090839061371b565b611ea96127fe565b60005b81811015611f7c57611ee6838383818110611ec357fe5b9050602002016020611ed89190810190612fcd565b60069063ffffffff612bb516565b611f7457611f1c838383818110611ef957fe5b9050602002016020611f0e9190810190612fcd565b60069063ffffffff612c6016565b7f7db05e63d635a68c62fd7fd8f3107ae8ab584a383e102d1bd8a40f4c977e465f838383818110611f4957fe5b9050602002016020611f5e9190810190612fcd565b604051611f6b91906136b8565b60405180910390a15b600101611eac565b505050565b60135481565b6005546001600160a01b031681565b60105481565b611fa46127fe565b60005b81811015611f7c57611fd5838383818110611fbe57fe5b90506020020135600d6128a090919063ffffffff16565b1561214d57612000838383818110611fe957fe5b90506020020135600d61292890919063ffffffff16565b600061201d84848481811061201157fe5b90506020020135612baa565b6001600160a01b031663dbd06c856040518163ffffffff1660e01b815260040160206040518083038186803b15801561205557600080fd5b505afa158015612069573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061208d919081019061319b565b6000818152600f6020526040808220919091556005549051636431e0bd60e01b81529192506001600160a01b031690636431e0bd906120d090849060040161371b565b600060405180830381600087803b1580156120ea57600080fd5b505af11580156120fe573d6000803e3d6000fd5b505050507f23caa21d7c1015aa7051e1ae4a09f99de36dab4545dfec5f4dde3a54173a123b84848481811061212f57fe5b90506020020135604051612143919061371b565b60405180910390a1505b600101611fa7565b60115481565b60055460405163d2f0047560e01b81526000916001600160a01b03169063d2f004759061218c90859060040161371b565b60206040518083038186803b1580156121a457600080fd5b505afa1580156121b8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250611ba8919081019061319b565b60006121e733611b95565b9050806122065760405162461bcd60e51b8152600401610b4590613857565b60055460405163e31f27c160e01b81526001600160a01b039091169063e31f27c190610ddf9086908690600401613765565b60055460405163719130ff60e11b81526000916001600160a01b03169063e32261fe9061218c90859060040161371b565b600061227433611b95565b9050806122935760405162461bcd60e51b8152600401610b4590613857565b60055460405163e50a31b360e01b81526001600160a01b039091169063e50a31b390610ddf9086908690600401613765565b60006122d033611b95565b9050806122ef5760405162461bcd60e51b8152600401610b4590613857565b6005546040516375ca5def60e11b81526001600160a01b039091169063eb94bbde90610ddf9086908690600401613765565b6008805460408051602080840282018101909252828152600093849360609383018282801561236f57602002820191906000526020600020905b81548152602001906001019080831161235b575b50505050509050600081511115610b19576060600061238c612856565b6001600160a01b031663c8e5bbd5846040518263ffffffff1660e01b81526004016123b791906136e1565b60006040518083038186803b1580156123cf57600080fd5b505afa1580156123e3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261240b91908101906130f0565b909250905060005b825181101561250d57600061248984838151811061242d57fe5b6020026020010151600560009054906101000a90046001600160a01b03166001600160a01b031663d2f0047588868151811061246557fe5b60200260200101516040518263ffffffff1660e01b8152600401610a8f919061371b565b905060006124d485848151811061249c57fe5b6020026020010151600560009054906101000a90046001600160a01b03166001600160a01b031663e32261fe89878151811061246557fe5b90506124f6816124ea8a8563ffffffff61282a16565b9063ffffffff61282a16565b9750831561250357600196505b5050600101612413565b505050509091565b600080612520612856565b6001600160a01b0316632528f0fe846040518263ffffffff1660e01b815260040161254b919061371b565b60206040518083038186803b15801561256357600080fd5b505afa158015612577573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061259b919081019061315f565b6000848152600f6020526040812054919250906125b790612baa565b6001600160a01b03166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b1580156125ef57600080fd5b505afa158015612603573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250612627919081019061319b565b60055460405163719130ff60e11b81529192506000916001600160a01b039091169063e32261fe9061265d90889060040161371b565b60206040518083038186803b15801561267557600080fd5b505afa158015612689573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506126ad919081019061319b565b9050808211156126c35750600092506127409050565b60006126d5828463ffffffff6129fc16565b905060006127086a1a1a7062e5185d7e380000611e1a6126fb878763ffffffff61282a16565b859063ffffffff612c3616565b905060006127216012548361287690919063ffffffff16565b90506127386014548261282a90919063ffffffff16565b965050505050505b915091565b61274d6127fe565b60005b81811015611f7c57612767838383818110611ec357fe5b156127f65761279e83838381811061277b57fe5b90506020020160206127909190810190612fcd565b60069063ffffffff612cb216565b7fd89d2ee68ab04dca0193f48a4aff55e20fa5ec0429a8a8c1c51b8dad6178a5938383838181106127cb57fe5b90506020020160206127e09190810190612fcd565b6040516127ed91906136b8565b60405180910390a15b600101612750565b6000546001600160a01b031633146128285760405162461bcd60e51b8152600401610b4590613837565b565b60008282018381101561284f5760405162461bcd60e51b8152600401610b45906137e7565b9392505050565b60006128716c45786368616e6765526174657360981b612dc8565b905090565b6000670de0b6b3a7640000612891848463ffffffff612a2416565b8161289857fe5b049392505050565b81546000906128b157506000611ba8565b600082815260018401602052604090205480151580611049575082846000016000815481106128dc57fe5b906000526020600020015414949350505050565b6128fa82826128a0565b6111a35781546000828152600180850160209081526040832084905590830185558482529020018190555050565b61293282826128a0565b61294e5760405162461bcd60e51b8152600401610b45906137f7565b60008181526001830160205260409020548254600019018082146129bc57600084600001828154811061297d57fe5b906000526020600020015490508085600001848154811061299a57fe5b6000918252602080832090910192909255918252600186019052604090208290555b83548490806129c757fe5b600190038181906000526020600020016000905590558360010160008481526020019081526020016000206000905550505050565b600082821115612a1e5760405162461bcd60e51b8152600401610b4590613807565b50900390565b600082612a3357506000611ba8565b82820282848281612a4057fe5b041461284f5760405162461bcd60e51b8152600401610b4590613847565b600554604051637a981bdb60e11b81526001600160a01b039091169063f53037b690612a8e90849060040161371b565b600060405180830381600087803b158015612aa857600080fd5b505af1158015610fb0573d6000803e3d6000fd5b600554604051632462063960e01b81526001600160a01b039091169063246206399061162c9085908590600401613765565b60608151835101604051908082528060200260200182016040528015612b1e578160200160208202803883390190505b50905060005b8351811015612b6057838181518110612b3957fe5b6020026020010151828281518110612b4d57fe5b6020908102919091010152600101612b24565b5060005b8251811015612ba357828181518110612b7957fe5b6020026020010151828286510181518110612b9057fe5b6020908102919091010152600101612b64565b5092915050565b6000611ba882612dc8565b8154600090612bc657506000611ba8565b6001600160a01b0382166000908152600184016020526040902054801515806110495750826001600160a01b031684600001600081548110612c0457fe5b6000918252602090912001546001600160a01b031614949350505050565b60006128716524b9b9bab2b960d11b612dc8565b600061284f82612c5485670de0b6b3a764000063ffffffff612a2416565b9063ffffffff612e2516565b612c6a8282612bb5565b6111a35781546001600160a01b038216600081815260018086016020908152604083208590559084018655858252902090910180546001600160a01b03191690911790555050565b612cbc8282612bb5565b612cd85760405162461bcd60e51b8152600401610b45906137f7565b6001600160a01b0381166000908152600183016020526040902054825460001901808214612d77576000846000018281548110612d1157fe5b60009182526020909120015485546001600160a01b0390911691508190869085908110612d3a57fe5b600091825260208083209190910180546001600160a01b0319166001600160a01b0394851617905592909116815260018601909152604090208290555b8354849080612d8257fe5b60008281526020808220830160001990810180546001600160a01b03191690559092019092556001600160a01b0394909416815260019490940190925250506040812055565b60008181526004602090815260408083205490516001600160a01b039091169182151591612df89186910161368d565b60405160208183030381529060405290612ba35760405162461bcd60e51b8152600401610b4591906137b6565b6000808211612e465760405162461bcd60e51b8152600401610b4590613817565b6000828481612e5157fe5b04949350505050565b8035611ba88161396d565b8051611ba88161396d565b60008083601f840112612e8257600080fd5b50813567ffffffffffffffff811115612e9a57600080fd5b602083019150836020820283011115611d2857600080fd5b600082601f830112612ec357600080fd5b8135612ed6612ed1826138dc565b6138b5565b91508181835260208401935060208101905083856020840282011115612efb57600080fd5b60005b83811015612f275781612f118882612e5a565b8452506020928301929190910190600101612efe565b5050505092915050565b600082601f830112612f4257600080fd5b8151612f50612ed1826138dc565b91508181835260208401935060208101905083856020840282011115612f7557600080fd5b60005b83811015612f275781612f8b8882612fc2565b8452506020928301929190910190600101612f78565b8035611ba881613981565b8051611ba881613981565b8035611ba88161398a565b8051611ba88161398a565b600060208284031215612fdf57600080fd5b60006110498484612e5a565b600060208284031215612ffd57600080fd5b60006110498484612e65565b6000806020838503121561301c57600080fd5b823567ffffffffffffffff81111561303357600080fd5b61303f85828601612e70565b92509250509250929050565b60006020828403121561305d57600080fd5b813567ffffffffffffffff81111561307457600080fd5b61104984828501612eb2565b6000806000806040858703121561309657600080fd5b843567ffffffffffffffff8111156130ad57600080fd5b6130b987828801612e70565b9450945050602085013567ffffffffffffffff8111156130d857600080fd5b6130e487828801612e70565b95989497509550505050565b6000806040838503121561310357600080fd5b825167ffffffffffffffff81111561311a57600080fd5b61312685828601612f31565b925050602061313785828601612fac565b9150509250929050565b60006020828403121561315357600080fd5b60006110498484612fa1565b60006020828403121561317157600080fd5b60006110498484612fac565b60006020828403121561318f57600080fd5b60006110498484612fb7565b6000602082840312156131ad57600080fd5b60006110498484612fc2565b600080604083850312156131cc57600080fd5b60006131d88585612fb7565b925050602061313785828601612fb7565b600080604083850312156131fc57600080fd5b60006131268585612fc2565b60008060006060848603121561321d57600080fd5b60006132298686612fb7565b935050602061323a86828701612fb7565b925050604061324b86828701612fa1565b9150509250925092565b6000806000806080858703121561326b57600080fd5b60006132778787612fc2565b945050602061328887828801612fc2565b935050604061329987828801612fc2565b92505060606132aa87828801612fc2565b91505092959194509250565b60006132c2838361333b565b505060200190565b6132d381613910565b82525050565b60006132e482613903565b6132ee8185613907565b93506132f9836138fd565b8060005b8381101561332757815161331188826132b6565b975061331c836138fd565b9250506001016132fd565b509495945050505050565b6132d38161391b565b6132d381610d68565b6132d361335082610d68565b610d68565b6132d38161392c565b600061336982613903565b6133738185613907565b9350613383818560208601613937565b61338c81613963565b9093019392505050565b60006133a3601b83613907565b7f496e707574206172726179206c656e677468206d69736d617463680000000000815260200192915050565b60006133dc603583613907565b7f596f75206d757374206265206e6f6d696e61746564206265666f726520796f7581527402063616e20616363657074206f776e65727368697605c1b602082015260400192915050565b6000613433601b83613907565b7f536166654d6174683a206164646974696f6e206f766572666c6f770000000000815260200192915050565b600061346c601383613907565b7222b632b6b2b73a103737ba1034b71039b2ba1760691b815260200192915050565b600061349b601e83613907565b7f536166654d6174683a207375627472616374696f6e206f766572666c6f770000815260200192915050565b60006134d4601a83613907565b7f536166654d6174683a206469766973696f6e206279207a65726f000000000000815260200192915050565b600061350d6011836111ec565b70026b4b9b9b4b7339030b2323932b9b99d1607d1b815260110192915050565b600061353a601683613907565b7504d7573742062652067726561746572207468616e20360541b815260200192915050565b600061356c602f83613907565b7f4f6e6c792074686520636f6e7472616374206f776e6572206d6179207065726681526e37b936903a3434b99030b1ba34b7b760891b602082015260400192915050565b60006135bd602183613907565b7f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f8152607760f81b602082015260400192915050565b6000613600601983613907565b7f4f6e6c7920636f6c6c61746572616c20636f6e74726163747300000000000000815260200192915050565b60006136396019836111ec565b7f5265736f6c766572206d697373696e67207461726765743a2000000000000000815260190192915050565b6000613672600c83613907565b6b496e76616c6964207261746560a01b815260200192915050565b600061369882613500565b91506136a48284613344565b50602001919050565b60006136988261362c565b60208101611ba882846132ca565b604081016136d482856132ca565b61284f60208301846132ca565b6020808252810161284f81846132d9565b60208101611ba88284613332565b6040810161370e8285613332565b61284f6020830184613332565b60208101611ba8828461333b565b604081016136d4828561333b565b6040810161370e828561333b565b60408101613753828561333b565b8181036020830152611049818461335e565b60408101613773828561333b565b61284f602083018461333b565b6060810161378e828661333b565b61379b602083018561333b565b611049604083018461333b565b60208101611ba88284613355565b6020808252810161284f818461335e565b60208082528101611ba881613396565b60208082528101611ba8816133cf565b60208082528101611ba881613426565b60208082528101611ba88161345f565b60208082528101611ba88161348e565b60208082528101611ba8816134c7565b60208082528101611ba88161352d565b60208082528101611ba88161355f565b60208082528101611ba8816135b0565b60208082528101611ba8816135f3565b60208082528101611ba881613665565b60808101613885828761333b565b613892602083018661333b565b61389f604083018561333b565b6138ac606083018461333b565b95945050505050565b60405181810167ffffffffffffffff811182821017156138d457600080fd5b604052919050565b600067ffffffffffffffff8211156138f357600080fd5b5060209081020190565b60200190565b5190565b90815260200190565b6000611ba882613920565b151590565b6001600160a01b031690565b6000611ba882613910565b60005b8381101561395257818101518382015260200161393a565b83811115610c485750506000910152565b601f01601f191690565b61397681613910565b81146108a057600080fd5b6139768161391b565b61397681610d6856fea365627a7a723158208ce9b6c873048c9e13f053c324a4e1d84a649d7ccdf7ce0df35c31497bc316e06c6578706572696d656e74616cf564736f6c63430005100040
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ba10526cd8742acc73aedef5f7dbb2477bf869220000000000000000000000003c05b1239b223c969540fefc0270227a2b00e0470000000000000000000000001cb059b7e74fd21665968c908806143e744d5f300000000000000000000000000000000000000000003e09de2596099e2b00000000000000000000000000000000000000000000000000000002c68af0bb140000000000000000000000000000000000000000000000000000000000000971a92f000000000000000000000000000000000000000000000000000000000971a92f
-----Decoded View---------------
Arg [0] : _state (address): 0xbA10526cD8742acC73AedeF5f7Dbb2477Bf86922
Arg [1] : _owner (address): 0x3C05B1239B223c969540FeFc0270227a2B00e047
Arg [2] : _resolver (address): 0x1Cb059b7e74fD21665968C908806143E744D5F30
Arg [3] : _maxDebt (uint256): 75000000000000000000000000
Arg [4] : _maxSkewRate (uint256): 200000000000000000
Arg [5] : _baseBorrowRate (uint256): 158443823
Arg [6] : _baseShortRate (uint256): 158443823
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000ba10526cd8742acc73aedef5f7dbb2477bf86922
Arg [1] : 0000000000000000000000003c05b1239b223c969540fefc0270227a2b00e047
Arg [2] : 0000000000000000000000001cb059b7e74fd21665968c908806143e744d5f30
Arg [3] : 0000000000000000000000000000000000000000003e09de2596099e2b000000
Arg [4] : 00000000000000000000000000000000000000000000000002c68af0bb140000
Arg [5] : 000000000000000000000000000000000000000000000000000000000971a92f
Arg [6] : 000000000000000000000000000000000000000000000000000000000971a92f
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.