More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 275 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Withdraw | 14917781 | 990 days ago | IN | 0 ETH | 0.01761018 | ||||
Withdraw To | 12066886 | 1435 days ago | IN | 0 ETH | 0.04974741 | ||||
Withdraw To | 12066839 | 1435 days ago | IN | 0 ETH | 0.05103398 | ||||
Withdraw To | 11205891 | 1567 days ago | IN | 0 ETH | 0.0067626 | ||||
Withdraw To | 11050553 | 1591 days ago | IN | 0 ETH | 0.01521586 | ||||
Withdraw To | 10892021 | 1615 days ago | IN | 0 ETH | 0.05269947 | ||||
Withdraw To | 10843575 | 1623 days ago | IN | 0 ETH | 0.03547352 | ||||
Withdraw To | 10698175 | 1645 days ago | IN | 0 ETH | 0.0604129 | ||||
Withdraw To | 10654715 | 1652 days ago | IN | 0 ETH | 0.07249856 | ||||
Withdraw To | 10557265 | 1667 days ago | IN | 0 ETH | 0.02039022 | ||||
Withdraw To | 10523919 | 1672 days ago | IN | 0 ETH | 0.03154348 | ||||
Withdraw To | 10516020 | 1673 days ago | IN | 0 ETH | 0.03373585 | ||||
Update | 10473979 | 1680 days ago | IN | 0 ETH | 0.00112233 | ||||
Withdraw To | 10471293 | 1680 days ago | IN | 0 ETH | 0.03373493 | ||||
Withdraw To | 10414147 | 1689 days ago | IN | 0 ETH | 0.0133469 | ||||
Withdraw To | 10414136 | 1689 days ago | IN | 0 ETH | 0.01358159 | ||||
Withdraw To | 10388315 | 1693 days ago | IN | 0 ETH | 0.01393636 | ||||
Withdraw To | 10323075 | 1703 days ago | IN | 0 ETH | 0.02059098 | ||||
Withdraw To | 10304130 | 1706 days ago | IN | 0 ETH | 0.00963806 | ||||
Withdraw To | 10300481 | 1707 days ago | IN | 0 ETH | 0.00968187 | ||||
Request | 10296939 | 1707 days ago | IN | 0 ETH | 0.06181071 | ||||
Request | 10289714 | 1708 days ago | IN | 0 ETH | 0.05013252 | ||||
Withdraw To | 10289182 | 1708 days ago | IN | 0 ETH | 0.01721757 | ||||
Request | 10278767 | 1710 days ago | IN | 0 ETH | 0.03841065 | ||||
Create | 10271581 | 1711 days ago | IN | 0 ETH | 0.02138871 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Funds
Compiler Version
v0.5.10+commit.5a6ea5b1
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2020-02-24 */ pragma solidity 0.5.10; contract Context { constructor () internal { } function _msgSender() internal view returns (address payable) { return msg.sender; } function _msgData() internal view returns (bytes memory) { this; return msg.data; } } interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } contract ERC20 is Context, IERC20 { using SafeMath for uint256; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; function totalSupply() public view returns (uint256) { return _totalSupply; } function balanceOf(address account) public view returns (uint256) { return _balances[account]; } function transfer(address recipient, uint256 amount) public returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } function allowance(address owner, address spender) public view returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 amount) public returns (bool) { _approve(_msgSender(), spender, amount); return true; } function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } function increaseAllowance(address spender, uint256 addedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) public returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } function _transfer(address sender, address recipient, uint256 amount) internal { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } function _mint(address account, uint256 amount) internal { require(account != address(0), "ERC20: mint to the zero address"); _totalSupply = _totalSupply.add(amount); _balances[account] = _balances[account].add(amount); emit Transfer(address(0), account, amount); } function _burn(address account, uint256 amount) internal { require(account != address(0), "ERC20: burn from the zero address"); _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); _totalSupply = _totalSupply.sub(amount); emit Transfer(account, address(0), amount); } function _approve(address owner, address spender, uint256 amount) internal { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } function _burnFrom(address account, uint256 amount) internal { _burn(account, amount); _approve(account, _msgSender(), _allowances[account][_msgSender()].sub(amount, "ERC20: burn amount exceeds allowance")); } } library BytesLib { function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) { bytes memory tempBytes; assembly { tempBytes := mload(0x40) let length := mload(_preBytes) mstore(tempBytes, length) let mc := add(tempBytes, 0x20) let end := add(mc, length) for { let cc := add(_preBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } length := mload(_postBytes) mstore(tempBytes, add(length, mload(tempBytes))) mc := end end := add(mc, length) for { let cc := add(_postBytes, 0x20) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(0x40, and( add(add(end, iszero(add(length, mload(_preBytes)))), 31), not(31) )) } return tempBytes; } function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal { assembly { let fslot := sload(_preBytes_slot) let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) let newlength := add(slength, mlength) switch add(lt(slength, 32), lt(newlength, 32)) case 2 { sstore( _preBytes_slot, add( fslot, add( mul( div( mload(add(_postBytes, 0x20)), exp(0x100, sub(32, mlength)) ), exp(0x100, sub(32, newlength)) ), mul(mlength, 2) ) ) ) } case 1 { mstore(0x0, _preBytes_slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) sstore(_preBytes_slot, add(mul(newlength, 2), 1)) let submod := sub(32, slength) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore( sc, add( and( fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00 ), and(mload(mc), mask) ) ) for { mc := add(mc, 0x20) sc := add(sc, 1) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } default { mstore(0x0, _preBytes_slot) let sc := add(keccak256(0x0, 0x20), div(slength, 32)) sstore(_preBytes_slot, add(mul(newlength, 2), 1)) let slengthmod := mod(slength, 32) let mlengthmod := mod(mlength, 32) let submod := sub(32, slengthmod) let mc := add(_postBytes, submod) let end := add(_postBytes, mlength) let mask := sub(exp(0x100, submod), 1) sstore(sc, add(sload(sc), and(mload(mc), mask))) for { sc := add(sc, 1) mc := add(mc, 0x20) } lt(mc, end) { sc := add(sc, 1) mc := add(mc, 0x20) } { sstore(sc, mload(mc)) } mask := exp(0x100, sub(mc, end)) sstore(sc, mul(div(mload(mc), mask), mask)) } } } function slice(bytes memory _bytes, uint _start, uint _length) internal pure returns (bytes memory) { require(_bytes.length >= (_start + _length), "Slice out of bounds"); bytes memory tempBytes; assembly { switch iszero(_length) case 0 { tempBytes := mload(0x40) let lengthmod := and(_length, 31) let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod))) let end := add(mc, _length) for { let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start) } lt(mc, end) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { mstore(mc, mload(cc)) } mstore(tempBytes, _length) mstore(0x40, and(add(mc, 31), not(31))) } default { tempBytes := mload(0x40) mstore(0x40, add(tempBytes, 0x20)) } } return tempBytes; } function toAddress(bytes memory _bytes, uint _start) internal pure returns (address) { require(_bytes.length >= (_start + 20), "Address conversion out of bounds."); address tempAddress; assembly { tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000) } return tempAddress; } function toUint(bytes memory _bytes, uint _start) internal pure returns (uint256) { require(_bytes.length >= (_start + 32), "Uint conversion out of bounds."); uint256 tempUint; assembly { tempUint := mload(add(add(_bytes, 0x20), _start)) } return tempUint; } function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) { bool success = true; assembly { let length := mload(_preBytes) switch eq(length, mload(_postBytes)) case 1 { let cb := 1 let mc := add(_preBytes, 0x20) let end := add(mc, length) for { let cc := add(_postBytes, 0x20) } eq(add(lt(mc, end), cb), 2) { mc := add(mc, 0x20) cc := add(cc, 0x20) } { if iszero(eq(mload(mc), mload(cc))) { success := 0 cb := 0 } } } default { success := 0 } } return success; } function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) { bool success = true; assembly { let fslot := sload(_preBytes_slot) let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2) let mlength := mload(_postBytes) switch eq(slength, mlength) case 1 { if iszero(iszero(slength)) { switch lt(slength, 32) case 1 { fslot := mul(div(fslot, 0x100), 0x100) if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) { success := 0 } } default { let cb := 1 mstore(0x0, _preBytes_slot) let sc := keccak256(0x0, 0x20) let mc := add(_postBytes, 0x20) let end := add(mc, mlength) for {} eq(add(lt(mc, end), cb), 2) { sc := add(sc, 1) mc := add(mc, 0x20) } { if iszero(eq(sload(sc), mload(mc))) { success := 0 cb := 0 } } } } } default { success := 0 } } return success; } function toBytes32(bytes memory _source) pure internal returns (bytes32 result) { bytes memory tempEmptyStringTest = bytes(_source); if (tempEmptyStringTest.length == 0) { return 0x0; } assembly { result := mload(add(_source, 32)) } } } library BTCUtils { using BytesLib for bytes; using SafeMath for uint256; uint256 public constant DIFF1_TARGET = 0xffff0000000000000000000000000000000000000000000000000000; uint256 public constant RETARGET_PERIOD = 2 * 7 * 24 * 60 * 60; uint256 public constant RETARGET_PERIOD_BLOCKS = 2016; function determineVarIntDataLength(bytes memory _flag) internal pure returns (uint8) { if (uint8(_flag[0]) == 0xff) { return 8; } if (uint8(_flag[0]) == 0xfe) { return 4; } if (uint8(_flag[0]) == 0xfd) { return 2; } return 0; } function reverseEndianness(bytes memory _b) internal pure returns (bytes memory) { bytes memory _newValue = new bytes(_b.length); for (uint i = 0; i < _b.length; i++) { _newValue[_b.length - i - 1] = _b[i]; } return _newValue; } function bytesToUint(bytes memory _b) internal pure returns (uint256) { uint256 _number; for (uint i = 0; i < _b.length; i++) { _number = _number + uint8(_b[i]) * (2 ** (8 * (_b.length - (i + 1)))); } return _number; } function lastBytes(bytes memory _b, uint256 _num) internal pure returns (bytes memory) { uint256 _start = _b.length.sub(_num); return _b.slice(_start, _num); } function hash160(bytes memory _b) internal pure returns (bytes memory) { return abi.encodePacked(ripemd160(abi.encodePacked(sha256(_b)))); } function hash256(bytes memory _b) internal pure returns (bytes32) { return abi.encodePacked(sha256(abi.encodePacked(sha256(_b)))).toBytes32(); } function extractInputAtIndex(bytes memory _vin, uint8 _index) internal pure returns (bytes memory) { uint256 _len; bytes memory _remaining; uint256 _offset = 1; for (uint8 _i = 0; _i < _index; _i ++) { _remaining = _vin.slice(_offset, _vin.length - _offset); _len = determineInputLength(_remaining); _offset = _offset + _len; } _remaining = _vin.slice(_offset, _vin.length - _offset); _len = determineInputLength(_remaining); return _vin.slice(_offset, _len); } function isLegacyInput(bytes memory _input) internal pure returns (bool) { return keccak256(_input.slice(36, 1)) != keccak256(hex"00"); } function determineInputLength(bytes memory _input) internal pure returns (uint256) { uint8 _varIntDataLen; uint256 _scriptSigLen; (_varIntDataLen, _scriptSigLen) = extractScriptSigLen(_input); return 36 + 1 + _varIntDataLen + _scriptSigLen + 4; } function extractSequenceLELegacy(bytes memory _input) internal pure returns (bytes memory) { uint8 _varIntDataLen; uint256 _scriptSigLen; (_varIntDataLen, _scriptSigLen) = extractScriptSigLen(_input); return _input.slice(36 + 1 + _varIntDataLen + _scriptSigLen, 4); } function extractSequenceLegacy(bytes memory _input) internal pure returns (uint32) { bytes memory _leSeqence = extractSequenceLELegacy(_input); bytes memory _beSequence = reverseEndianness(_leSeqence); return uint32(bytesToUint(_beSequence)); } function extractScriptSig(bytes memory _input) internal pure returns (bytes memory) { uint8 _varIntDataLen; uint256 _scriptSigLen; (_varIntDataLen, _scriptSigLen) = extractScriptSigLen(_input); return _input.slice(36, 1 + _varIntDataLen + _scriptSigLen); } function extractScriptSigLen(bytes memory _input) internal pure returns (uint8, uint256) { bytes memory _varIntTag = _input.slice(36, 1); uint8 _varIntDataLen = determineVarIntDataLength(_varIntTag); uint256 _len; if (_varIntDataLen == 0) { _len = uint8(_varIntTag[0]); } else { _len = bytesToUint(reverseEndianness(_input.slice(36 + 1, _varIntDataLen))); } return (_varIntDataLen, _len); } function extractSequenceLEWitness(bytes memory _input) internal pure returns (bytes memory) { return _input.slice(37, 4); } function extractSequenceWitness(bytes memory _input) internal pure returns (uint32) { bytes memory _leSeqence = extractSequenceLEWitness(_input); bytes memory _inputeSequence = reverseEndianness(_leSeqence); return uint32(bytesToUint(_inputeSequence)); } function extractOutpoint(bytes memory _input) internal pure returns (bytes memory) { return _input.slice(0, 36); } function extractInputTxIdLE(bytes memory _input) internal pure returns (bytes32) { return _input.slice(0, 32).toBytes32(); } function extractInputTxId(bytes memory _input) internal pure returns (bytes32) { bytes memory _leId = abi.encodePacked(extractInputTxIdLE(_input)); bytes memory _beId = reverseEndianness(_leId); return _beId.toBytes32(); } function extractTxIndexLE(bytes memory _input) internal pure returns (bytes memory) { return _input.slice(32, 4); } function extractTxIndex(bytes memory _input) internal pure returns (uint32) { bytes memory _leIndex = extractTxIndexLE(_input); bytes memory _beIndex = reverseEndianness(_leIndex); return uint32(bytesToUint(_beIndex)); } function determineOutputLength(bytes memory _output) internal pure returns (uint256) { uint8 _len = uint8(_output.slice(8, 1)[0]); require(_len < 0xfd, "Multi-byte VarInts not supported"); return _len + 8 + 1; } function extractOutputAtIndex(bytes memory _vout, uint8 _index) internal pure returns (bytes memory) { uint256 _len; bytes memory _remaining; uint256 _offset = 1; for (uint8 _i = 0; _i < _index; _i ++) { _remaining = _vout.slice(_offset, _vout.length - _offset); _len = determineOutputLength(_remaining); _offset = _offset + _len; } _remaining = _vout.slice(_offset, _vout.length - _offset); _len = determineOutputLength(_remaining); return _vout.slice(_offset, _len); } function extractOutputScriptLen(bytes memory _output) internal pure returns (bytes memory) { return _output.slice(8, 1); } function extractValueLE(bytes memory _output) internal pure returns (bytes memory) { return _output.slice(0, 8); } function extractValue(bytes memory _output) internal pure returns (uint64) { bytes memory _leValue = extractValueLE(_output); bytes memory _beValue = reverseEndianness(_leValue); return uint64(bytesToUint(_beValue)); } function extractOpReturnData(bytes memory _output) internal pure returns (bytes memory) { if (keccak256(_output.slice(9, 1)) != keccak256(hex"6a")) { return hex""; } bytes memory _dataLen = _output.slice(10, 1); return _output.slice(11, bytesToUint(_dataLen)); } function extractHash(bytes memory _output) internal pure returns (bytes memory) { if (uint8(_output.slice(9, 1)[0]) == 0) { uint256 _len = uint8(extractOutputScriptLen(_output)[0]) - 2; if (uint8(_output.slice(10, 1)[0]) != uint8(_len)) { return hex""; } return _output.slice(11, _len); } else { bytes32 _tag = keccak256(_output.slice(8, 3)); if (_tag == keccak256(hex"1976a9")) { if (uint8(_output.slice(11, 1)[0]) != 0x14 || keccak256(_output.slice(_output.length - 2, 2)) != keccak256(hex"88ac")) { return hex""; } return _output.slice(12, 20); } else if (_tag == keccak256(hex"17a914")) { if (uint8(_output.slice(_output.length - 1, 1)[0]) != 0x87) { return hex""; } return _output.slice(11, 20); } } return hex""; } function validateVin(bytes memory _vin) internal pure returns (bool) { uint256 _offset = 1; uint8 _nIns = uint8(_vin.slice(0, 1)[0]); if (_nIns >= 0xfd || _nIns == 0) { return false; } for (uint8 i = 0; i < _nIns; i++) { _offset += determineInputLength(_vin.slice(_offset, _vin.length - _offset)); if (_offset > _vin.length) { return false; } } return _offset == _vin.length; } function validateVout(bytes memory _vout) internal pure returns (bool) { uint256 _offset = 1; uint8 _nOuts = uint8(_vout.slice(0, 1)[0]); if (_nOuts >= 0xfd || _nOuts == 0) { return false; } for (uint8 i = 0; i < _nOuts; i++) { _offset += determineOutputLength(_vout.slice(_offset, _vout.length - _offset)); if (_offset > _vout.length) { return false; } } return _offset == _vout.length; } function extractMerkleRootLE(bytes memory _header) internal pure returns (bytes memory) { return _header.slice(36, 32); } function extractMerkleRootBE(bytes memory _header) internal pure returns (bytes memory) { return reverseEndianness(extractMerkleRootLE(_header)); } function extractTarget(bytes memory _header) internal pure returns (uint256) { bytes memory _m = _header.slice(72, 3); uint8 _e = uint8(_header[75]); uint256 _mantissa = bytesToUint(reverseEndianness(_m)); uint _exponent = _e - 3; return _mantissa * (256 ** _exponent); } function calculateDifficulty(uint256 _target) internal pure returns (uint256) { return DIFF1_TARGET.div(_target); } function extractPrevBlockLE(bytes memory _header) internal pure returns (bytes memory) { return _header.slice(4, 32); } function extractPrevBlockBE(bytes memory _header) internal pure returns (bytes memory) { return reverseEndianness(extractPrevBlockLE(_header)); } function extractTimestampLE(bytes memory _header) internal pure returns (bytes memory) { return _header.slice(68, 4); } function extractTimestamp(bytes memory _header) internal pure returns (uint32) { return uint32(bytesToUint(reverseEndianness(extractTimestampLE(_header)))); } function extractDifficulty(bytes memory _header) internal pure returns (uint256) { return calculateDifficulty(extractTarget(_header)); } function _hash256MerkleStep(bytes memory _a, bytes memory _b) internal pure returns (bytes32) { return hash256(abi.encodePacked(_a, _b)); } function verifyHash256Merkle(bytes memory _proof, uint _index) internal pure returns (bool) { if (_proof.length % 32 != 0) { return false; } if (_proof.length == 32) { return true; } if (_proof.length == 64) { return false; } uint _idx = _index; bytes32 _root = _proof.slice(_proof.length - 32, 32).toBytes32(); bytes32 _current = _proof.slice(0, 32).toBytes32(); for (uint i = 1; i < (_proof.length.div(32)) - 1; i++) { if (_idx % 2 == 1) { _current = _hash256MerkleStep(_proof.slice(i * 32, 32), abi.encodePacked(_current)); } else { _current = _hash256MerkleStep(abi.encodePacked(_current), _proof.slice(i * 32, 32)); } _idx = _idx >> 1; } return _current == _root; } function retargetAlgorithm( uint256 _previousTarget, uint256 _firstTimestamp, uint256 _secondTimestamp ) internal pure returns (uint256) { uint256 _elapsedTime = _secondTimestamp.sub(_firstTimestamp); if (_elapsedTime < RETARGET_PERIOD.div(4)) { _elapsedTime = RETARGET_PERIOD.div(4); } if (_elapsedTime > RETARGET_PERIOD.mul(4)) { _elapsedTime = RETARGET_PERIOD.mul(4); } uint256 _adjusted = _previousTarget.div(65536).mul(_elapsedTime); return _adjusted.div(RETARGET_PERIOD).mul(65536); } } interface FundsInterface { function lender(bytes32) external view returns (address); function custom(bytes32) external view returns (bool); function deposit(bytes32, uint256) external; function decreaseTotalBorrow(uint256) external; function calcGlobalInterest() external; } interface SalesInterface { function saleIndexByLoan(bytes32, uint256) external returns(bytes32); function settlementExpiration(bytes32) external view returns (uint256); function accepted(bytes32) external view returns (bool); function next(bytes32) external view returns (uint256); function create(bytes32, address, address, address, address, bytes32, bytes32, bytes32, bytes32, bytes20) external returns(bytes32); } interface CollateralInterface { function onDemandSpv() external view returns(address); function collateral(bytes32 loan) external view returns (uint256); function refundableCollateral(bytes32 loan) external view returns (uint256); function seizableCollateral(bytes32 loan) external view returns (uint256); function temporaryRefundableCollateral(bytes32 loan) external view returns (uint256); function temporarySeizableCollateral(bytes32 loan) external view returns (uint256); function setCollateral(bytes32 loan, uint256 refundableCollateral_, uint256 seizableCollateral_) external; function requestSpv(bytes32 loan) external; function cancelSpv(bytes32 loan) external; } contract DSMath { function add(uint x, uint y) internal pure returns (uint z) { require((z = x + y) >= x); } function sub(uint x, uint y) internal pure returns (uint z) { require((z = x - y) <= x); } function mul(uint x, uint y) internal pure returns (uint z) { require(y == 0 || (z = x * y) / y == x); } function div(uint a, uint b) internal pure returns (uint c) { require(b > 0); c = a / b; } function min(uint x, uint y) internal pure returns (uint z) { return x <= y ? x : y; } function max(uint x, uint y) internal pure returns (uint z) { return x >= y ? x : y; } function imin(int x, int y) internal pure returns (int z) { return x <= y ? x : y; } function imax(int x, int y) internal pure returns (int z) { return x >= y ? x : y; } uint constant COL = 10 ** 8; uint constant WAD = 10 ** 18; uint constant RAY = 10 ** 27; function cmul(uint x, uint y) public pure returns (uint z) { z = add(mul(x, y), COL / 2) / COL; } function wmul(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, y), WAD / 2) / WAD; } function rmul(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, y), RAY / 2) / RAY; } function cdiv(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, COL), y / 2) / y; } function wdiv(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, WAD), y / 2) / y; } function rdiv(uint x, uint y) internal pure returns (uint z) { z = add(mul(x, RAY), y / 2) / y; } function rpow(uint x, uint n) internal pure returns (uint z) { z = n % 2 != 0 ? x : RAY; for (n /= 2; n != 0; n /= 2) { x = rmul(x, x); if (n % 2 != 0) { z = rmul(z, x); } } } } contract Medianizer { function peek() external view returns (bytes32, bool); function read() external returns (bytes32); function poke() external; function poke(bytes32) external; function fund (uint256 amount, ERC20 token) external; } contract Loans is DSMath { FundsInterface funds; Medianizer med; SalesInterface sales; CollateralInterface col; uint256 public constant APPROVE_EXP_THRESHOLD = 4 hours; uint256 public constant ACCEPT_EXP_THRESHOLD = 2 days; uint256 public constant LIQUIDATION_EXP_THRESHOLD = 7 days; uint256 public constant SEIZURE_EXP_THRESHOLD = 2 days; uint256 public constant LIQUIDATION_DISCOUNT = 930000000000000000; uint256 public constant MAX_NUM_LIQUIDATIONS = 3; uint256 public constant MAX_UINT_256 = 2**256-1; mapping (bytes32 => Loan) public loans; mapping (bytes32 => PubKeys) public pubKeys; mapping (bytes32 => SecretHashes) public secretHashes; mapping (bytes32 => Bools) public bools; mapping (bytes32 => bytes32) public fundIndex; mapping (bytes32 => uint256) public repayments; mapping (address => bytes32[]) public borrowerLoans; mapping (address => bytes32[]) public lenderLoans; mapping (address => mapping(uint256 => bool)) public addressToTimestamp; uint256 public loanIndex; ERC20 public token; uint256 public decimals; address deployer; struct Loan { address borrower; address lender; address arbiter; uint256 createdAt; uint256 loanExpiration; uint256 requestTimestamp; uint256 closedTimestamp; uint256 principal; uint256 interest; uint256 penalty; uint256 fee; uint256 liquidationRatio; } struct PubKeys { bytes borrowerPubKey; bytes lenderPubKey; bytes arbiterPubKey; } struct SecretHashes { bytes32 secretHashA1; bytes32[3] secretHashAs; bytes32 secretHashB1; bytes32[3] secretHashBs; bytes32 secretHashC1; bytes32[3] secretHashCs; bytes32 withdrawSecret; bytes32 acceptSecret; bool set; } struct Bools { bool funded; bool approved; bool withdrawn; bool sale; bool paid; bool off; } event Create(bytes32 loan); event SetSecretHashes(bytes32 loan); event FundLoan(bytes32 loan); event Approve(bytes32 loan); event Withdraw(bytes32 loan, bytes32 secretA1); event Repay(bytes32 loan, uint256 amount); event Refund(bytes32 loan); event Cancel(bytes32 loan, bytes32 secret); event Accept(bytes32 loan, bytes32 secret); event Liquidate(bytes32 loan, bytes32 secretHash, bytes20 pubKeyHash); function borrower(bytes32 loan) external view returns (address) { return loans[loan].borrower; } function lender(bytes32 loan) external view returns (address) { return loans[loan].lender; } function arbiter(bytes32 loan) external view returns (address) { return loans[loan].arbiter; } function approveExpiration(bytes32 loan) public view returns (uint256) { return add(loans[loan].createdAt, APPROVE_EXP_THRESHOLD); } function acceptExpiration(bytes32 loan) public view returns (uint256) { return add(loans[loan].loanExpiration, ACCEPT_EXP_THRESHOLD); } function liquidationExpiration(bytes32 loan) public view returns (uint256) { return add(loans[loan].loanExpiration, LIQUIDATION_EXP_THRESHOLD); } function seizureExpiration(bytes32 loan) public view returns (uint256) { return add(liquidationExpiration(loan), SEIZURE_EXP_THRESHOLD); } function principal(bytes32 loan) public view returns (uint256) { return loans[loan].principal; } function interest(bytes32 loan) public view returns (uint256) { return loans[loan].interest; } function fee(bytes32 loan) public view returns (uint256) { return loans[loan].fee; } function penalty(bytes32 loan) public view returns (uint256) { return loans[loan].penalty; } function collateral(bytes32 loan) public view returns (uint256) { return col.collateral(loan); } function refundableCollateral(bytes32 loan) external view returns (uint256) { return col.refundableCollateral(loan); } function seizableCollateral(bytes32 loan) external view returns (uint256) { return col.seizableCollateral(loan); } function temporaryRefundableCollateral(bytes32 loan) external view returns (uint256) { return col.temporaryRefundableCollateral(loan); } function temporarySeizableCollateral(bytes32 loan) external view returns (uint256) { return col.temporarySeizableCollateral(loan); } function repaid(bytes32 loan) public view returns (uint256) { return repayments[loan]; } function liquidationRatio(bytes32 loan) public view returns (uint256) { return loans[loan].liquidationRatio; } function owedToLender(bytes32 loan) public view returns (uint256) { return add(principal(loan), interest(loan)); } function owedForLoan(bytes32 loan) public view returns (uint256) { return add(owedToLender(loan), fee(loan)); } function owedForLiquidation(bytes32 loan) external view returns (uint256) { return add(owedForLoan(loan), penalty(loan)); } function owing(bytes32 loan) external view returns (uint256) { return sub(owedForLoan(loan), repaid(loan)); } function funded(bytes32 loan) external view returns (bool) { return bools[loan].funded; } function approved(bytes32 loan) external view returns (bool) { return bools[loan].approved; } function withdrawn(bytes32 loan) external view returns (bool) { return bools[loan].withdrawn; } function sale(bytes32 loan) public view returns (bool) { return bools[loan].sale; } function paid(bytes32 loan) external view returns (bool) { return bools[loan].paid; } function off(bytes32 loan) public view returns (bool) { return bools[loan].off; } function dmul(uint x) public view returns (uint256) { return mul(x, (10 ** sub(18, decimals))); } function ddiv(uint x) public view returns (uint256) { return div(x, (10 ** sub(18, decimals))); } function borrowerLoanCount(address borrower_) external view returns (uint256) { return borrowerLoans[borrower_].length; } function lenderLoanCount(address lender_) external view returns (uint256) { return lenderLoans[lender_].length; } function minSeizableCollateral(bytes32 loan) public view returns (uint256) { (bytes32 val, bool set) = med.peek(); require(set, "Loans.minSeizableCollateral: Medianizer must be set"); uint256 price = uint(val); return div(wdiv(dmul(sub(owedForLoan(loan), repaid(loan))), price), div(WAD, COL)); } function collateralValue(bytes32 loan) public view returns (uint256) { (bytes32 val, bool set) = med.peek(); require(set, "Loans.collateralValue: Medianizer must be set"); uint256 price = uint(val); return cmul(price, collateral(loan)); } function minCollateralValue(bytes32 loan) public view returns (uint256) { return rmul(dmul(sub(owedForLoan(loan), repaid(loan))), liquidationRatio(loan)); } function discountCollateralValue(bytes32 loan) public view returns (uint256) { return wmul(collateralValue(loan), LIQUIDATION_DISCOUNT); } function safe(bytes32 loan) public view returns (bool) { return collateralValue(loan) >= minCollateralValue(loan); } constructor (FundsInterface funds_, Medianizer med_, ERC20 token_, uint256 decimals_) public { require(address(funds_) != address(0), "Funds address must be non-zero"); require(address(med_) != address(0), "Medianizer address must be non-zero"); require(address(token_) != address(0), "Token address must be non-zero"); deployer = msg.sender; funds = funds_; med = med_; token = token_; decimals = decimals_; require(token.approve(address(funds), MAX_UINT_256), "Token approve failed"); } function setSales(SalesInterface sales_) external { require(msg.sender == deployer, "Loans.setSales: Only the deployer can perform this"); require(address(sales) == address(0), "Loans.setSales: The Sales address has already been set"); require(address(sales_) != address(0), "Loans.setSales: Sales address must be non-zero"); sales = sales_; } function setCollateral(CollateralInterface col_) external { require(msg.sender == deployer, "Loans.setCollateral: Only the deployer can perform this"); require(address(col) == address(0), "Loans.setCollateral: The Collateral address has already been set"); require(address(col_) != address(0), "Loans.setCollateral: Collateral address must be non-zero"); col = col_; } function create( uint256 loanExpiration_, address[3] calldata usrs_, uint256[7] calldata vals_, bytes32 fund ) external returns (bytes32 loan) { if (fund != bytes32(0)) { require(funds.lender(fund) == usrs_[1], "Loans.create: Lender of Fund not in args"); } require(!addressToTimestamp[usrs_[0]][vals_[6]], "Loans.create: Duplicate request timestamps are not allowed"); require(loanExpiration_ > now, "Loans.create: loanExpiration must be greater than `now`"); require(usrs_[0] != address(0) && usrs_[1] != address(0), "Loans.create: Borrower and Lender address must be non-zero"); require(vals_[0] != 0 && vals_[4] != 0, "Loans.create: Principal and Collateral must be non-zero"); require(vals_[5] != 0 && vals_[6] != 0, "Loans.create: Liquidation ratio and Request timestamp must be non-zero"); loanIndex = add(loanIndex, 1); loan = bytes32(loanIndex); loans[loan].createdAt = now; loans[loan].loanExpiration = loanExpiration_; loans[loan].borrower = usrs_[0]; loans[loan].lender = usrs_[1]; loans[loan].arbiter = usrs_[2]; loans[loan].principal = vals_[0]; loans[loan].interest = vals_[1]; loans[loan].penalty = vals_[2]; loans[loan].fee = vals_[3]; uint256 minSeizableCol = minSeizableCollateral(loan); col.setCollateral(loan, sub(vals_[4], minSeizableCol), minSeizableCol); loans[loan].liquidationRatio = vals_[5]; loans[loan].requestTimestamp = vals_[6]; fundIndex[loan] = fund; secretHashes[loan].set = false; borrowerLoans[usrs_[0]].push(bytes32(loanIndex)); lenderLoans[usrs_[1]].push(bytes32(loanIndex)); addressToTimestamp[usrs_[0]][vals_[6]] = true; emit Create(loan); } function setSecretHashes( bytes32 loan, bytes32[4] calldata borrowerSecretHashes, bytes32[4] calldata lenderSecretHashes, bytes32[4] calldata arbiterSecretHashes, bytes calldata borrowerPubKey_, bytes calldata lenderPubKey_, bytes calldata arbiterPubKey_ ) external { require(!secretHashes[loan].set, "Loans.setSecretHashes: Secret hashes must not already be set"); require( msg.sender == loans[loan].borrower || msg.sender == loans[loan].lender || msg.sender == address(funds), "Loans.setSecretHashes: msg.sender must be Borrower, Lender or Funds Address" ); secretHashes[loan].secretHashA1 = borrowerSecretHashes[0]; secretHashes[loan].secretHashAs = [ borrowerSecretHashes[1], borrowerSecretHashes[2], borrowerSecretHashes[3] ]; secretHashes[loan].secretHashB1 = lenderSecretHashes[0]; secretHashes[loan].secretHashBs = [ lenderSecretHashes[1], lenderSecretHashes[2], lenderSecretHashes[3] ]; secretHashes[loan].secretHashC1 = arbiterSecretHashes[0]; secretHashes[loan].secretHashCs = [ arbiterSecretHashes[1], arbiterSecretHashes[2], arbiterSecretHashes[3] ]; pubKeys[loan].borrowerPubKey = borrowerPubKey_; pubKeys[loan].lenderPubKey = lenderPubKey_; pubKeys[loan].arbiterPubKey = arbiterPubKey_; secretHashes[loan].set = true; } function fund(bytes32 loan) external { require(secretHashes[loan].set, "Loans.fund: Secret hashes must be set"); require(bools[loan].funded == false, "Loans.fund: Loan is already funded"); bools[loan].funded = true; require(token.transferFrom(msg.sender, address(this), principal(loan)), "Loans.fund: Failed to transfer tokens"); emit FundLoan(loan); } function approve(bytes32 loan) external { require(bools[loan].funded == true, "Loans.approve: Loan must be funded"); require(loans[loan].lender == msg.sender, "Loans.approve: Only the lender can approve the loan"); require(now <= approveExpiration(loan), "Loans.approve: Loan is past the approve deadline"); bools[loan].approved = true; emit Approve(loan); } function withdraw(bytes32 loan, bytes32 secretA1) external { require(!off(loan), "Loans.withdraw: Loan cannot be inactive"); require(bools[loan].funded == true, "Loans.withdraw: Loan must be funded"); require(bools[loan].approved == true, "Loans.withdraw: Loan must be approved"); require(bools[loan].withdrawn == false, "Loans.withdraw: Loan principal has already been withdrawn"); require(sha256(abi.encodePacked(secretA1)) == secretHashes[loan].secretHashA1, "Loans.withdraw: Secret does not match"); bools[loan].withdrawn = true; require(token.transfer(loans[loan].borrower, principal(loan)), "Loans.withdraw: Failed to transfer tokens"); secretHashes[loan].withdrawSecret = secretA1; if (address(col.onDemandSpv()) != address(0)) {col.requestSpv(loan);} emit Withdraw(loan, secretA1); } function repay(bytes32 loan, uint256 amount) external { require(!off(loan), "Loans.repay: Loan cannot be inactive"); require(!sale(loan), "Loans.repay: Loan cannot be undergoing a liquidation"); require(bools[loan].withdrawn == true, "Loans.repay: Loan principal must be withdrawn"); require(now <= loans[loan].loanExpiration, "Loans.repay: Loan cannot have expired"); require(add(amount, repaid(loan)) <= owedForLoan(loan), "Loans.repay: Cannot repay more than the owed amount"); require(token.transferFrom(msg.sender, address(this), amount), "Loans.repay: Failed to transfer tokens"); repayments[loan] = add(amount, repayments[loan]); if (repaid(loan) == owedForLoan(loan)) { bools[loan].paid = true; if (address(col.onDemandSpv()) != address(0)) {col.cancelSpv(loan);} } emit Repay(loan, amount); } function refund(bytes32 loan) external { require(!off(loan), "Loans.refund: Loan cannot be inactive"); require(!sale(loan), "Loans.refund: Loan cannot be undergoing a liquidation"); require(now > acceptExpiration(loan), "Loans.refund: Cannot request refund until after acceptExpiration"); require(bools[loan].paid == true, "Loans.refund: The loan must be repaid"); require(msg.sender == loans[loan].borrower, "Loans.refund: Only the borrower can request a refund"); bools[loan].off = true; loans[loan].closedTimestamp = now; if (funds.custom(fundIndex[loan]) == false) { funds.decreaseTotalBorrow(loans[loan].principal); funds.calcGlobalInterest(); } require(token.transfer(loans[loan].borrower, owedForLoan(loan)), "Loans.refund: Failed to transfer tokens"); emit Refund(loan); } function cancel(bytes32 loan, bytes32 secret) external { accept(loan, secret); emit Cancel(loan, secret); } function cancel(bytes32 loan) external { require(!off(loan), "Loans.cancel: Loan must not be inactive"); require(bools[loan].withdrawn == false, "Loans.cancel: Loan principal must not be withdrawn"); require(now >= seizureExpiration(loan), "Loans.cancel: Seizure deadline has not been reached"); require(bools[loan].sale == false, "Loans.cancel: Loan must not be undergoing liquidation"); close(loan); emit Cancel(loan, bytes32(0)); } function accept(bytes32 loan, bytes32 secret) public { require(!off(loan), "Loans.accept: Loan must not be inactive"); require(bools[loan].withdrawn == false || bools[loan].paid == true, "Loans.accept: Loan must be either not withdrawn or repaid"); require(msg.sender == loans[loan].lender || msg.sender == loans[loan].arbiter, "Loans.accept: msg.sender must be lender or arbiter"); require(now <= acceptExpiration(loan), "Loans.accept: Acceptance deadline has past"); require(bools[loan].sale == false, "Loans.accept: Loan must not be going under liquidation"); require( sha256(abi.encodePacked(secret)) == secretHashes[loan].secretHashB1 || sha256(abi.encodePacked(secret)) == secretHashes[loan].secretHashC1, "Loans.accept: Invalid secret" ); secretHashes[loan].acceptSecret = secret; close(loan); emit Accept(loan, secret); } function close(bytes32 loan) private { bools[loan].off = true; loans[loan].closedTimestamp = now; if (bools[loan].withdrawn == false) { if (fundIndex[loan] == bytes32(0)) { require(token.transfer(loans[loan].lender, loans[loan].principal), "Loans.close: Failed to transfer principal to Lender"); } else { if (funds.custom(fundIndex[loan]) == false) { funds.decreaseTotalBorrow(loans[loan].principal); } funds.deposit(fundIndex[loan], loans[loan].principal); } } else { if (fundIndex[loan] == bytes32(0)) { require(token.transfer(loans[loan].lender, owedToLender(loan)), "Loans.close: Failed to transfer owedToLender to Lender"); } else { if (funds.custom(fundIndex[loan]) == false) { funds.decreaseTotalBorrow(loans[loan].principal); } funds.deposit(fundIndex[loan], owedToLender(loan)); } require(token.transfer(loans[loan].arbiter, fee(loan)), "Loans.close: Failed to transfer fee to Arbiter"); } } function liquidate(bytes32 loan, bytes32 secretHash, bytes20 pubKeyHash) external returns (bytes32 sale_) { require(!off(loan), "Loans.liquidate: Loan must not be inactive"); require(bools[loan].withdrawn == true, "Loans.liquidate: Loan principal must be withdrawn"); require(msg.sender != loans[loan].borrower && msg.sender != loans[loan].lender, "Loans.liquidate: Liquidator must be a third-party"); require(secretHash != bytes32(0) && pubKeyHash != bytes20(0), "Loans.liquidate: secretHash and pubKeyHash must be non-zero"); if (sales.next(loan) == 0) { if (now > loans[loan].loanExpiration) { require(bools[loan].paid == false, "Loans.liquidate: loan must not have already been repaid"); } else { require(!safe(loan), "Loans.liquidate: collateralization must be below min-collateralization ratio"); } if (funds.custom(fundIndex[loan]) == false) { funds.decreaseTotalBorrow(loans[loan].principal); funds.calcGlobalInterest(); } } else { require(sales.next(loan) < MAX_NUM_LIQUIDATIONS, "Loans.liquidate: Max number of liquidations reached"); require(!sales.accepted(sales.saleIndexByLoan(loan, sales.next(loan) - 1)), "Loans.liquidate: Previous liquidation already accepted"); require( now > sales.settlementExpiration(sales.saleIndexByLoan(loan, sales.next(loan) - 1)), "Loans.liquidate: Previous liquidation settlement expiration hasn't expired" ); } require(token.balanceOf(msg.sender) >= ddiv(discountCollateralValue(loan)), "Loans.liquidate: insufficient balance to liquidate"); require(token.transferFrom(msg.sender, address(sales), ddiv(discountCollateralValue(loan))), "Loans.liquidate: Token transfer failed"); SecretHashes storage h = secretHashes[loan]; uint256 i = sales.next(loan); sale_ = sales.create( loan, loans[loan].borrower, loans[loan].lender, loans[loan].arbiter, msg.sender, h.secretHashAs[i], h.secretHashBs[i], h.secretHashCs[i], secretHash, pubKeyHash ); if (bools[loan].sale == false) { bools[loan].sale = true; require(token.transfer(address(sales), repaid(loan)), "Loans.liquidate: Token transfer to Sales contract failed"); } if (address(col.onDemandSpv()) != address(0)) {col.cancelSpv(loan);} emit Liquidate(loan, secretHash, pubKeyHash); } } interface CTokenInterface { function redeem(uint redeemTokens) external returns (uint); function redeemUnderlying(uint redeemAmount) external returns (uint); function borrow(uint borrowAmount) external returns (uint); function liquidateBorrow(address borrower, uint repayAmount, address cTokenCollateral) external returns (uint); function liquidateBorrow(address borrower, address cTokenCollateral) external payable; function exchangeRateCurrent() external returns (uint); function getCash() external view returns (uint); function totalBorrowsCurrent() external returns (uint); function borrowRatePerBlock() external view returns (uint); function supplyRatePerBlock() external view returns (uint); function totalReserves() external view returns (uint); function reserveFactorMantissa() external view returns (uint); function totalSupply() external view returns (uint256); function balanceOf(address owner) external view returns (uint256 balance); function allowance(address, address) external view returns (uint); function approve(address, uint) external; function transfer(address, uint) external returns (bool); function transferFrom(address, address, uint) external returns (bool); } interface CERC20Interface { function mint(uint mintAmount) external returns (uint); function repayBorrow(uint repayAmount) external returns (uint); function repayBorrowBehalf(address borrower, uint repayAmount) external returns (uint); function borrowBalanceCurrent(address account) external returns (uint); } interface ERC20Interface { function allowance(address, address) external view returns (uint); function balanceOf(address) external view returns (uint); function approve(address, uint) external; function transfer(address, uint) external returns (bool); function transferFrom(address, address, uint) external returns (bool); } interface TrollerInterface { function enterMarkets(address[] calldata cTokens) external returns (uint[] memory); function exitMarket(address cTokenAddress) external returns (uint); function getAssetsIn(address account) external view returns (address[] memory); function getAccountLiquidity(address account) external view returns (uint, uint, uint); } contract Helpers is DSMath { address public comptroller; function getComptrollerAddress() public view returns (address) { return comptroller; } function enterMarket(address cErc20) internal { TrollerInterface troller = TrollerInterface(getComptrollerAddress()); address[] memory markets = troller.getAssetsIn(address(this)); bool isEntered = false; for (uint i = 0; i < markets.length; i++) { if (markets[i] == cErc20) { isEntered = true; } } if (!isEntered) { address[] memory toEnter = new address[](1); toEnter[0] = cErc20; troller.enterMarkets(toEnter); } } function setApproval(address erc20, uint srcAmt, address to) internal { ERC20Interface erc20Contract = ERC20Interface(erc20); uint tokenAllowance = erc20Contract.allowance(address(this), to); if (srcAmt > tokenAllowance) { erc20Contract.approve(to, 2**255); } } } contract ALCompound is Helpers { function mintCToken(address erc20, address cErc20, uint tokenAmt) internal { enterMarket(cErc20); ERC20Interface token = ERC20Interface(erc20); uint toDeposit = token.balanceOf(address(this)); if (toDeposit > tokenAmt) { toDeposit = tokenAmt; } CERC20Interface cToken = CERC20Interface(cErc20); setApproval(erc20, toDeposit, cErc20); assert(cToken.mint(toDeposit) == 0); } function redeemUnderlying(address cErc20, uint tokenAmt) internal { CTokenInterface cToken = CTokenInterface(cErc20); setApproval(cErc20, 10**50, cErc20); uint toBurn = cToken.balanceOf(address(this)); uint tokenToReturn = wmul(toBurn, cToken.exchangeRateCurrent()); if (tokenToReturn > tokenAmt) { tokenToReturn = tokenAmt; } require(cToken.redeemUnderlying(tokenToReturn) == 0, "something went wrong"); } function redeemCToken(address cErc20, uint cTokenAmt) internal { CTokenInterface cToken = CTokenInterface(cErc20); uint toBurn = cToken.balanceOf(address(this)); if (toBurn > cTokenAmt) { toBurn = cTokenAmt; } setApproval(cErc20, toBurn, cErc20); require(cToken.redeem(toBurn) == 0, "something went wrong"); } } contract Funds is DSMath, ALCompound { Loans loans; uint256 public constant DEFAULT_LIQUIDATION_RATIO = 1400000000000000000000000000; uint256 public constant DEFAULT_LIQUIDATION_PENALTY = 1000000000937303470807876289; uint256 public constant DEFAULT_MIN_LOAN_AMT = 25 ether; uint256 public constant DEFAULT_MAX_LOAN_AMT = 2**256-1; uint256 public constant DEFAULT_MIN_LOAN_DUR = 6 hours; uint256 public constant NUM_SECONDS_IN_YEAR = 365 days; uint256 public constant MAX_LOAN_LENGTH = 10 * NUM_SECONDS_IN_YEAR; uint256 public constant MAX_UINT_256 = 2**256-1; mapping (address => bytes32[]) public secretHashes; mapping (address => uint256) public secretHashIndex; mapping (address => bytes) public pubKeys; mapping (bytes32 => Fund) public funds; mapping (address => bytes32) public fundOwner; mapping (bytes32 => Bools) public bools; uint256 public fundIndex; uint256 public lastGlobalInterestUpdated; uint256 public tokenMarketLiquidity; uint256 public cTokenMarketLiquidity; uint256 public marketLiquidity; uint256 public totalBorrow; uint256 public globalInterestRateNumerator; uint256 public lastUtilizationRatio; uint256 public globalInterestRate; uint256 public maxUtilizationDelta; uint256 public utilizationInterestDivisor; uint256 public maxInterestRateNumerator; uint256 public minInterestRateNumerator; uint256 public interestUpdateDelay; uint256 public defaultArbiterFee; ERC20 public token; uint256 public decimals; CTokenInterface public cToken; bool compoundSet; address deployer; struct Fund { address lender; uint256 minLoanAmt; uint256 maxLoanAmt; uint256 minLoanDur; uint256 maxLoanDur; uint256 fundExpiry; uint256 interest; uint256 penalty; uint256 fee; uint256 liquidationRatio; address arbiter; uint256 balance; uint256 cBalance; } struct Bools { bool custom; bool compoundEnabled; } event Create(bytes32 fund); event Deposit(bytes32 fund, uint256 amount_); event Update(bytes32 fund, uint256 maxLoanDur_, uint256 fundExpiry_, address arbiter_); event Request(bytes32 fund, address borrower_, uint256 amount_, uint256 collateral_, uint256 loanDur_, uint256 requestTimestamp_); event Withdraw(bytes32 fund, uint256 amount_, address recipient_); event EnableCompound(bytes32 fund); event DisableCompound(bytes32 fund); constructor( ERC20 token_, uint256 decimals_ ) public { require(address(token_) != address(0), "Funds.constructor: Token address must be non-zero"); require(decimals_ != 0, "Funds.constructor: Decimals must be non-zero"); deployer = msg.sender; token = token_; decimals = decimals_; utilizationInterestDivisor = 10531702972595856680093239305; maxUtilizationDelta = 95310179948351216961192521; globalInterestRateNumerator = 95310179948351216961192521; maxInterestRateNumerator = 182321557320989604265864303; minInterestRateNumerator = 24692612600038629323181834; interestUpdateDelay = 86400; defaultArbiterFee = 1000000000236936036262880196; globalInterestRate = add(RAY, div(globalInterestRateNumerator, NUM_SECONDS_IN_YEAR)); } function setLoans(Loans loans_) external { require(msg.sender == deployer, "Funds.setLoans: Only the deployer can perform this"); require(address(loans) == address(0), "Funds.setLoans: Loans address has already been set"); require(address(loans_) != address(0), "Funds.setLoans: Loans address must be non-zero"); loans = loans_; require(token.approve(address(loans_), MAX_UINT_256), "Funds.setLoans: Tokens cannot be approved"); } function setCompound(CTokenInterface cToken_, address comptroller_) external { require(msg.sender == deployer, "Funds.setCompound: Only the deployer can enable Compound lending"); require(!compoundSet, "Funds.setCompound: Compound address has already been set"); require(address(cToken_) != address(0), "Funds.setCompound: cToken address must be non-zero"); require(comptroller_ != address(0), "Funds.setCompound: comptroller address must be non-zero"); cToken = cToken_; comptroller = comptroller_; compoundSet = true; } function setUtilizationInterestDivisor(uint256 utilizationInterestDivisor_) external { require(msg.sender == deployer, "Funds.setUtilizationInterestDivisor: Only the deployer can perform this"); require(utilizationInterestDivisor_ != 0, "Funds.setUtilizationInterestDivisor: utilizationInterestDivisor is zero"); utilizationInterestDivisor = utilizationInterestDivisor_; } function setMaxUtilizationDelta(uint256 maxUtilizationDelta_) external { require(msg.sender == deployer, "Funds.setMaxUtilizationDelta: Only the deployer can perform this"); require(maxUtilizationDelta_ != 0, "Funds.setMaxUtilizationDelta: maxUtilizationDelta is zero"); maxUtilizationDelta = maxUtilizationDelta_; } function setGlobalInterestRateNumerator(uint256 globalInterestRateNumerator_) external { require(msg.sender == deployer, "Funds.setGlobalInterestRateNumerator: Only the deployer can perform this"); require(globalInterestRateNumerator_ != 0, "Funds.setGlobalInterestRateNumerator: globalInterestRateNumerator is zero"); globalInterestRateNumerator = globalInterestRateNumerator_; } function setGlobalInterestRate(uint256 globalInterestRate_) external { require(msg.sender == deployer, "Funds.setGlobalInterestRate: Only the deployer can perform this"); require(globalInterestRate_ != 0, "Funds.setGlobalInterestRate: globalInterestRate is zero"); globalInterestRate = globalInterestRate_; } function setMaxInterestRateNumerator(uint256 maxInterestRateNumerator_) external { require(msg.sender == deployer, "Funds.setMaxInterestRateNumerator: Only the deployer can perform this"); require(maxInterestRateNumerator_ != 0, "Funds.setMaxInterestRateNumerator: maxInterestRateNumerator is zero"); maxInterestRateNumerator = maxInterestRateNumerator_; } function setMinInterestRateNumerator(uint256 minInterestRateNumerator_) external { require(msg.sender == deployer, "Funds.setMinInterestRateNumerator: Only the deployer can perform this"); require(minInterestRateNumerator_ != 0, "Funds.setMinInterestRateNumerator: minInterestRateNumerator is zero"); minInterestRateNumerator = minInterestRateNumerator_; } function setInterestUpdateDelay(uint256 interestUpdateDelay_) external { require(msg.sender == deployer, "Funds.setInterestUpdateDelay: Only the deployer can perform this"); require(interestUpdateDelay_ != 0, "Funds.setInterestUpdateDelay: interestUpdateDelay is zero"); interestUpdateDelay = interestUpdateDelay_; } function setDefaultArbiterFee(uint256 defaultArbiterFee_) external { require(msg.sender == deployer, "Funds.setDefaultArbiterFee: Only the deployer can perform this"); require(defaultArbiterFee_ <= 1000000000315522921573372069, "Funds.setDefaultArbiterFee: defaultArbiterFee cannot be less than -1%"); defaultArbiterFee = defaultArbiterFee_; } function lender(bytes32 fund) public view returns (address) { return funds[fund].lender; } function minLoanAmt(bytes32 fund) public view returns (uint256) { if (bools[fund].custom) {return funds[fund].minLoanAmt;} else {return div(DEFAULT_MIN_LOAN_AMT, (10 ** sub(18, decimals)));} } function maxLoanAmt(bytes32 fund) public view returns (uint256) { if (bools[fund].custom) {return funds[fund].maxLoanAmt;} else {return DEFAULT_MAX_LOAN_AMT;} } function minLoanDur(bytes32 fund) public view returns (uint256) { if (bools[fund].custom) {return funds[fund].minLoanDur;} else {return DEFAULT_MIN_LOAN_DUR;} } function maxLoanDur(bytes32 fund) public view returns (uint256) { return funds[fund].maxLoanDur; } function fundExpiry(bytes32 fund) public view returns (uint256) { return funds[fund].fundExpiry; } function interest(bytes32 fund) public view returns (uint256) { if (bools[fund].custom) {return funds[fund].interest;} else {return globalInterestRate;} } function penalty(bytes32 fund) public view returns (uint256) { if (bools[fund].custom) {return funds[fund].penalty;} else {return DEFAULT_LIQUIDATION_PENALTY;} } function fee(bytes32 fund) public view returns (uint256) { if (bools[fund].custom) {return funds[fund].fee;} else {return defaultArbiterFee;} } function liquidationRatio(bytes32 fund) public view returns (uint256) { if (bools[fund].custom) {return funds[fund].liquidationRatio;} else {return DEFAULT_LIQUIDATION_RATIO;} } function arbiter(bytes32 fund) public view returns (address) { return funds[fund].arbiter; } function balance(bytes32 fund) public returns (uint256) { if (bools[fund].compoundEnabled) { return wmul(funds[fund].cBalance, cToken.exchangeRateCurrent()); } else { return funds[fund].balance; } } function cTokenExchangeRate() public returns (uint256) { if (compoundSet) { return cToken.exchangeRateCurrent(); } else { return 0; } } function custom(bytes32 fund) public view returns (bool) { return bools[fund].custom; } function secretHashesCount(address addr_) public view returns (uint256) { return secretHashes[addr_].length; } function create( uint256 maxLoanDur_, uint256 fundExpiry_, address arbiter_, bool compoundEnabled_, uint256 amount_ ) external returns (bytes32 fund) { require(funds[fundOwner[msg.sender]].lender != msg.sender, "Funds.create: Only one loan fund allowed per address"); require( ensureNotZero(maxLoanDur_, false) < MAX_LOAN_LENGTH && ensureNotZero(fundExpiry_, true) < now + MAX_LOAN_LENGTH, "Funds.create: fundExpiry and maxLoanDur cannot exceed 10 years" ); if (!compoundSet) {require(compoundEnabled_ == false, "Funds.create: Cannot enable Compound as it has not been configured");} fundIndex = add(fundIndex, 1); fund = bytes32(fundIndex); funds[fund].lender = msg.sender; funds[fund].maxLoanDur = ensureNotZero(maxLoanDur_, false); funds[fund].fundExpiry = ensureNotZero(fundExpiry_, true); funds[fund].arbiter = arbiter_; bools[fund].custom = false; bools[fund].compoundEnabled = compoundEnabled_; fundOwner[msg.sender] = bytes32(fundIndex); if (amount_ > 0) {deposit(fund, amount_);} emit Create(fund); } function createCustom( uint256 minLoanAmt_, uint256 maxLoanAmt_, uint256 minLoanDur_, uint256 maxLoanDur_, uint256 fundExpiry_, uint256 liquidationRatio_, uint256 interest_, uint256 penalty_, uint256 fee_, address arbiter_, bool compoundEnabled_, uint256 amount_ ) external returns (bytes32 fund) { require(funds[fundOwner[msg.sender]].lender != msg.sender, "Funds.create: Only one loan fund allowed per address"); require( ensureNotZero(maxLoanDur_, false) < MAX_LOAN_LENGTH && ensureNotZero(fundExpiry_, true) < now + MAX_LOAN_LENGTH, "Funds.createCustom: fundExpiry and maxLoanDur cannot exceed 10 years" ); require(maxLoanAmt_ >= minLoanAmt_, "Funds.createCustom: maxLoanAmt must be greater than or equal to minLoanAmt"); require(ensureNotZero(maxLoanDur_, false) >= minLoanDur_, "Funds.createCustom: maxLoanDur must be greater than or equal to minLoanDur"); if (!compoundSet) {require(compoundEnabled_ == false, "Funds.createCustom: Cannot enable Compound as it has not been configured");} fundIndex = add(fundIndex, 1); fund = bytes32(fundIndex); funds[fund].lender = msg.sender; funds[fund].minLoanAmt = minLoanAmt_; funds[fund].maxLoanAmt = maxLoanAmt_; funds[fund].minLoanDur = minLoanDur_; funds[fund].maxLoanDur = ensureNotZero(maxLoanDur_, false); funds[fund].fundExpiry = ensureNotZero(fundExpiry_, true); funds[fund].interest = interest_; funds[fund].penalty = penalty_; funds[fund].fee = fee_; funds[fund].liquidationRatio = liquidationRatio_; funds[fund].arbiter = arbiter_; bools[fund].custom = true; bools[fund].compoundEnabled = compoundEnabled_; fundOwner[msg.sender] = bytes32(fundIndex); if (amount_ > 0) {deposit(fund, amount_);} emit Create(fund); } function deposit(bytes32 fund, uint256 amount_) public { require(token.transferFrom(msg.sender, address(this), amount_), "Funds.deposit: Failed to transfer tokens"); if (bools[fund].compoundEnabled) { mintCToken(address(token), address(cToken), amount_); uint256 cTokenToAdd = div(mul(amount_, WAD), cToken.exchangeRateCurrent()); funds[fund].cBalance = add(funds[fund].cBalance, cTokenToAdd); if (!custom(fund)) {cTokenMarketLiquidity = add(cTokenMarketLiquidity, cTokenToAdd);} } else { funds[fund].balance = add(funds[fund].balance, amount_); if (!custom(fund)) {tokenMarketLiquidity = add(tokenMarketLiquidity, amount_);} } if (!custom(fund)) {calcGlobalInterest();} emit Deposit(fund, amount_); } function update( bytes32 fund, uint256 maxLoanDur_, uint256 fundExpiry_, address arbiter_ ) public { require(msg.sender == lender(fund), "Funds.update: Only the lender can update the fund"); require( ensureNotZero(maxLoanDur_, false) <= MAX_LOAN_LENGTH && ensureNotZero(fundExpiry_, true) <= now + MAX_LOAN_LENGTH, "Funds.update: fundExpiry and maxLoanDur cannot exceed 10 years" ); funds[fund].maxLoanDur = maxLoanDur_; funds[fund].fundExpiry = fundExpiry_; funds[fund].arbiter = arbiter_; emit Update(fund, maxLoanDur_, fundExpiry_, arbiter_); } function updateCustom( bytes32 fund, uint256 minLoanAmt_, uint256 maxLoanAmt_, uint256 minLoanDur_, uint256 maxLoanDur_, uint256 fundExpiry_, uint256 interest_, uint256 penalty_, uint256 fee_, uint256 liquidationRatio_, address arbiter_ ) external { require(bools[fund].custom, "Funds.updateCustom: Fund must be a custom fund"); require(maxLoanAmt_ >= minLoanAmt_, "Funds.updateCustom: maxLoanAmt must be greater than or equal to minLoanAmt"); require(ensureNotZero(maxLoanDur_, false) >= minLoanDur_, "Funds.updateCustom: maxLoanDur must be greater than or equal to minLoanDur"); update(fund, maxLoanDur_, fundExpiry_, arbiter_); funds[fund].minLoanAmt = minLoanAmt_; funds[fund].maxLoanAmt = maxLoanAmt_; funds[fund].minLoanDur = minLoanDur_; funds[fund].interest = interest_; funds[fund].penalty = penalty_; funds[fund].fee = fee_; funds[fund].liquidationRatio = liquidationRatio_; } function request( bytes32 fund, address borrower_, uint256 amount_, uint256 collateral_, uint256 loanDur_, uint256 requestTimestamp_, bytes32[8] calldata secretHashes_, bytes calldata pubKeyA_, bytes calldata pubKeyB_ ) external returns (bytes32 loanIndex) { require(msg.sender == lender(fund), "Funds.request: Only the lender can fulfill a loan request"); require(amount_ <= balance(fund), "Funds.request: Insufficient balance"); require(amount_ >= minLoanAmt(fund), "Funds.request: Amount requested must be greater than minLoanAmt"); require(amount_ <= maxLoanAmt(fund), "Funds.request: Amount requested must be less than maxLoanAmt"); require(loanDur_ >= minLoanDur(fund), "Funds.request: Loan duration must be greater than minLoanDur"); require(loanDur_ <= sub(fundExpiry(fund), now) && loanDur_ <= maxLoanDur(fund), "Funds.request: Loan duration must be less than maxLoanDur and expiry"); require(borrower_ != address(0), "Funds.request: Borrower address must be non-zero"); require(secretHashes_[0] != bytes32(0) && secretHashes_[1] != bytes32(0), "Funds.request: SecretHash1 & SecretHash2 should be non-zero"); require(secretHashes_[2] != bytes32(0) && secretHashes_[3] != bytes32(0), "Funds.request: SecretHash3 & SecretHash4 should be non-zero"); require(secretHashes_[4] != bytes32(0) && secretHashes_[5] != bytes32(0), "Funds.request: SecretHash5 & SecretHash6 should be non-zero"); require(secretHashes_[6] != bytes32(0) && secretHashes_[7] != bytes32(0), "Funds.request: SecretHash7 & SecretHash8 should be non-zero"); loanIndex = createLoan(fund, borrower_, amount_, collateral_, loanDur_, requestTimestamp_); loanSetSecretHashes(fund, loanIndex, secretHashes_, pubKeyA_, pubKeyB_); loanUpdateMarketLiquidity(fund, amount_); loans.fund(loanIndex); emit Request(fund, borrower_, amount_, collateral_, loanDur_, requestTimestamp_); } function withdraw(bytes32 fund, uint256 amount_) external { withdrawTo(fund, amount_, msg.sender); } function withdrawTo(bytes32 fund, uint256 amount_, address recipient_) public { require(msg.sender == lender(fund), "Funds.withdrawTo: Only the lender can withdraw tokens"); require(balance(fund) >= amount_, "Funds.withdrawTo: Insufficient balance"); if (bools[fund].compoundEnabled) { uint256 cBalanceBefore = cToken.balanceOf(address(this)); redeemUnderlying(address(cToken), amount_); uint256 cBalanceAfter = cToken.balanceOf(address(this)); uint256 cTokenToRemove = sub(cBalanceBefore, cBalanceAfter); funds[fund].cBalance = sub(funds[fund].cBalance, cTokenToRemove); require(token.transfer(recipient_, amount_), "Funds.withdrawTo: Token transfer failed"); if (!custom(fund)) {cTokenMarketLiquidity = sub(cTokenMarketLiquidity, cTokenToRemove);} } else { funds[fund].balance = sub(funds[fund].balance, amount_); require(token.transfer(recipient_, amount_), "Funds.withdrawTo: Token transfer failed"); if (!custom(fund)) {tokenMarketLiquidity = sub(tokenMarketLiquidity, amount_);} } if (!custom(fund)) {calcGlobalInterest();} emit Withdraw(fund, amount_, recipient_); } function generate(bytes32[] calldata secretHashes_) external { for (uint i = 0; i < secretHashes_.length; i++) { secretHashes[msg.sender].push(secretHashes_[i]); } } function setPubKey(bytes calldata pubKey_) external { pubKeys[msg.sender] = pubKey_; } function enableCompound(bytes32 fund) external { require(compoundSet, "Funds.enableCompound: Cannot enable Compound as it has not been configured"); require(bools[fund].compoundEnabled == false, "Funds.enableCompound: Compound is already enabled"); require(msg.sender == lender(fund), "Funds.enableCompound: Only the lender can enable Compound"); uint256 cBalanceBefore = cToken.balanceOf(address(this)); mintCToken(address(token), address(cToken), funds[fund].balance); uint256 cBalanceAfter = cToken.balanceOf(address(this)); uint256 cTokenToReturn = sub(cBalanceAfter, cBalanceBefore); tokenMarketLiquidity = sub(tokenMarketLiquidity, funds[fund].balance); cTokenMarketLiquidity = add(cTokenMarketLiquidity, cTokenToReturn); bools[fund].compoundEnabled = true; funds[fund].balance = 0; funds[fund].cBalance = cTokenToReturn; emit EnableCompound(fund); } function disableCompound(bytes32 fund) external { require(bools[fund].compoundEnabled, "Funds.disableCompound: Compound is already disabled"); require(msg.sender == lender(fund), "Funds.disableCompound: Only the lender can disable Compound"); uint256 balanceBefore = token.balanceOf(address(this)); redeemCToken(address(cToken), funds[fund].cBalance); uint256 balanceAfter = token.balanceOf(address(this)); uint256 tokenToReturn = sub(balanceAfter, balanceBefore); tokenMarketLiquidity = add(tokenMarketLiquidity, tokenToReturn); cTokenMarketLiquidity = sub(cTokenMarketLiquidity, funds[fund].cBalance); bools[fund].compoundEnabled = false; funds[fund].cBalance = 0; funds[fund].balance = tokenToReturn; emit DisableCompound(fund); } function decreaseTotalBorrow(uint256 amount_) external { require(msg.sender == address(loans), "Funds.decreaseTotalBorrow: Only the Loans contract can perform this"); totalBorrow = sub(totalBorrow, amount_); } function calcGlobalInterest() public { marketLiquidity = add(tokenMarketLiquidity, wmul(cTokenMarketLiquidity, cTokenExchangeRate())); if (now > (add(lastGlobalInterestUpdated, interestUpdateDelay))) { uint256 utilizationRatio; if (totalBorrow != 0) {utilizationRatio = rdiv(totalBorrow, add(marketLiquidity, totalBorrow));} if (utilizationRatio > lastUtilizationRatio) { uint256 changeUtilizationRatio = sub(utilizationRatio, lastUtilizationRatio); globalInterestRateNumerator = min(maxInterestRateNumerator, add(globalInterestRateNumerator, rdiv(min(maxUtilizationDelta, changeUtilizationRatio), utilizationInterestDivisor))); } else { uint256 changeUtilizationRatio = sub(lastUtilizationRatio, utilizationRatio); globalInterestRateNumerator = max(minInterestRateNumerator, sub(globalInterestRateNumerator, rdiv(min(maxUtilizationDelta, changeUtilizationRatio), utilizationInterestDivisor))); } globalInterestRate = add(RAY, div(globalInterestRateNumerator, NUM_SECONDS_IN_YEAR)); lastGlobalInterestUpdated = now; lastUtilizationRatio = utilizationRatio; } } function calcInterest(uint256 amount_, uint256 rate_, uint256 loanDur_) public pure returns (uint256) { return sub(rmul(amount_, rpow(rate_, loanDur_)), amount_); } function ensureNotZero(uint256 value, bool addNow) public view returns (uint256) { if (value == 0) { if (addNow) { return now + MAX_LOAN_LENGTH; } return MAX_LOAN_LENGTH; } return value; } function createLoan( bytes32 fund, address borrower_, uint256 amount_, uint256 collateral_, uint256 loanDur_, uint256 requestTimestamp_ ) private returns (bytes32 loanIndex) { loanIndex = loans.create( now + loanDur_, [borrower_, lender(fund), funds[fund].arbiter], [ amount_, calcInterest(amount_, interest(fund), loanDur_), calcInterest(amount_, penalty(fund), loanDur_), calcInterest(amount_, fee(fund), loanDur_), collateral_, liquidationRatio(fund), requestTimestamp_ ], fund ); } function loanSetSecretHashes( bytes32 fund, bytes32 loan, bytes32[8] memory secretHashes_, bytes memory pubKeyA_, bytes memory pubKeyB_ ) private { loans.setSecretHashes( loan, [ secretHashes_[0], secretHashes_[1], secretHashes_[2], secretHashes_[3] ], [ secretHashes_[4], secretHashes_[5], secretHashes_[6], secretHashes_[7] ], getSecretHashesForLoan(arbiter(fund)), pubKeyA_, pubKeyB_, pubKeys[arbiter(fund)] ); } function loanUpdateMarketLiquidity(bytes32 fund, uint256 amount_) private { if (bools[fund].compoundEnabled) { uint256 cBalanceBefore = cToken.balanceOf(address(this)); redeemUnderlying(address(cToken), amount_); uint256 cBalanceAfter = cToken.balanceOf(address(this)); uint256 cTokenToRemove = sub(cBalanceBefore, cBalanceAfter); funds[fund].cBalance = sub(funds[fund].cBalance, cTokenToRemove); if (!custom(fund)) {cTokenMarketLiquidity = sub(cTokenMarketLiquidity, cTokenToRemove);} } else { funds[fund].balance = sub(funds[fund].balance, amount_); if (!custom(fund)) {tokenMarketLiquidity = sub(tokenMarketLiquidity, amount_);} } if (!custom(fund)) { totalBorrow = add(totalBorrow, amount_); calcGlobalInterest(); } } function getSecretHashesForLoan(address addr_) private returns (bytes32[4] memory) { secretHashIndex[addr_] = add(secretHashIndex[addr_], 4); require(secretHashesCount(addr_) >= secretHashIndex[addr_], "Funds.getSecretHashesForLoan: Not enough secrets generated"); return [ secretHashes[addr_][sub(secretHashIndex[addr_], 4)], secretHashes[addr_][sub(secretHashIndex[addr_], 3)], secretHashes[addr_][sub(secretHashIndex[addr_], 2)], secretHashes[addr_][sub(secretHashIndex[addr_], 1)] ]; } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"secretHashIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxUtilizationDelta","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"minLoanAmt","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"fund","type":"bytes32"},{"name":"amount_","type":"uint256"}],"name":"withdraw","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"defaultArbiterFee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cTokenMarketLiquidity","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DEFAULT_LIQUIDATION_RATIO","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"defaultArbiterFee_","type":"uint256"}],"name":"setDefaultArbiterFee","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"globalInterestRateNumerator","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"globalInterestRateNumerator_","type":"uint256"}],"name":"setGlobalInterestRateNumerator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"fund","type":"bytes32"},{"name":"amount_","type":"uint256"}],"name":"deposit","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"fundOwner","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"penalty","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"fee","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastGlobalInterestUpdated","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"decimals","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"calcGlobalInterest","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"MAX_UINT_256","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"maxLoanAmt","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"arbiter","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DEFAULT_MIN_LOAN_AMT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"fund","type":"bytes32"},{"name":"maxLoanDur_","type":"uint256"},{"name":"fundExpiry_","type":"uint256"},{"name":"arbiter_","type":"address"}],"name":"update","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"getComptrollerAddress","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"utilizationInterestDivisor","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"fund","type":"bytes32"},{"name":"minLoanAmt_","type":"uint256"},{"name":"maxLoanAmt_","type":"uint256"},{"name":"minLoanDur_","type":"uint256"},{"name":"maxLoanDur_","type":"uint256"},{"name":"fundExpiry_","type":"uint256"},{"name":"interest_","type":"uint256"},{"name":"penalty_","type":"uint256"},{"name":"fee_","type":"uint256"},{"name":"liquidationRatio_","type":"uint256"},{"name":"arbiter_","type":"address"}],"name":"updateCustom","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"interestUpdateDelay_","type":"uint256"}],"name":"setInterestUpdateDelay","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"},{"name":"","type":"uint256"}],"name":"secretHashes","outputs":[{"name":"","type":"bytes32"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"globalInterestRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"comptroller","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"marketLiquidity","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"MAX_LOAN_LENGTH","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"value","type":"uint256"},{"name":"addNow","type":"bool"}],"name":"ensureNotZero","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"minInterestRateNumerator","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"cToken","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"funds","outputs":[{"name":"lender","type":"address"},{"name":"minLoanAmt","type":"uint256"},{"name":"maxLoanAmt","type":"uint256"},{"name":"minLoanDur","type":"uint256"},{"name":"maxLoanDur","type":"uint256"},{"name":"fundExpiry","type":"uint256"},{"name":"interest","type":"uint256"},{"name":"penalty","type":"uint256"},{"name":"fee","type":"uint256"},{"name":"liquidationRatio","type":"uint256"},{"name":"arbiter","type":"address"},{"name":"balance","type":"uint256"},{"name":"cBalance","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"maxLoanDur_","type":"uint256"},{"name":"fundExpiry_","type":"uint256"},{"name":"arbiter_","type":"address"},{"name":"compoundEnabled_","type":"bool"},{"name":"amount_","type":"uint256"}],"name":"create","outputs":[{"name":"fund","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"","type":"bytes32"}],"name":"bools","outputs":[{"name":"custom","type":"bool"},{"name":"compoundEnabled","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"maxLoanDur","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"liquidationRatio","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"fund","type":"bytes32"}],"name":"disableCompound","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"totalBorrow","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"fund","type":"bytes32"}],"name":"balance","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"globalInterestRate_","type":"uint256"}],"name":"setGlobalInterestRate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"amount_","type":"uint256"},{"name":"rate_","type":"uint256"},{"name":"loanDur_","type":"uint256"}],"name":"calcInterest","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"loans_","type":"address"}],"name":"setLoans","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"lender","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"custom","outputs":[{"name":"","type":"bool"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"maxUtilizationDelta_","type":"uint256"}],"name":"setMaxUtilizationDelta","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"fundIndex","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"fund","type":"bytes32"}],"name":"enableCompound","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"minLoanDur","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DEFAULT_MIN_LOAN_DUR","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"fundExpiry","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"utilizationInterestDivisor_","type":"uint256"}],"name":"setUtilizationInterestDivisor","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"DEFAULT_LIQUIDATION_PENALTY","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"DEFAULT_MAX_LOAN_AMT","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"","type":"address"}],"name":"pubKeys","outputs":[{"name":"","type":"bytes"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[{"name":"addr_","type":"address"}],"name":"secretHashesCount","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"minInterestRateNumerator_","type":"uint256"}],"name":"setMinInterestRateNumerator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"secretHashes_","type":"bytes32[]"}],"name":"generate","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"cToken_","type":"address"},{"name":"comptroller_","type":"address"}],"name":"setCompound","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"NUM_SECONDS_IN_YEAR","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"interestUpdateDelay","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[{"name":"fund","type":"bytes32"},{"name":"amount_","type":"uint256"},{"name":"recipient_","type":"address"}],"name":"withdrawTo","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"pubKey_","type":"bytes"}],"name":"setPubKey","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"amount_","type":"uint256"}],"name":"decreaseTotalBorrow","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"fund","type":"bytes32"}],"name":"interest","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"maxInterestRateNumerator","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"lastUtilizationRatio","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":false,"inputs":[],"name":"cTokenExchangeRate","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"fund","type":"bytes32"},{"name":"borrower_","type":"address"},{"name":"amount_","type":"uint256"},{"name":"collateral_","type":"uint256"},{"name":"loanDur_","type":"uint256"},{"name":"requestTimestamp_","type":"uint256"},{"name":"secretHashes_","type":"bytes32[8]"},{"name":"pubKeyA_","type":"bytes"},{"name":"pubKeyB_","type":"bytes"}],"name":"request","outputs":[{"name":"loanIndex","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":false,"inputs":[{"name":"minLoanAmt_","type":"uint256"},{"name":"maxLoanAmt_","type":"uint256"},{"name":"minLoanDur_","type":"uint256"},{"name":"maxLoanDur_","type":"uint256"},{"name":"fundExpiry_","type":"uint256"},{"name":"liquidationRatio_","type":"uint256"},{"name":"interest_","type":"uint256"},{"name":"penalty_","type":"uint256"},{"name":"fee_","type":"uint256"},{"name":"arbiter_","type":"address"},{"name":"compoundEnabled_","type":"bool"},{"name":"amount_","type":"uint256"}],"name":"createCustom","outputs":[{"name":"fund","type":"bytes32"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"name":"x","type":"uint256"},{"name":"y","type":"uint256"}],"name":"cmul","outputs":[{"name":"z","type":"uint256"}],"payable":false,"stateMutability":"pure","type":"function"},{"constant":false,"inputs":[{"name":"maxInterestRateNumerator_","type":"uint256"}],"name":"setMaxInterestRateNumerator","outputs":[],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[],"name":"token","outputs":[{"name":"","type":"address"}],"payable":false,"stateMutability":"view","type":"function"},{"constant":true,"inputs":[],"name":"tokenMarketLiquidity","outputs":[{"name":"","type":"uint256"}],"payable":false,"stateMutability":"view","type":"function"},{"inputs":[{"name":"token_","type":"address"},{"name":"decimals_","type":"uint256"}],"payable":false,"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"name":"fund","type":"bytes32"}],"name":"Create","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"fund","type":"bytes32"},{"indexed":false,"name":"amount_","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"fund","type":"bytes32"},{"indexed":false,"name":"maxLoanDur_","type":"uint256"},{"indexed":false,"name":"fundExpiry_","type":"uint256"},{"indexed":false,"name":"arbiter_","type":"address"}],"name":"Update","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"fund","type":"bytes32"},{"indexed":false,"name":"borrower_","type":"address"},{"indexed":false,"name":"amount_","type":"uint256"},{"indexed":false,"name":"collateral_","type":"uint256"},{"indexed":false,"name":"loanDur_","type":"uint256"},{"indexed":false,"name":"requestTimestamp_","type":"uint256"}],"name":"Request","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"fund","type":"bytes32"},{"indexed":false,"name":"amount_","type":"uint256"},{"indexed":false,"name":"recipient_","type":"address"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"fund","type":"bytes32"}],"name":"EnableCompound","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"name":"fund","type":"bytes32"}],"name":"DisableCompound","type":"event"}]
Contract Creation Code
60806040523480156200001157600080fd5b506040516200590638038062005906833981810160405260408110156200003757600080fd5b5080516020909101516001600160a01b038216620000a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180620058a96031913960400191505060405180910390fd5b80620000f9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180620058da602c913960400191505060405180910390fd5b601a8054336001600160a01b031991821617909155601780549091166001600160a01b03841617905560188190556b22079eda249d327c677048096012556a4ed6b7353f71d0a0f402496011819055600e8190556a96d0176d4a7d47fc102c6f6013556a146cdd36157a9553e20f0a601455620151806015556b033b2e3ca31a444ebbf023c4601655620001b4906b033b2e3c9fd0803ce800000090620001a5906301e13380620001c0565b6001600160e01b03620001e116565b60105550620001f89050565b6000808211620001cf57600080fd5b818381620001d957fe5b049392505050565b80820182811015620001f257600080fd5b92915050565b6156a180620002086000396000f3fe608060405234801561001057600080fd5b50600436106104545760003560e01c806376a0b16611610241578063d39a2c0c1161013b578063e91d14a4116100c3578063f61d02d311610087578063f61d02d314610de2578063f7837eb714610e51578063fa3bfb1714610e74578063fc0c546a14610e91578063fdd5aab114610e9957610454565b8063e91d14a414610cb9578063eae1c2cf14610cd6578063f05541be14610cde578063f0a422d014610ce6578063f59bf27314610cee57610454565b8063da2c5c5b1161010a578063da2c5c5b14610bec578063db9b376c14610bf4578063e179e77114610bfc578063e32d291314610c2e578063e493325614610c9c57610454565b8063d39a2c0c14610b0d578063d4785d2914610b33578063d73b906214610b50578063d9d0a2d114610bbe57610454565b8063a2c70b6b116101c9578063ba617eef1161018d578063ba617eef14610a30578063bf12f43d14610a4d578063ccb99d5514610a6a578063ce26d44b146105d0578063d1b8b4bf14610a7257610454565b8063a2c70b6b146109c9578063a5a70965146109e6578063a5fa6706146109ee578063a634baf214610a0b578063b2d6107114610a2857610454565b80638c5d5268116102105780638c5d52681461090f578063994871fa1461092c5780639d06bcea146109555780639fc3f02f1461097b578063a18e4a801461099857610454565b806376a0b166146108b05780637e25a221146108cd5780638285ef40146108ea57806389eba421146108f257610454565b806344b6ba95116103525780635fe3b567116102da57806369e527da1161029e57806369e527da1461077a5780636a29a620146107825780636a7bb32c1461081b5780636e1719a61461085b578063712d8e6a1461089357610454565b80635fe3b56714610735578063612ef80b1461073d5780636158153d14610745578063668064da1461074d578063689c76ef1461077257610454565b80634f9bc9d5116103215780634f9bc9d514610676578063513916741461067e578063516dbe24146106e457806354e39f90146107015780635b873ffa1461072d57610454565b806344b6ba95146105f557806347ca77161461062e5780634c9fb84a146106365780634ee9159a1461066e57610454565b80631beec294116103e05780632eb1ad73116103a45780632eb1ad73146105b8578063313ce567146105c057806333549b1b146105c85780633d41a26b146105d057806342febf0c146105d857610454565b80631beec294146105185780631de26e161461053557806321fd933b1461055857806326fc75901461057e57806327cdab061461059b57610454565b806304e9ef031161042757806304e9ef03146104db57806316df840a146104e35780631723cfa5146104eb5780631873fe50146104f35780631bb736971461051057610454565b806301937d0414610459578063031558e51461049157806303b69d1814610499578063040cf020146104b6575b600080fd5b61047f6004803603602081101561046f57600080fd5b50356001600160a01b0316610ea1565b60408051918252519081900360200190f35b61047f610eb3565b61047f600480360360208110156104af57600080fd5b5035610eb9565b6104d9600480360360408110156104cc57600080fd5b5080359060200135610f12565b005b61047f610f21565b61047f610f27565b61047f610f2d565b6104d96004803603602081101561050957600080fd5b5035610f3d565b61047f610fd6565b6104d96004803603602081101561052e57600080fd5b5035610fdc565b6104d96004803603604081101561054b57600080fd5b5080359060200135611066565b61047f6004803603602081101561056e57600080fd5b50356001600160a01b03166112eb565b61047f6004803603602081101561059457600080fd5b50356112fd565b61047f600480360360208110156105b157600080fd5b503561133f565b61047f611377565b61047f61137d565b6104d9611383565b61047f611495565b61047f600480360360208110156105ee57600080fd5b503561149b565b6106126004803603602081101561060b57600080fd5b50356114d3565b604080516001600160a01b039092168252519081900360200190f35b61047f6114f1565b6104d96004803603608081101561064c57600080fd5b50803590602081013590604081013590606001356001600160a01b03166114fe565b610612611648565b61047f611658565b6104d9600480360361016081101561069557600080fd5b5080359060208101359060408101359060608101359060808101359060a08101359060c08101359060e081013590610100810135906101208101359061014001356001600160a01b031661165e565b6104d9600480360360208110156106fa57600080fd5b503561177e565b61047f6004803603604081101561071757600080fd5b506001600160a01b038135169060200135611808565b61047f611836565b61061261183c565b61047f61184b565b61047f611851565b61047f6004803603604081101561076357600080fd5b50803590602001351515611859565b61047f611887565b61061261188d565b61079f6004803603602081101561079857600080fd5b503561189c565b604080516001600160a01b039e8f168152602081019d909d528c81019b909b5260608c019990995260808b019790975260a08a019590955260c089019390935260e08801919091526101008701526101208601529094166101408401526101608301939093526101808201929092529051908190036101a00190f35b61047f600480360360a081101561083157600080fd5b508035906020810135906001600160a01b0360408201351690606081013515159060800135611910565b6108786004803603602081101561087157600080fd5b5035611b30565b60408051921515835290151560208301528051918290030190f35b61047f600480360360208110156108a957600080fd5b5035611b4e565b61047f600480360360208110156108c657600080fd5b5035611b63565b6104d9600480360360208110156108e357600080fd5b5035611ba5565b61047f611e15565b61047f6004803603602081101561090857600080fd5b5035611e1b565b6104d96004803603602081101561092557600080fd5b5035611edc565b61047f6004803603606081101561094257600080fd5b5080359060208101359060400135611f66565b6104d96004803603602081101561096b57600080fd5b50356001600160a01b0316611f8c565b6106126004803603602081101561099157600080fd5b5035612138565b6109b5600480360360208110156109ae57600080fd5b5035612153565b604080519115158252519081900360200190f35b6104d9600480360360208110156109df57600080fd5b5035612168565b61047f6121f2565b6104d960048036036020811015610a0457600080fd5b50356121f8565b61047f60048036036020811015610a2157600080fd5b50356124bd565b61047f6124f5565b61047f60048036036020811015610a4657600080fd5b50356124fb565b6104d960048036036020811015610a6357600080fd5b5035612511565b61047f61259b565b610a9860048036036020811015610a8857600080fd5b50356001600160a01b03166125ab565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610ad2578181015183820152602001610aba565b50505050905090810190601f168015610aff5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61047f60048036036020811015610b2357600080fd5b50356001600160a01b0316612646565b6104d960048036036020811015610b4957600080fd5b5035612661565b6104d960048036036020811015610b6657600080fd5b810190602081018135600160201b811115610b8057600080fd5b820183602082011115610b9257600080fd5b803590602001918460208302840111600160201b83111715610bb357600080fd5b5090925090506126eb565b6104d960048036036040811015610bd457600080fd5b506001600160a01b0381358116916020013516612740565b61047f61289a565b61047f6128a2565b6104d960048036036060811015610c1257600080fd5b50803590602081013590604001356001600160a01b03166128a8565b6104d960048036036020811015610c4457600080fd5b810190602081018135600160201b811115610c5e57600080fd5b820183602082011115610c7057600080fd5b803590602001918460018302840111600160201b83111715610c9157600080fd5b509092509050612cf5565b6104d960048036036020811015610cb257600080fd5b5035612d0f565b61047f60048036036020811015610ccf57600080fd5b5035612d6a565b61047f612da2565b61047f612da8565b61047f612dae565b61047f6004803603610200811015610d0557600080fd5b8135916001600160a01b036020820135169160408201359160608101359160808201359160a08101359160c0820191908101906101e081016101c0820135600160201b811115610d5457600080fd5b820183602082011115610d6657600080fd5b803590602001918460018302840111600160201b83111715610d8757600080fd5b919390929091602081019035600160201b811115610da457600080fd5b820183602082011115610db657600080fd5b803590602001918460018302840111600160201b83111715610dd757600080fd5b509092509050612e4e565b61047f6004803603610180811015610df957600080fd5b5080359060208101359060408101359060608101359060808101359060a08101359060c08101359060e081013590610100810135906001600160a01b0361012082013516906101408101351515906101600135613336565b61047f60048036036040811015610e6757600080fd5b508035906020013561367a565b6104d960048036036020811015610e8a57600080fd5b50356136ab565b610612613735565b61047f613744565b60036020526000908152604090205481565b60115481565b60008181526007602052604081205460ff1615610ee85750600081815260056020526040902060010154610f0d565b610f0a68015af1d78b58c40000610f02601260185461374a565b600a0a61375a565b90505b919050565b610f1d8282336128a8565b5050565b60165481565b600b5481565b6b04860d8812f0b3887800000081565b601a546001600160a01b03163314610f865760405162461bcd60e51b815260040180806020018281038252603e815260200180614fb3603e913960400191505060405180910390fd5b6b033b2e3ca43176a9d2dfd0a5811115610fd15760405162461bcd60e51b81526004018080602001828103825260458152602001806154b06045913960600191505060405180910390fd5b601655565b600e5481565b601a546001600160a01b031633146110255760405162461bcd60e51b8152600401808060200182810382526048815260200180614b506048913960600191505060405180910390fd5b806110615760405162461bcd60e51b81526004018080602001828103825260498152602001806150316049913960600191505060405180910390fd5b600e55565b601754604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b1580156110c057600080fd5b505af11580156110d4573d6000803e3d6000fd5b505050506040513d60208110156110ea57600080fd5b50516111275760405162461bcd60e51b81526004018080602001828103825260288152602001806150ee6028913960400191505060405180910390fd5b600082815260076020526040902054610100900460ff161561124c57601754601954611160916001600160a01b03908116911683613771565b60006111f861117783670de0b6b3a764000061388b565b601960009054906101000a90046001600160a01b03166001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156111c757600080fd5b505af11580156111db573d6000803e3d6000fd5b505050506040513d60208110156111f157600080fd5b505161375a565b6000848152600560205260409020600c015490915061121790826138af565b6000848152600560205260409020600c015561123283612153565b61124657611242600b54826138af565b600b555b50611297565b6000828152600560205260409020600b015461126890826138af565b6000838152600560205260409020600b015561128382612153565b61129757611293600a54826138af565b600a555b6112a082612153565b6112ac576112ac611383565b604080518381526020810183905281517f98e783c3864bbf744a057ef605a2a61701c3b62b5ed68b3745b99094497daf1f929181900390910190a15050565b60066020526000908152604090205481565b60008181526007602052604081205460ff161561132c5750600081815260056020526040902060070154610f0d565b506b033b2e3cacd278c7503e82c1610f0d565b60008181526007602052604081205460ff161561136e5750600081815260056020526040902060080154610f0d565b50601654610f0d565b60095481565b60185481565b6113a1600a5461139c600b54611397612dae565b6138bf565b6138af565b600c556009546015546113b491906138af565b421115611493576000600d546000146113e3576113e0600d546113db600c54600d546138af565b6138e7565b90505b600f5481111561142e5760006113fb82600f5461374a565b9050611425601354611420600e5461139c6114186011548761390b565b6012546138e7565b61390b565b600e5550611468565b600061143c600f548361374a565b905061146360145461145e600e546114596114186011548761390b565b61374a565b61391e565b600e55505b6114886b033b2e3c9fd0803ce800000061139c600e546301e1338061375a565b60105542600955600f555b565b60001981565b60008181526007602052604081205460ff16156114ca5750600081815260056020526040902060020154610f0d565b50600019610f0d565b6000908152600560205260409020600a01546001600160a01b031690565b68015af1d78b58c4000081565b61150784612138565b6001600160a01b0316336001600160a01b0316146115565760405162461bcd60e51b8152600401808060200182810382526031815260200180614e246031913960400191505060405180910390fd5b6312cc0300611566846000611859565b111580156115845750426312cc030001611581836001611859565b11155b6115bf5760405162461bcd60e51b815260040180806020018281038252603e815260200180614bd4603e913960400191505060405180910390fd5b60008481526005602081815260409283902060048101879055918201859055600a90910180546001600160a01b0385166001600160a01b031990911681179091558251878152918201869052818301859052606082015290517fbc2980147202467df8874a7f933ee11c59b6b1f6273647aca58bd18d349e67ac9181900360800190a150505050565b6000546001600160a01b03165b90565b60125481565b60008b81526007602052604090205460ff166116ab5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154f5602e913960400191505060405180910390fd5b898910156116ea5760405162461bcd60e51b815260040180806020018281038252604a815260200180614c52604a913960600191505060405180910390fd5b876116f6886000611859565b10156117335760405162461bcd60e51b815260040180806020018281038252604a81526020018061534c604a913960600191505060405180910390fd5b61173f8b8888846114fe565b506000998a5260056020526040909920600181019890985560028801969096556003870194909455600686015550506007830155600882015560090155565b601a546001600160a01b031633146117c75760405162461bcd60e51b8152600401808060200182810382526040815260200180614ff16040913960400191505060405180910390fd5b806118035760405162461bcd60e51b8152600401808060200182810382526039815260200180614b176039913960400191505060405180910390fd5b601555565b6002602052816000526040600020818154811061182157fe5b90600052602060002001600091509150505481565b60105481565b6000546001600160a01b031681565b600c5481565b6312cc030081565b60008261187e5781156118735750426312cc030001611881565b506312cc0300611881565b50815b92915050565b60145481565b6019546001600160a01b031681565b600560208190526000918252604090912080546001820154600283015460038401546004850154958501546006860154600787015460088801546009890154600a8a0154600b8b0154600c909b01546001600160a01b039a8b169c999b989a9799989697959694959394929390911691908d565b336000818152600660209081526040808320548352600590915281205490916001600160a01b0390911614156119775760405162461bcd60e51b8152600401808060200182810382526034815260200180614e8e6034913960400191505060405180910390fd5b6312cc0300611987876000611859565b1080156119a35750426312cc0300016119a1866001611859565b105b6119de5760405162461bcd60e51b815260040180806020018281038252603e815260200180614d91603e913960400191505060405180910390fd5b601954600160a01b900460ff16611a2c578215611a2c5760405162461bcd60e51b81526004018080602001828103825260428152602001806151cc6042913960600191505060405180910390fd5b611a3960085460016138af565b6008819055600081815260056020526040812080546001600160a01b03191633179055909150611a6a908790611859565b600082815260056020526040902060040155611a87856001611859565b600082815260056020818152604080842092830194909455600a90910180546001600160a01b0319166001600160a01b03891617905560078152828220805461ffff1916610100881515021790556008543383526006909152919020558115611af457611af48183611066565b6040805182815290517fa7857d7da6974b0157f3bf7dd25a745bd7d81d845bb525ee0b316a87541a5c319181900360200190a195945050505050565b60076020526000908152604090205460ff8082169161010090041682565b60009081526005602052604090206004015490565b60008181526007602052604081205460ff1615611b925750600081815260056020526040902060090154610f0d565b506b04860d8812f0b38878000000610f0d565b600081815260076020526040902054610100900460ff16611bf75760405162461bcd60e51b81526004018080602001828103825260338152602001806149ce6033913960400191505060405180910390fd5b611c0081612138565b6001600160a01b0316336001600160a01b031614611c4f5760405162461bcd60e51b815260040180806020018281038252603b815260200180614d56603b913960400191505060405180910390fd5b601754604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611c9a57600080fd5b505afa158015611cae573d6000803e3d6000fd5b505050506040513d6020811015611cc457600080fd5b50516019546000848152600560205260409020600c0154919250611cf3916001600160a01b039091169061392e565b601754604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611d3e57600080fd5b505afa158015611d52573d6000803e3d6000fd5b505050506040513d6020811015611d6857600080fd5b505190506000611d78828461374a565b9050611d86600a54826138af565b600a55600b546000858152600560205260409020600c0154611da8919061374a565b600b9081556000858152600760209081526040808320805461ff001916905560058252808320600c81019390935591909201839055805186815290517ffb6e0a1c4958f3e250db013b5035dc019d1e6426df7b4a40a5d0229a336aad53929181900390910190a150505050565b600d5481565b600081815260076020526040812054610100900460ff1615611ec4576000828152600560209081526040808320600c0154601954825163bd6d894d60e01b81529251610f0a9592946001600160a01b039092169363bd6d894d9360048083019493928390030190829087803b158015611e9357600080fd5b505af1158015611ea7573d6000803e3d6000fd5b505050506040513d6020811015611ebd57600080fd5b50516138bf565b506000818152600560205260409020600b0154610f0d565b601a546001600160a01b03163314611f255760405162461bcd60e51b815260040180806020018281038252603f81526020018061520e603f913960400191505060405180910390fd5b80611f615760405162461bcd60e51b81526004018080602001828103825260378152602001806152976037913960400191505060405180910390fd5b601055565b6000611f84611f7e85611f798686613a7e565b613ad8565b8561374a565b949350505050565b601a546001600160a01b03163314611fd55760405162461bcd60e51b8152600401808060200182810382526032815260200180614df26032913960400191505060405180910390fd5b6001546001600160a01b03161561201d5760405162461bcd60e51b8152600401808060200182810382526032815260200180614c9c6032913960400191505060405180910390fd5b6001600160a01b0381166120625760405162461bcd60e51b815260040180806020018281038252602e815260200180615449602e913960400191505060405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556017546040805163095ea7b360e01b8152600481019390935260001960248401525192169163095ea7b3916044808201926020929091908290030181600087803b1580156120ce57600080fd5b505af11580156120e2573d6000803e3d6000fd5b505050506040513d60208110156120f857600080fd5b50516121355760405162461bcd60e51b815260040180806020018281038252602981526020018061496e6029913960400191505060405180910390fd5b50565b6000908152600560205260409020546001600160a01b031690565b60009081526007602052604090205460ff1690565b601a546001600160a01b031633146121b15760405162461bcd60e51b81526004018080602001828103825260408152602001806155496040913960400191505060405180910390fd5b806121ed5760405162461bcd60e51b8152600401808060200182810382526039815260200180614e556039913960400191505060405180910390fd5b601155565b60085481565b601954600160a01b900460ff166122405760405162461bcd60e51b815260040180806020018281038252604a81526020018061524d604a913960600191505060405180910390fd5b600081815260076020526040902054610100900460ff16156122935760405162461bcd60e51b815260040180806020018281038252603181526020018061493d6031913960400191505060405180910390fd5b61229c81612138565b6001600160a01b0316336001600160a01b0316146122eb5760405162461bcd60e51b81526004018080602001828103825260398152602001806154776039913960400191505060405180910390fd5b601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561233657600080fd5b505afa15801561234a573d6000803e3d6000fd5b505050506040513d602081101561236057600080fd5b50516017546019546000858152600560205260409020600b0154929350612396926001600160a01b039283169290911690613771565b601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156123e157600080fd5b505afa1580156123f5573d6000803e3d6000fd5b505050506040513d602081101561240b57600080fd5b50519050600061241b828461374a565b600a546000868152600560205260409020600b015491925061243c9161374a565b600a55600b5461244c90826138af565b600b9081556000858152600760209081526040808320805461ff0019166101001790556005825280832093840192909255600c909201839055805186815290517f43c40c3c72eec13a64775a3231f52699c8ba28e57131e7343e4f57734d8a3ce4929181900390910190a150505050565b60008181526007602052604081205460ff16156124ec5750600081815260056020526040902060030154610f0d565b50615460610f0d565b61546081565b6000908152600560208190526040909120015490565b601a546001600160a01b0316331461255a5760405162461bcd60e51b8152600401808060200182810382526047815260200180614a016047913960600191505060405180910390fd5b806125965760405162461bcd60e51b81526004018080602001828103825260478152602001806148f66047913960600191505060405180910390fd5b601255565b6b033b2e3cacd278c7503e82c181565b60046020908152600091825260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909183018282801561263e5780601f106126135761010080835404028352916020019161263e565b820191906000526020600020905b81548152906001019060200180831161262157829003601f168201915b505050505081565b6001600160a01b031660009081526002602052604090205490565b601a546001600160a01b031633146126aa5760405162461bcd60e51b8152600401808060200182810382526045815260200180614cce6045913960600191505060405180910390fd5b806126e65760405162461bcd60e51b8152600401808060200182810382526043815260200180614a486043913960600191505060405180910390fd5b601455565b60005b8181101561273b5733600090815260026020526040902083838381811061271157fe5b835460018082018655600095865260209586902092909502939093013592019190915550016126ee565b505050565b601a546001600160a01b031633146127895760405162461bcd60e51b8152600401808060200182810382526040815260200180614c126040913960400191505060405180910390fd5b601954600160a01b900460ff16156127d25760405162461bcd60e51b8152600401808060200182810382526038815260200180614f016038913960400191505060405180910390fd5b6001600160a01b0382166128175760405162461bcd60e51b81526004018080602001828103825260328152602001806155896032913960400191505060405180910390fd5b6001600160a01b03811661285c5760405162461bcd60e51b81526004018080602001828103825260378152602001806149976037913960400191505060405180910390fd5b60198054600080546001600160a01b039485166001600160a01b03199182161790915560ff60a01b199390941693169290921716600160a01b179055565b6301e1338081565b60155481565b6128b183612138565b6001600160a01b0316336001600160a01b0316146129005760405162461bcd60e51b81526004018080602001828103825260358152602001806153d16035913960400191505060405180910390fd5b8161290a84611e1b565b10156129475760405162461bcd60e51b81526004018080602001828103825260268152602001806155236026913960400191505060405180910390fd5b600083815260076020526040902054610100900460ff1615612b8b57601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156129ae57600080fd5b505afa1580156129c2573d6000803e3d6000fd5b505050506040513d60208110156129d857600080fd5b50516019549091506129f3906001600160a01b031684613b08565b601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015612a3e57600080fd5b505afa158015612a52573d6000803e3d6000fd5b505050506040513d6020811015612a6857600080fd5b505190506000612a78838361374a565b6000878152600560205260409020600c0154909150612a97908261374a565b6000878152600560209081526040808320600c0193909355601754835163a9059cbb60e01b81526001600160a01b038981166004830152602482018b90529451949091169363a9059cbb93604480840194938390030190829087803b158015612aff57600080fd5b505af1158015612b13573d6000803e3d6000fd5b505050506040513d6020811015612b2957600080fd5b5051612b665760405162461bcd60e51b81526004018080602001828103825260278152602001806151166027913960400191505060405180910390fd5b612b6f86612153565b612b8357612b7f600b548261374a565b600b555b505050612c93565b6000838152600560205260409020600b0154612ba7908361374a565b6000848152600560209081526040808320600b0193909355601754835163a9059cbb60e01b81526001600160a01b038681166004830152602482018890529451949091169363a9059cbb93604480840194938390030190829087803b158015612c0f57600080fd5b505af1158015612c23573d6000803e3d6000fd5b505050506040513d6020811015612c3957600080fd5b5051612c765760405162461bcd60e51b81526004018080602001828103825260278152602001806151166027913960400191505060405180910390fd5b612c7f83612153565b612c9357612c8f600a548361374a565b600a555b612c9c83612153565b612ca857612ca8611383565b60408051848152602081018490526001600160a01b0383168183015290517f181177e6e9bbf7d7a45604cf4fdb0444641e20905d8d4daf2a7863036e56dc159181900360600190a1505050565b33600090815260046020526040902061273b90838361483f565b6001546001600160a01b03163314612d585760405162461bcd60e51b8152600401808060200182810382526043815260200180614d136043913960600191505060405180910390fd5b612d64600d548261374a565b600d5550565b60008181526007602052604081205460ff1615612d995750600081815260056020526040902060060154610f0d565b50601054610f0d565b60135481565b600f5481565b601954600090600160a01b900460ff1615612e4657601960009054906101000a90046001600160a01b03166001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015612e1357600080fd5b505af1158015612e27573d6000803e3d6000fd5b505050506040513d6020811015612e3d57600080fd5b50519050611655565b506000611655565b6000612e598c612138565b6001600160a01b0316336001600160a01b031614612ea85760405162461bcd60e51b81526004018080602001828103825260398152602001806150b56039913960400191505060405180910390fd5b612eb18c611e1b565b8a1115612eef5760405162461bcd60e51b8152600401808060200182810382526023815260200180614dcf6023913960400191505060405180910390fd5b612ef88c610eb9565b8a1015612f365760405162461bcd60e51b815260040180806020018281038252603f815260200180614ec2603f913960400191505060405180910390fd5b612f3f8c61149b565b8a1115612f7d5760405162461bcd60e51b815260040180806020018281038252603c815260200180614b98603c913960400191505060405180910390fd5b612f868c6124bd565b881015612fc45760405162461bcd60e51b815260040180806020018281038252603c815260200180615631603c913960400191505060405180910390fd5b612fd6612fd08d6124fb565b4261374a565b8811158015612fed5750612fe98c611b4e565b8811155b6130285760405162461bcd60e51b8152600401808060200182810382526044815260200180614a8b6044913960600191505060405180910390fd5b6001600160a01b038b1661306d5760405162461bcd60e51b8152600401808060200182810382526030815260200180614f396030913960400191505060405180910390fd5b8535158015906130805750602086013515155b6130bb5760405162461bcd60e51b815260040180806020018281038252603b8152602001806155bb603b913960400191505060405180910390fd5b6040860135158015906130d15750606086013515155b61310c5760405162461bcd60e51b815260040180806020018281038252603b8152602001806155f6603b913960400191505060405180910390fd5b608086013515801590613122575060a086013515155b61315d5760405162461bcd60e51b815260040180806020018281038252603b815260200180615396603b913960400191505060405180910390fd5b60c086013515801590613173575060e086013515155b6131ae5760405162461bcd60e51b815260040180806020018281038252603b81526020018061507a603b913960400191505060405180910390fd5b6131bc8c8c8c8c8c8c613cbb565b905061325a8c8288600880602002604051908101604052809291908260086020028082843760009201919091525050604080516020601f8c018190048102820181019092528a815291508a908a908190840183828082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a9150899081908401838280828437600092019190915250613e5092505050565b6132648c8b61412f565b6001546040805163bf14c11960e01b81526004810184905290516001600160a01b039092169163bf14c1199160248082019260009290919082900301818387803b1580156132b157600080fd5b505af11580156132c5573d6000803e3d6000fd5b5050604080518f81526001600160a01b038f1660208201528082018e9052606081018d9052608081018c905260a081018b905290517ff494fa7145682762e6918aefe85748818b2f1092c6f8c0a3284bcb18506416d593509081900360c0019150a19b9a5050505050505050505050565b336000818152600660209081526040808320548352600590915281205490916001600160a01b03909116141561339d5760405162461bcd60e51b8152600401808060200182810382526034815260200180614e8e6034913960400191505060405180910390fd5b6312cc03006133ad8b6000611859565b1080156133c95750426312cc0300016133c78a6001611859565b105b6134045760405162461bcd60e51b81526004018080602001828103825260448152602001806152ce6044913960600191505060405180910390fd5b8c8c10156134435760405162461bcd60e51b815260040180806020018281038252604a815260200180615182604a913960600191505060405180910390fd5b8a61344f8b6000611859565b101561348c5760405162461bcd60e51b815260040180806020018281038252604a815260200180614f69604a913960600191505060405180910390fd5b601954600160a01b900460ff166134da5782156134da5760405162461bcd60e51b8152600401808060200182810382526048815260200180614acf6048913960600191505060405180910390fd5b6134e760085460016138af565b60088190555060085460001b9050336005600083815260200190815260200160002060000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508c60056000838152602001908152602001600020600101819055508b60056000838152602001908152602001600020600201819055508a600560008381526020019081526020016000206003018190555061358c8a6000611859565b6000828152600560205260409020600401556135a9896001611859565b60008281526005602081815260408084209283019490945560068083018c905560078084018c905560088085018c9055600985018f9055600a90940180546001600160a01b0319166001600160a01b038c161790558252848420805460ff191660011761ff0019166101008a1515021790559154338452919052919020558115613637576136378183611066565b6040805182815290517fa7857d7da6974b0157f3bf7dd25a745bd7d81d845bb525ee0b316a87541a5c319181900360200190a19c9b505050505050505050505050565b60006305f5e10061369c61368e858561388b565b60026305f5e1005b046138af565b816136a357fe5b049392505050565b601a546001600160a01b031633146136f45760405162461bcd60e51b815260040180806020018281038252604581526020018061513d6045913960600191505060405180910390fd5b806137305760405162461bcd60e51b81526004018080602001828103825260438152602001806154066043913960600191505060405180910390fd5b601355565b6017546001600160a01b031681565b600a5481565b8082038281111561188157600080fd5b600080821161376857600080fd5b8183816136a357fe5b61377a82614325565b604080516370a0823160e01b8152306004820152905184916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b1580156137c557600080fd5b505afa1580156137d9573d6000803e3d6000fd5b505050506040513d60208110156137ef57600080fd5b50519050828111156137fe5750815b8361380a8683836145a8565b806001600160a01b031663a0712d68836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561385057600080fd5b505af1158015613864573d6000803e3d6000fd5b505050506040513d602081101561387a57600080fd5b50511561388357fe5b505050505050565b60008115806138a6575050808202828282816138a357fe5b04145b61188157600080fd5b8082018281101561188157600080fd5b6000670de0b6b3a764000061369c6138d7858561388b565b6002670de0b6b3a7640000613696565b60008161369c613903856b033b2e3c9fd0803ce800000061388b565b600285613696565b60008183111561187e57815b9392505050565b60008183101561187e5781613917565b604080516370a0823160e01b8152306004820152905183916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561397957600080fd5b505afa15801561398d573d6000803e3d6000fd5b505050506040513d60208110156139a357600080fd5b50519050828111156139b25750815b6139bd8482866145a8565b816001600160a01b031663db006a75826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015613a0357600080fd5b505af1158015613a17573d6000803e3d6000fd5b505050506040513d6020811015613a2d57600080fd5b505115613a78576040805162461bcd60e51b8152602060048201526014602482015273736f6d657468696e672077656e742077726f6e6760601b604482015290519081900360640190fd5b50505050565b600060028206613a9a576b033b2e3c9fd0803ce8000000613a9c565b825b90506002820491505b811561188157613ab58384613ad8565b92506002820615613acd57613aca8184613ad8565b90505b600282049150613aa5565b60006b033b2e3c9fd0803ce800000061369c613af4858561388b565b60026b033b2e3c9fd0803ce8000000613696565b81613b298174446c3b15f9926687d2c40534fdb564000000000000816145a8565b604080516370a0823160e01b815230600482015290516000916001600160a01b038416916370a0823191602480820192602092909190829003018186803b158015613b7357600080fd5b505afa158015613b87573d6000803e3d6000fd5b505050506040513d6020811015613b9d57600080fd5b50516040805163bd6d894d60e01b81529051919250600091613bec9184916001600160a01b0387169163bd6d894d91600480830192602092919082900301818987803b158015611e9357600080fd5b905083811115613bf95750825b826001600160a01b031663852a12e3826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015613c3f57600080fd5b505af1158015613c53573d6000803e3d6000fd5b505050506040513d6020811015613c6957600080fd5b505115613cb4576040805162461bcd60e51b8152602060048201526014602482015273736f6d657468696e672077656e742077726f6e6760601b604482015290519081900360640190fd5b5050505050565b60015460408051606081019091526001600160a01b03878116825260009216906310375921904286019060208101613cf28c612138565b6001600160a01b03908116825260008d815260056020908152604091829020600a015490921692820192909252815160e081019092528a82528101613d408b613d3a8f612d6a565b8b611f66565b8152602001613d528b613d3a8f6112fd565b8152602001613d648b613d3a8f61133f565b8152602001898152602001613d788d611b63565b81526020018790526040516001600160e01b031960e086901b168152600481018481528d9160240184606080838360005b83811015613dc1578181015183820152602001613da9565b5050505090500183600760200280838360005b83811015613dec578181015183820152602001613dd4565b50505050905001828152602001945050505050602060405180830381600087803b158015613e1957600080fd5b505af1158015613e2d573d6000803e3d6000fd5b505050506040513d6020811015613e4357600080fd5b5051979650505050505050565b600154604080516080808201835286518252602080880151818401528784015183850152606080890151908401528351808301855291880151825260a0880151908201526001600160a01b039093169263ee79b12b928892919081018860066020020151815260200188600760088110613ec657fe5b60200201519052613ede613ed98b6114d3565b614688565b878760046000613eed8f6114d3565b6001600160a01b03166001600160a01b031681526020019081526020016000206040518863ffffffff1660e01b81526004018088815260200187600460200280838360005b83811015613f4a578181015183820152602001613f32565b5050505090500186600460200280838360005b83811015613f75578181015183820152602001613f5d565b5050505090500185600460200280838360005b83811015613fa0578181015183820152602001613f88565b50505050905001806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015613fe8578181015183820152602001613fd0565b50505050905090810190601f1680156140155780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b83811015614048578181015183820152602001614030565b50505050905090810190601f1680156140755780820380516001836020036101000a031916815260200191505b508481038252855460026000196101006001841615020190911604808252602090910190869080156140e85780601f106140bd576101008083540402835291602001916140e8565b820191906000526020600020905b8154815290600101906020018083116140cb57829003601f168201915b50509a5050505050505050505050600060405180830381600087803b15801561411057600080fd5b505af1158015614124573d6000803e3d6000fd5b505050505050505050565b600082815260076020526040902054610100900460ff16156142b657601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561419657600080fd5b505afa1580156141aa573d6000803e3d6000fd5b505050506040513d60208110156141c057600080fd5b50516019549091506141db906001600160a01b031683613b08565b601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561422657600080fd5b505afa15801561423a573d6000803e3d6000fd5b505050506040513d602081101561425057600080fd5b505190506000614260838361374a565b6000868152600560205260409020600c015490915061427f908261374a565b6000868152600560205260409020600c015561429a85612153565b6142ae576142aa600b548261374a565b600b555b505050614301565b6000828152600560205260409020600b01546142d2908261374a565b6000838152600560205260409020600b01556142ed82612153565b614301576142fd600a548261374a565b600a555b61430a82612153565b610f1d5761431a600d54826138af565b600d55610f1d611383565b600061432f611648565b60408051632aff3bff60e21b815230600482015290519192506060916001600160a01b0384169163abfceffc916024808301926000929190829003018186803b15801561437b57600080fd5b505afa15801561438f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156143b857600080fd5b810190808051600160201b8111156143cf57600080fd5b820160208101848111156143e257600080fd5b81518560208202830111600160201b821117156143fe57600080fd5b509094506000935083925050505b825181101561444f57846001600160a01b031683828151811061442b57fe5b60200260200101516001600160a01b0316141561444757600191505b60010161440c565b5080613a785760408051600180825281830190925260609160208083019080388339019050509050848160008151811061448557fe5b6001600160a01b03928316602091820292909201810191909152604051631853304760e31b8152600481018281528451602483015284519388169363c29982389386938392604490910191858101910280838360005b838110156144f35781810151838201526020016144db565b5050505090500192505050600060405180830381600087803b15801561451857600080fd5b505af115801561452c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561455557600080fd5b810190808051600160201b81111561456c57600080fd5b8201602081018481111561457f57600080fd5b81518560208202830111600160201b8211171561459b57600080fd5b5050505050505050505050565b60408051636eb1769f60e11b81523060048201526001600160a01b038381166024830152915185926000929084169163dd62ed3e91604480820192602092909190829003018186803b1580156145fd57600080fd5b505afa158015614611573d6000803e3d6000fd5b505050506040513d602081101561462757600080fd5b5051905080841115613cb4576040805163095ea7b360e01b81526001600160a01b038581166004830152600160ff1b602483015291519184169163095ea7b39160448082019260009290919082900301818387803b15801561411057600080fd5b6146906148bd565b6001600160a01b0382166000908152600360205260409020546146b49060046138af565b6001600160a01b03831660009081526003602052604090208190556146d883612646565b10156147155760405162461bcd60e51b815260040180806020018281038252603a815260200180615312603a913960400191505060405180910390fd5b604080516080810182526001600160a01b0384166000908152600260209081528382206003909152929020549091829161475090600461374a565b8154811061475a57fe5b600091825260208083209091015483526001600160a01b03861682526002815260408083206003808452919093205493909101926147979161374a565b815481106147a157fe5b600091825260208083209091015483526001600160a01b0386168252600280825260408084206003845293205493909101926147dc9161374a565b815481106147e657fe5b600091825260208083209091015483526001600160a01b03861682526002815260408083206003835292205492019161482090600161374a565b8154811061482a57fe5b90600052602060002001548152509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106148805782800160ff198235161785556148ad565b828001600101855582156148ad579182015b828111156148ad578235825591602001919060010190614892565b506148b99291506148db565b5090565b60405180608001604052806004906020820280388339509192915050565b61165591905b808211156148b957600081556001016148e156fe46756e64732e7365745574696c697a6174696f6e496e74657265737444697669736f723a207574696c697a6174696f6e496e74657265737444697669736f72206973207a65726f46756e64732e656e61626c65436f6d706f756e643a20436f6d706f756e6420697320616c726561647920656e61626c656446756e64732e7365744c6f616e733a20546f6b656e732063616e6e6f7420626520617070726f76656446756e64732e736574436f6d706f756e643a20636f6d7074726f6c6c65722061646472657373206d757374206265206e6f6e2d7a65726f46756e64732e64697361626c65436f6d706f756e643a20436f6d706f756e6420697320616c72656164792064697361626c656446756e64732e7365745574696c697a6174696f6e496e74657265737444697669736f723a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e7365744d696e496e746572657374526174654e756d657261746f723a206d696e496e746572657374526174654e756d657261746f72206973207a65726f46756e64732e726571756573743a204c6f616e206475726174696f6e206d757374206265206c657373207468616e206d61784c6f616e44757220616e642065787069727946756e64732e637265617465437573746f6d3a2043616e6e6f7420656e61626c6520436f6d706f756e6420617320697420686173206e6f74206265656e20636f6e6669677572656446756e64732e736574496e74657265737455706461746544656c61793a20696e74657265737455706461746544656c6179206973207a65726f46756e64732e736574476c6f62616c496e746572657374526174654e756d657261746f723a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e726571756573743a20416d6f756e7420726571756573746564206d757374206265206c657373207468616e206d61784c6f616e416d7446756e64732e7570646174653a2066756e6445787069727920616e64206d61784c6f616e4475722063616e6e6f742065786365656420313020796561727346756e64732e736574436f6d706f756e643a204f6e6c7920746865206465706c6f7965722063616e20656e61626c6520436f6d706f756e64206c656e64696e6746756e64732e757064617465437573746f6d3a206d61784c6f616e416d74206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c6f616e416d7446756e64732e7365744c6f616e733a204c6f616e7320616464726573732068617320616c7265616479206265656e2073657446756e64732e7365744d696e496e746572657374526174654e756d657261746f723a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e6465637265617365546f74616c426f72726f773a204f6e6c7920746865204c6f616e7320636f6e74726163742063616e20706572666f726d207468697346756e64732e64697361626c65436f6d706f756e643a204f6e6c7920746865206c656e6465722063616e2064697361626c6520436f6d706f756e6446756e64732e6372656174653a2066756e6445787069727920616e64206d61784c6f616e4475722063616e6e6f742065786365656420313020796561727346756e64732e726571756573743a20496e73756666696369656e742062616c616e636546756e64732e7365744c6f616e733a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e7570646174653a204f6e6c7920746865206c656e6465722063616e20757064617465207468652066756e6446756e64732e7365744d61785574696c697a6174696f6e44656c74613a206d61785574696c697a6174696f6e44656c7461206973207a65726f46756e64732e6372656174653a204f6e6c79206f6e65206c6f616e2066756e6420616c6c6f77656420706572206164647265737346756e64732e726571756573743a20416d6f756e7420726571756573746564206d7573742062652067726561746572207468616e206d696e4c6f616e416d7446756e64732e736574436f6d706f756e643a20436f6d706f756e6420616464726573732068617320616c7265616479206265656e2073657446756e64732e726571756573743a20426f72726f7765722061646472657373206d757374206265206e6f6e2d7a65726f46756e64732e637265617465437573746f6d3a206d61784c6f616e447572206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c6f616e44757246756e64732e73657444656661756c74417262697465724665653a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e736574496e74657265737455706461746544656c61793a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e736574476c6f62616c496e746572657374526174654e756d657261746f723a20676c6f62616c496e746572657374526174654e756d657261746f72206973207a65726f46756e64732e726571756573743a20536563726574486173683720262053656372657448617368382073686f756c64206265206e6f6e2d7a65726f46756e64732e726571756573743a204f6e6c7920746865206c656e6465722063616e2066756c66696c6c2061206c6f616e207265717565737446756e64732e6465706f7369743a204661696c656420746f207472616e7366657220746f6b656e7346756e64732e7769746864726177546f3a20546f6b656e207472616e73666572206661696c656446756e64732e7365744d6178496e746572657374526174654e756d657261746f723a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e637265617465437573746f6d3a206d61784c6f616e416d74206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c6f616e416d7446756e64732e6372656174653a2043616e6e6f7420656e61626c6520436f6d706f756e6420617320697420686173206e6f74206265656e20636f6e6669677572656446756e64732e736574476c6f62616c496e746572657374526174653a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e656e61626c65436f6d706f756e643a2043616e6e6f7420656e61626c6520436f6d706f756e6420617320697420686173206e6f74206265656e20636f6e6669677572656446756e64732e736574476c6f62616c496e746572657374526174653a20676c6f62616c496e74657265737452617465206973207a65726f46756e64732e637265617465437573746f6d3a2066756e6445787069727920616e64206d61784c6f616e4475722063616e6e6f742065786365656420313020796561727346756e64732e676574536563726574486173686573466f724c6f616e3a204e6f7420656e6f75676820736563726574732067656e65726174656446756e64732e757064617465437573746f6d3a206d61784c6f616e447572206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c6f616e44757246756e64732e726571756573743a20536563726574486173683520262053656372657448617368362073686f756c64206265206e6f6e2d7a65726f46756e64732e7769746864726177546f3a204f6e6c7920746865206c656e6465722063616e20776974686472617720746f6b656e7346756e64732e7365744d6178496e746572657374526174654e756d657261746f723a206d6178496e746572657374526174654e756d657261746f72206973207a65726f46756e64732e7365744c6f616e733a204c6f616e732061646472657373206d757374206265206e6f6e2d7a65726f46756e64732e656e61626c65436f6d706f756e643a204f6e6c7920746865206c656e6465722063616e20656e61626c6520436f6d706f756e6446756e64732e73657444656661756c74417262697465724665653a2064656661756c74417262697465724665652063616e6e6f74206265206c657373207468616e202d312546756e64732e757064617465437573746f6d3a2046756e64206d757374206265206120637573746f6d2066756e6446756e64732e7769746864726177546f3a20496e73756666696369656e742062616c616e636546756e64732e7365744d61785574696c697a6174696f6e44656c74613a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e736574436f6d706f756e643a2063546f6b656e2061646472657373206d757374206265206e6f6e2d7a65726f46756e64732e726571756573743a20536563726574486173683120262053656372657448617368322073686f756c64206265206e6f6e2d7a65726f46756e64732e726571756573743a20536563726574486173683320262053656372657448617368342073686f756c64206265206e6f6e2d7a65726f46756e64732e726571756573743a204c6f616e206475726174696f6e206d7573742062652067726561746572207468616e206d696e4c6f616e447572a265627a7a7230582001ece922c650df050f16dab7220a9a0e1dcfd2986d994476756a09a8d47974bd64736f6c634300050a003246756e64732e636f6e7374727563746f723a20546f6b656e2061646472657373206d757374206265206e6f6e2d7a65726f46756e64732e636f6e7374727563746f723a20446563696d616c73206d757374206265206e6f6e2d7a65726f000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000006
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106104545760003560e01c806376a0b16611610241578063d39a2c0c1161013b578063e91d14a4116100c3578063f61d02d311610087578063f61d02d314610de2578063f7837eb714610e51578063fa3bfb1714610e74578063fc0c546a14610e91578063fdd5aab114610e9957610454565b8063e91d14a414610cb9578063eae1c2cf14610cd6578063f05541be14610cde578063f0a422d014610ce6578063f59bf27314610cee57610454565b8063da2c5c5b1161010a578063da2c5c5b14610bec578063db9b376c14610bf4578063e179e77114610bfc578063e32d291314610c2e578063e493325614610c9c57610454565b8063d39a2c0c14610b0d578063d4785d2914610b33578063d73b906214610b50578063d9d0a2d114610bbe57610454565b8063a2c70b6b116101c9578063ba617eef1161018d578063ba617eef14610a30578063bf12f43d14610a4d578063ccb99d5514610a6a578063ce26d44b146105d0578063d1b8b4bf14610a7257610454565b8063a2c70b6b146109c9578063a5a70965146109e6578063a5fa6706146109ee578063a634baf214610a0b578063b2d6107114610a2857610454565b80638c5d5268116102105780638c5d52681461090f578063994871fa1461092c5780639d06bcea146109555780639fc3f02f1461097b578063a18e4a801461099857610454565b806376a0b166146108b05780637e25a221146108cd5780638285ef40146108ea57806389eba421146108f257610454565b806344b6ba95116103525780635fe3b567116102da57806369e527da1161029e57806369e527da1461077a5780636a29a620146107825780636a7bb32c1461081b5780636e1719a61461085b578063712d8e6a1461089357610454565b80635fe3b56714610735578063612ef80b1461073d5780636158153d14610745578063668064da1461074d578063689c76ef1461077257610454565b80634f9bc9d5116103215780634f9bc9d514610676578063513916741461067e578063516dbe24146106e457806354e39f90146107015780635b873ffa1461072d57610454565b806344b6ba95146105f557806347ca77161461062e5780634c9fb84a146106365780634ee9159a1461066e57610454565b80631beec294116103e05780632eb1ad73116103a45780632eb1ad73146105b8578063313ce567146105c057806333549b1b146105c85780633d41a26b146105d057806342febf0c146105d857610454565b80631beec294146105185780631de26e161461053557806321fd933b1461055857806326fc75901461057e57806327cdab061461059b57610454565b806304e9ef031161042757806304e9ef03146104db57806316df840a146104e35780631723cfa5146104eb5780631873fe50146104f35780631bb736971461051057610454565b806301937d0414610459578063031558e51461049157806303b69d1814610499578063040cf020146104b6575b600080fd5b61047f6004803603602081101561046f57600080fd5b50356001600160a01b0316610ea1565b60408051918252519081900360200190f35b61047f610eb3565b61047f600480360360208110156104af57600080fd5b5035610eb9565b6104d9600480360360408110156104cc57600080fd5b5080359060200135610f12565b005b61047f610f21565b61047f610f27565b61047f610f2d565b6104d96004803603602081101561050957600080fd5b5035610f3d565b61047f610fd6565b6104d96004803603602081101561052e57600080fd5b5035610fdc565b6104d96004803603604081101561054b57600080fd5b5080359060200135611066565b61047f6004803603602081101561056e57600080fd5b50356001600160a01b03166112eb565b61047f6004803603602081101561059457600080fd5b50356112fd565b61047f600480360360208110156105b157600080fd5b503561133f565b61047f611377565b61047f61137d565b6104d9611383565b61047f611495565b61047f600480360360208110156105ee57600080fd5b503561149b565b6106126004803603602081101561060b57600080fd5b50356114d3565b604080516001600160a01b039092168252519081900360200190f35b61047f6114f1565b6104d96004803603608081101561064c57600080fd5b50803590602081013590604081013590606001356001600160a01b03166114fe565b610612611648565b61047f611658565b6104d9600480360361016081101561069557600080fd5b5080359060208101359060408101359060608101359060808101359060a08101359060c08101359060e081013590610100810135906101208101359061014001356001600160a01b031661165e565b6104d9600480360360208110156106fa57600080fd5b503561177e565b61047f6004803603604081101561071757600080fd5b506001600160a01b038135169060200135611808565b61047f611836565b61061261183c565b61047f61184b565b61047f611851565b61047f6004803603604081101561076357600080fd5b50803590602001351515611859565b61047f611887565b61061261188d565b61079f6004803603602081101561079857600080fd5b503561189c565b604080516001600160a01b039e8f168152602081019d909d528c81019b909b5260608c019990995260808b019790975260a08a019590955260c089019390935260e08801919091526101008701526101208601529094166101408401526101608301939093526101808201929092529051908190036101a00190f35b61047f600480360360a081101561083157600080fd5b508035906020810135906001600160a01b0360408201351690606081013515159060800135611910565b6108786004803603602081101561087157600080fd5b5035611b30565b60408051921515835290151560208301528051918290030190f35b61047f600480360360208110156108a957600080fd5b5035611b4e565b61047f600480360360208110156108c657600080fd5b5035611b63565b6104d9600480360360208110156108e357600080fd5b5035611ba5565b61047f611e15565b61047f6004803603602081101561090857600080fd5b5035611e1b565b6104d96004803603602081101561092557600080fd5b5035611edc565b61047f6004803603606081101561094257600080fd5b5080359060208101359060400135611f66565b6104d96004803603602081101561096b57600080fd5b50356001600160a01b0316611f8c565b6106126004803603602081101561099157600080fd5b5035612138565b6109b5600480360360208110156109ae57600080fd5b5035612153565b604080519115158252519081900360200190f35b6104d9600480360360208110156109df57600080fd5b5035612168565b61047f6121f2565b6104d960048036036020811015610a0457600080fd5b50356121f8565b61047f60048036036020811015610a2157600080fd5b50356124bd565b61047f6124f5565b61047f60048036036020811015610a4657600080fd5b50356124fb565b6104d960048036036020811015610a6357600080fd5b5035612511565b61047f61259b565b610a9860048036036020811015610a8857600080fd5b50356001600160a01b03166125ab565b6040805160208082528351818301528351919283929083019185019080838360005b83811015610ad2578181015183820152602001610aba565b50505050905090810190601f168015610aff5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b61047f60048036036020811015610b2357600080fd5b50356001600160a01b0316612646565b6104d960048036036020811015610b4957600080fd5b5035612661565b6104d960048036036020811015610b6657600080fd5b810190602081018135600160201b811115610b8057600080fd5b820183602082011115610b9257600080fd5b803590602001918460208302840111600160201b83111715610bb357600080fd5b5090925090506126eb565b6104d960048036036040811015610bd457600080fd5b506001600160a01b0381358116916020013516612740565b61047f61289a565b61047f6128a2565b6104d960048036036060811015610c1257600080fd5b50803590602081013590604001356001600160a01b03166128a8565b6104d960048036036020811015610c4457600080fd5b810190602081018135600160201b811115610c5e57600080fd5b820183602082011115610c7057600080fd5b803590602001918460018302840111600160201b83111715610c9157600080fd5b509092509050612cf5565b6104d960048036036020811015610cb257600080fd5b5035612d0f565b61047f60048036036020811015610ccf57600080fd5b5035612d6a565b61047f612da2565b61047f612da8565b61047f612dae565b61047f6004803603610200811015610d0557600080fd5b8135916001600160a01b036020820135169160408201359160608101359160808201359160a08101359160c0820191908101906101e081016101c0820135600160201b811115610d5457600080fd5b820183602082011115610d6657600080fd5b803590602001918460018302840111600160201b83111715610d8757600080fd5b919390929091602081019035600160201b811115610da457600080fd5b820183602082011115610db657600080fd5b803590602001918460018302840111600160201b83111715610dd757600080fd5b509092509050612e4e565b61047f6004803603610180811015610df957600080fd5b5080359060208101359060408101359060608101359060808101359060a08101359060c08101359060e081013590610100810135906001600160a01b0361012082013516906101408101351515906101600135613336565b61047f60048036036040811015610e6757600080fd5b508035906020013561367a565b6104d960048036036020811015610e8a57600080fd5b50356136ab565b610612613735565b61047f613744565b60036020526000908152604090205481565b60115481565b60008181526007602052604081205460ff1615610ee85750600081815260056020526040902060010154610f0d565b610f0a68015af1d78b58c40000610f02601260185461374a565b600a0a61375a565b90505b919050565b610f1d8282336128a8565b5050565b60165481565b600b5481565b6b04860d8812f0b3887800000081565b601a546001600160a01b03163314610f865760405162461bcd60e51b815260040180806020018281038252603e815260200180614fb3603e913960400191505060405180910390fd5b6b033b2e3ca43176a9d2dfd0a5811115610fd15760405162461bcd60e51b81526004018080602001828103825260458152602001806154b06045913960600191505060405180910390fd5b601655565b600e5481565b601a546001600160a01b031633146110255760405162461bcd60e51b8152600401808060200182810382526048815260200180614b506048913960600191505060405180910390fd5b806110615760405162461bcd60e51b81526004018080602001828103825260498152602001806150316049913960600191505060405180910390fd5b600e55565b601754604080516323b872dd60e01b81523360048201523060248201526044810184905290516001600160a01b03909216916323b872dd916064808201926020929091908290030181600087803b1580156110c057600080fd5b505af11580156110d4573d6000803e3d6000fd5b505050506040513d60208110156110ea57600080fd5b50516111275760405162461bcd60e51b81526004018080602001828103825260288152602001806150ee6028913960400191505060405180910390fd5b600082815260076020526040902054610100900460ff161561124c57601754601954611160916001600160a01b03908116911683613771565b60006111f861117783670de0b6b3a764000061388b565b601960009054906101000a90046001600160a01b03166001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b1580156111c757600080fd5b505af11580156111db573d6000803e3d6000fd5b505050506040513d60208110156111f157600080fd5b505161375a565b6000848152600560205260409020600c015490915061121790826138af565b6000848152600560205260409020600c015561123283612153565b61124657611242600b54826138af565b600b555b50611297565b6000828152600560205260409020600b015461126890826138af565b6000838152600560205260409020600b015561128382612153565b61129757611293600a54826138af565b600a555b6112a082612153565b6112ac576112ac611383565b604080518381526020810183905281517f98e783c3864bbf744a057ef605a2a61701c3b62b5ed68b3745b99094497daf1f929181900390910190a15050565b60066020526000908152604090205481565b60008181526007602052604081205460ff161561132c5750600081815260056020526040902060070154610f0d565b506b033b2e3cacd278c7503e82c1610f0d565b60008181526007602052604081205460ff161561136e5750600081815260056020526040902060080154610f0d565b50601654610f0d565b60095481565b60185481565b6113a1600a5461139c600b54611397612dae565b6138bf565b6138af565b600c556009546015546113b491906138af565b421115611493576000600d546000146113e3576113e0600d546113db600c54600d546138af565b6138e7565b90505b600f5481111561142e5760006113fb82600f5461374a565b9050611425601354611420600e5461139c6114186011548761390b565b6012546138e7565b61390b565b600e5550611468565b600061143c600f548361374a565b905061146360145461145e600e546114596114186011548761390b565b61374a565b61391e565b600e55505b6114886b033b2e3c9fd0803ce800000061139c600e546301e1338061375a565b60105542600955600f555b565b60001981565b60008181526007602052604081205460ff16156114ca5750600081815260056020526040902060020154610f0d565b50600019610f0d565b6000908152600560205260409020600a01546001600160a01b031690565b68015af1d78b58c4000081565b61150784612138565b6001600160a01b0316336001600160a01b0316146115565760405162461bcd60e51b8152600401808060200182810382526031815260200180614e246031913960400191505060405180910390fd5b6312cc0300611566846000611859565b111580156115845750426312cc030001611581836001611859565b11155b6115bf5760405162461bcd60e51b815260040180806020018281038252603e815260200180614bd4603e913960400191505060405180910390fd5b60008481526005602081815260409283902060048101879055918201859055600a90910180546001600160a01b0385166001600160a01b031990911681179091558251878152918201869052818301859052606082015290517fbc2980147202467df8874a7f933ee11c59b6b1f6273647aca58bd18d349e67ac9181900360800190a150505050565b6000546001600160a01b03165b90565b60125481565b60008b81526007602052604090205460ff166116ab5760405162461bcd60e51b815260040180806020018281038252602e8152602001806154f5602e913960400191505060405180910390fd5b898910156116ea5760405162461bcd60e51b815260040180806020018281038252604a815260200180614c52604a913960600191505060405180910390fd5b876116f6886000611859565b10156117335760405162461bcd60e51b815260040180806020018281038252604a81526020018061534c604a913960600191505060405180910390fd5b61173f8b8888846114fe565b506000998a5260056020526040909920600181019890985560028801969096556003870194909455600686015550506007830155600882015560090155565b601a546001600160a01b031633146117c75760405162461bcd60e51b8152600401808060200182810382526040815260200180614ff16040913960400191505060405180910390fd5b806118035760405162461bcd60e51b8152600401808060200182810382526039815260200180614b176039913960400191505060405180910390fd5b601555565b6002602052816000526040600020818154811061182157fe5b90600052602060002001600091509150505481565b60105481565b6000546001600160a01b031681565b600c5481565b6312cc030081565b60008261187e5781156118735750426312cc030001611881565b506312cc0300611881565b50815b92915050565b60145481565b6019546001600160a01b031681565b600560208190526000918252604090912080546001820154600283015460038401546004850154958501546006860154600787015460088801546009890154600a8a0154600b8b0154600c909b01546001600160a01b039a8b169c999b989a9799989697959694959394929390911691908d565b336000818152600660209081526040808320548352600590915281205490916001600160a01b0390911614156119775760405162461bcd60e51b8152600401808060200182810382526034815260200180614e8e6034913960400191505060405180910390fd5b6312cc0300611987876000611859565b1080156119a35750426312cc0300016119a1866001611859565b105b6119de5760405162461bcd60e51b815260040180806020018281038252603e815260200180614d91603e913960400191505060405180910390fd5b601954600160a01b900460ff16611a2c578215611a2c5760405162461bcd60e51b81526004018080602001828103825260428152602001806151cc6042913960600191505060405180910390fd5b611a3960085460016138af565b6008819055600081815260056020526040812080546001600160a01b03191633179055909150611a6a908790611859565b600082815260056020526040902060040155611a87856001611859565b600082815260056020818152604080842092830194909455600a90910180546001600160a01b0319166001600160a01b03891617905560078152828220805461ffff1916610100881515021790556008543383526006909152919020558115611af457611af48183611066565b6040805182815290517fa7857d7da6974b0157f3bf7dd25a745bd7d81d845bb525ee0b316a87541a5c319181900360200190a195945050505050565b60076020526000908152604090205460ff8082169161010090041682565b60009081526005602052604090206004015490565b60008181526007602052604081205460ff1615611b925750600081815260056020526040902060090154610f0d565b506b04860d8812f0b38878000000610f0d565b600081815260076020526040902054610100900460ff16611bf75760405162461bcd60e51b81526004018080602001828103825260338152602001806149ce6033913960400191505060405180910390fd5b611c0081612138565b6001600160a01b0316336001600160a01b031614611c4f5760405162461bcd60e51b815260040180806020018281038252603b815260200180614d56603b913960400191505060405180910390fd5b601754604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611c9a57600080fd5b505afa158015611cae573d6000803e3d6000fd5b505050506040513d6020811015611cc457600080fd5b50516019546000848152600560205260409020600c0154919250611cf3916001600160a01b039091169061392e565b601754604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611d3e57600080fd5b505afa158015611d52573d6000803e3d6000fd5b505050506040513d6020811015611d6857600080fd5b505190506000611d78828461374a565b9050611d86600a54826138af565b600a55600b546000858152600560205260409020600c0154611da8919061374a565b600b9081556000858152600760209081526040808320805461ff001916905560058252808320600c81019390935591909201839055805186815290517ffb6e0a1c4958f3e250db013b5035dc019d1e6426df7b4a40a5d0229a336aad53929181900390910190a150505050565b600d5481565b600081815260076020526040812054610100900460ff1615611ec4576000828152600560209081526040808320600c0154601954825163bd6d894d60e01b81529251610f0a9592946001600160a01b039092169363bd6d894d9360048083019493928390030190829087803b158015611e9357600080fd5b505af1158015611ea7573d6000803e3d6000fd5b505050506040513d6020811015611ebd57600080fd5b50516138bf565b506000818152600560205260409020600b0154610f0d565b601a546001600160a01b03163314611f255760405162461bcd60e51b815260040180806020018281038252603f81526020018061520e603f913960400191505060405180910390fd5b80611f615760405162461bcd60e51b81526004018080602001828103825260378152602001806152976037913960400191505060405180910390fd5b601055565b6000611f84611f7e85611f798686613a7e565b613ad8565b8561374a565b949350505050565b601a546001600160a01b03163314611fd55760405162461bcd60e51b8152600401808060200182810382526032815260200180614df26032913960400191505060405180910390fd5b6001546001600160a01b03161561201d5760405162461bcd60e51b8152600401808060200182810382526032815260200180614c9c6032913960400191505060405180910390fd5b6001600160a01b0381166120625760405162461bcd60e51b815260040180806020018281038252602e815260200180615449602e913960400191505060405180910390fd5b600180546001600160a01b0319166001600160a01b038381169182179092556017546040805163095ea7b360e01b8152600481019390935260001960248401525192169163095ea7b3916044808201926020929091908290030181600087803b1580156120ce57600080fd5b505af11580156120e2573d6000803e3d6000fd5b505050506040513d60208110156120f857600080fd5b50516121355760405162461bcd60e51b815260040180806020018281038252602981526020018061496e6029913960400191505060405180910390fd5b50565b6000908152600560205260409020546001600160a01b031690565b60009081526007602052604090205460ff1690565b601a546001600160a01b031633146121b15760405162461bcd60e51b81526004018080602001828103825260408152602001806155496040913960400191505060405180910390fd5b806121ed5760405162461bcd60e51b8152600401808060200182810382526039815260200180614e556039913960400191505060405180910390fd5b601155565b60085481565b601954600160a01b900460ff166122405760405162461bcd60e51b815260040180806020018281038252604a81526020018061524d604a913960600191505060405180910390fd5b600081815260076020526040902054610100900460ff16156122935760405162461bcd60e51b815260040180806020018281038252603181526020018061493d6031913960400191505060405180910390fd5b61229c81612138565b6001600160a01b0316336001600160a01b0316146122eb5760405162461bcd60e51b81526004018080602001828103825260398152602001806154776039913960400191505060405180910390fd5b601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561233657600080fd5b505afa15801561234a573d6000803e3d6000fd5b505050506040513d602081101561236057600080fd5b50516017546019546000858152600560205260409020600b0154929350612396926001600160a01b039283169290911690613771565b601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156123e157600080fd5b505afa1580156123f5573d6000803e3d6000fd5b505050506040513d602081101561240b57600080fd5b50519050600061241b828461374a565b600a546000868152600560205260409020600b015491925061243c9161374a565b600a55600b5461244c90826138af565b600b9081556000858152600760209081526040808320805461ff0019166101001790556005825280832093840192909255600c909201839055805186815290517f43c40c3c72eec13a64775a3231f52699c8ba28e57131e7343e4f57734d8a3ce4929181900390910190a150505050565b60008181526007602052604081205460ff16156124ec5750600081815260056020526040902060030154610f0d565b50615460610f0d565b61546081565b6000908152600560208190526040909120015490565b601a546001600160a01b0316331461255a5760405162461bcd60e51b8152600401808060200182810382526047815260200180614a016047913960600191505060405180910390fd5b806125965760405162461bcd60e51b81526004018080602001828103825260478152602001806148f66047913960600191505060405180910390fd5b601255565b6b033b2e3cacd278c7503e82c181565b60046020908152600091825260409182902080548351601f60026000196101006001861615020190931692909204918201849004840281018401909452808452909183018282801561263e5780601f106126135761010080835404028352916020019161263e565b820191906000526020600020905b81548152906001019060200180831161262157829003601f168201915b505050505081565b6001600160a01b031660009081526002602052604090205490565b601a546001600160a01b031633146126aa5760405162461bcd60e51b8152600401808060200182810382526045815260200180614cce6045913960600191505060405180910390fd5b806126e65760405162461bcd60e51b8152600401808060200182810382526043815260200180614a486043913960600191505060405180910390fd5b601455565b60005b8181101561273b5733600090815260026020526040902083838381811061271157fe5b835460018082018655600095865260209586902092909502939093013592019190915550016126ee565b505050565b601a546001600160a01b031633146127895760405162461bcd60e51b8152600401808060200182810382526040815260200180614c126040913960400191505060405180910390fd5b601954600160a01b900460ff16156127d25760405162461bcd60e51b8152600401808060200182810382526038815260200180614f016038913960400191505060405180910390fd5b6001600160a01b0382166128175760405162461bcd60e51b81526004018080602001828103825260328152602001806155896032913960400191505060405180910390fd5b6001600160a01b03811661285c5760405162461bcd60e51b81526004018080602001828103825260378152602001806149976037913960400191505060405180910390fd5b60198054600080546001600160a01b039485166001600160a01b03199182161790915560ff60a01b199390941693169290921716600160a01b179055565b6301e1338081565b60155481565b6128b183612138565b6001600160a01b0316336001600160a01b0316146129005760405162461bcd60e51b81526004018080602001828103825260358152602001806153d16035913960400191505060405180910390fd5b8161290a84611e1b565b10156129475760405162461bcd60e51b81526004018080602001828103825260268152602001806155236026913960400191505060405180910390fd5b600083815260076020526040902054610100900460ff1615612b8b57601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b1580156129ae57600080fd5b505afa1580156129c2573d6000803e3d6000fd5b505050506040513d60208110156129d857600080fd5b50516019549091506129f3906001600160a01b031684613b08565b601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015612a3e57600080fd5b505afa158015612a52573d6000803e3d6000fd5b505050506040513d6020811015612a6857600080fd5b505190506000612a78838361374a565b6000878152600560205260409020600c0154909150612a97908261374a565b6000878152600560209081526040808320600c0193909355601754835163a9059cbb60e01b81526001600160a01b038981166004830152602482018b90529451949091169363a9059cbb93604480840194938390030190829087803b158015612aff57600080fd5b505af1158015612b13573d6000803e3d6000fd5b505050506040513d6020811015612b2957600080fd5b5051612b665760405162461bcd60e51b81526004018080602001828103825260278152602001806151166027913960400191505060405180910390fd5b612b6f86612153565b612b8357612b7f600b548261374a565b600b555b505050612c93565b6000838152600560205260409020600b0154612ba7908361374a565b6000848152600560209081526040808320600b0193909355601754835163a9059cbb60e01b81526001600160a01b038681166004830152602482018890529451949091169363a9059cbb93604480840194938390030190829087803b158015612c0f57600080fd5b505af1158015612c23573d6000803e3d6000fd5b505050506040513d6020811015612c3957600080fd5b5051612c765760405162461bcd60e51b81526004018080602001828103825260278152602001806151166027913960400191505060405180910390fd5b612c7f83612153565b612c9357612c8f600a548361374a565b600a555b612c9c83612153565b612ca857612ca8611383565b60408051848152602081018490526001600160a01b0383168183015290517f181177e6e9bbf7d7a45604cf4fdb0444641e20905d8d4daf2a7863036e56dc159181900360600190a1505050565b33600090815260046020526040902061273b90838361483f565b6001546001600160a01b03163314612d585760405162461bcd60e51b8152600401808060200182810382526043815260200180614d136043913960600191505060405180910390fd5b612d64600d548261374a565b600d5550565b60008181526007602052604081205460ff1615612d995750600081815260056020526040902060060154610f0d565b50601054610f0d565b60135481565b600f5481565b601954600090600160a01b900460ff1615612e4657601960009054906101000a90046001600160a01b03166001600160a01b031663bd6d894d6040518163ffffffff1660e01b8152600401602060405180830381600087803b158015612e1357600080fd5b505af1158015612e27573d6000803e3d6000fd5b505050506040513d6020811015612e3d57600080fd5b50519050611655565b506000611655565b6000612e598c612138565b6001600160a01b0316336001600160a01b031614612ea85760405162461bcd60e51b81526004018080602001828103825260398152602001806150b56039913960400191505060405180910390fd5b612eb18c611e1b565b8a1115612eef5760405162461bcd60e51b8152600401808060200182810382526023815260200180614dcf6023913960400191505060405180910390fd5b612ef88c610eb9565b8a1015612f365760405162461bcd60e51b815260040180806020018281038252603f815260200180614ec2603f913960400191505060405180910390fd5b612f3f8c61149b565b8a1115612f7d5760405162461bcd60e51b815260040180806020018281038252603c815260200180614b98603c913960400191505060405180910390fd5b612f868c6124bd565b881015612fc45760405162461bcd60e51b815260040180806020018281038252603c815260200180615631603c913960400191505060405180910390fd5b612fd6612fd08d6124fb565b4261374a565b8811158015612fed5750612fe98c611b4e565b8811155b6130285760405162461bcd60e51b8152600401808060200182810382526044815260200180614a8b6044913960600191505060405180910390fd5b6001600160a01b038b1661306d5760405162461bcd60e51b8152600401808060200182810382526030815260200180614f396030913960400191505060405180910390fd5b8535158015906130805750602086013515155b6130bb5760405162461bcd60e51b815260040180806020018281038252603b8152602001806155bb603b913960400191505060405180910390fd5b6040860135158015906130d15750606086013515155b61310c5760405162461bcd60e51b815260040180806020018281038252603b8152602001806155f6603b913960400191505060405180910390fd5b608086013515801590613122575060a086013515155b61315d5760405162461bcd60e51b815260040180806020018281038252603b815260200180615396603b913960400191505060405180910390fd5b60c086013515801590613173575060e086013515155b6131ae5760405162461bcd60e51b815260040180806020018281038252603b81526020018061507a603b913960400191505060405180910390fd5b6131bc8c8c8c8c8c8c613cbb565b905061325a8c8288600880602002604051908101604052809291908260086020028082843760009201919091525050604080516020601f8c018190048102820181019092528a815291508a908a908190840183828082843760009201919091525050604080516020601f8c018190048102820181019092528a815292508a9150899081908401838280828437600092019190915250613e5092505050565b6132648c8b61412f565b6001546040805163bf14c11960e01b81526004810184905290516001600160a01b039092169163bf14c1199160248082019260009290919082900301818387803b1580156132b157600080fd5b505af11580156132c5573d6000803e3d6000fd5b5050604080518f81526001600160a01b038f1660208201528082018e9052606081018d9052608081018c905260a081018b905290517ff494fa7145682762e6918aefe85748818b2f1092c6f8c0a3284bcb18506416d593509081900360c0019150a19b9a5050505050505050505050565b336000818152600660209081526040808320548352600590915281205490916001600160a01b03909116141561339d5760405162461bcd60e51b8152600401808060200182810382526034815260200180614e8e6034913960400191505060405180910390fd5b6312cc03006133ad8b6000611859565b1080156133c95750426312cc0300016133c78a6001611859565b105b6134045760405162461bcd60e51b81526004018080602001828103825260448152602001806152ce6044913960600191505060405180910390fd5b8c8c10156134435760405162461bcd60e51b815260040180806020018281038252604a815260200180615182604a913960600191505060405180910390fd5b8a61344f8b6000611859565b101561348c5760405162461bcd60e51b815260040180806020018281038252604a815260200180614f69604a913960600191505060405180910390fd5b601954600160a01b900460ff166134da5782156134da5760405162461bcd60e51b8152600401808060200182810382526048815260200180614acf6048913960600191505060405180910390fd5b6134e760085460016138af565b60088190555060085460001b9050336005600083815260200190815260200160002060000160006101000a8154816001600160a01b0302191690836001600160a01b031602179055508c60056000838152602001908152602001600020600101819055508b60056000838152602001908152602001600020600201819055508a600560008381526020019081526020016000206003018190555061358c8a6000611859565b6000828152600560205260409020600401556135a9896001611859565b60008281526005602081815260408084209283019490945560068083018c905560078084018c905560088085018c9055600985018f9055600a90940180546001600160a01b0319166001600160a01b038c161790558252848420805460ff191660011761ff0019166101008a1515021790559154338452919052919020558115613637576136378183611066565b6040805182815290517fa7857d7da6974b0157f3bf7dd25a745bd7d81d845bb525ee0b316a87541a5c319181900360200190a19c9b505050505050505050505050565b60006305f5e10061369c61368e858561388b565b60026305f5e1005b046138af565b816136a357fe5b049392505050565b601a546001600160a01b031633146136f45760405162461bcd60e51b815260040180806020018281038252604581526020018061513d6045913960600191505060405180910390fd5b806137305760405162461bcd60e51b81526004018080602001828103825260438152602001806154066043913960600191505060405180910390fd5b601355565b6017546001600160a01b031681565b600a5481565b8082038281111561188157600080fd5b600080821161376857600080fd5b8183816136a357fe5b61377a82614325565b604080516370a0823160e01b8152306004820152905184916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b1580156137c557600080fd5b505afa1580156137d9573d6000803e3d6000fd5b505050506040513d60208110156137ef57600080fd5b50519050828111156137fe5750815b8361380a8683836145a8565b806001600160a01b031663a0712d68836040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b15801561385057600080fd5b505af1158015613864573d6000803e3d6000fd5b505050506040513d602081101561387a57600080fd5b50511561388357fe5b505050505050565b60008115806138a6575050808202828282816138a357fe5b04145b61188157600080fd5b8082018281101561188157600080fd5b6000670de0b6b3a764000061369c6138d7858561388b565b6002670de0b6b3a7640000613696565b60008161369c613903856b033b2e3c9fd0803ce800000061388b565b600285613696565b60008183111561187e57815b9392505050565b60008183101561187e5781613917565b604080516370a0823160e01b8152306004820152905183916000916001600160a01b038416916370a08231916024808301926020929190829003018186803b15801561397957600080fd5b505afa15801561398d573d6000803e3d6000fd5b505050506040513d60208110156139a357600080fd5b50519050828111156139b25750815b6139bd8482866145a8565b816001600160a01b031663db006a75826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015613a0357600080fd5b505af1158015613a17573d6000803e3d6000fd5b505050506040513d6020811015613a2d57600080fd5b505115613a78576040805162461bcd60e51b8152602060048201526014602482015273736f6d657468696e672077656e742077726f6e6760601b604482015290519081900360640190fd5b50505050565b600060028206613a9a576b033b2e3c9fd0803ce8000000613a9c565b825b90506002820491505b811561188157613ab58384613ad8565b92506002820615613acd57613aca8184613ad8565b90505b600282049150613aa5565b60006b033b2e3c9fd0803ce800000061369c613af4858561388b565b60026b033b2e3c9fd0803ce8000000613696565b81613b298174446c3b15f9926687d2c40534fdb564000000000000816145a8565b604080516370a0823160e01b815230600482015290516000916001600160a01b038416916370a0823191602480820192602092909190829003018186803b158015613b7357600080fd5b505afa158015613b87573d6000803e3d6000fd5b505050506040513d6020811015613b9d57600080fd5b50516040805163bd6d894d60e01b81529051919250600091613bec9184916001600160a01b0387169163bd6d894d91600480830192602092919082900301818987803b158015611e9357600080fd5b905083811115613bf95750825b826001600160a01b031663852a12e3826040518263ffffffff1660e01b815260040180828152602001915050602060405180830381600087803b158015613c3f57600080fd5b505af1158015613c53573d6000803e3d6000fd5b505050506040513d6020811015613c6957600080fd5b505115613cb4576040805162461bcd60e51b8152602060048201526014602482015273736f6d657468696e672077656e742077726f6e6760601b604482015290519081900360640190fd5b5050505050565b60015460408051606081019091526001600160a01b03878116825260009216906310375921904286019060208101613cf28c612138565b6001600160a01b03908116825260008d815260056020908152604091829020600a015490921692820192909252815160e081019092528a82528101613d408b613d3a8f612d6a565b8b611f66565b8152602001613d528b613d3a8f6112fd565b8152602001613d648b613d3a8f61133f565b8152602001898152602001613d788d611b63565b81526020018790526040516001600160e01b031960e086901b168152600481018481528d9160240184606080838360005b83811015613dc1578181015183820152602001613da9565b5050505090500183600760200280838360005b83811015613dec578181015183820152602001613dd4565b50505050905001828152602001945050505050602060405180830381600087803b158015613e1957600080fd5b505af1158015613e2d573d6000803e3d6000fd5b505050506040513d6020811015613e4357600080fd5b5051979650505050505050565b600154604080516080808201835286518252602080880151818401528784015183850152606080890151908401528351808301855291880151825260a0880151908201526001600160a01b039093169263ee79b12b928892919081018860066020020151815260200188600760088110613ec657fe5b60200201519052613ede613ed98b6114d3565b614688565b878760046000613eed8f6114d3565b6001600160a01b03166001600160a01b031681526020019081526020016000206040518863ffffffff1660e01b81526004018088815260200187600460200280838360005b83811015613f4a578181015183820152602001613f32565b5050505090500186600460200280838360005b83811015613f75578181015183820152602001613f5d565b5050505090500185600460200280838360005b83811015613fa0578181015183820152602001613f88565b50505050905001806020018060200180602001848103845287818151815260200191508051906020019080838360005b83811015613fe8578181015183820152602001613fd0565b50505050905090810190601f1680156140155780820380516001836020036101000a031916815260200191505b50848103835286518152865160209182019188019080838360005b83811015614048578181015183820152602001614030565b50505050905090810190601f1680156140755780820380516001836020036101000a031916815260200191505b508481038252855460026000196101006001841615020190911604808252602090910190869080156140e85780601f106140bd576101008083540402835291602001916140e8565b820191906000526020600020905b8154815290600101906020018083116140cb57829003601f168201915b50509a5050505050505050505050600060405180830381600087803b15801561411057600080fd5b505af1158015614124573d6000803e3d6000fd5b505050505050505050565b600082815260076020526040902054610100900460ff16156142b657601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561419657600080fd5b505afa1580156141aa573d6000803e3d6000fd5b505050506040513d60208110156141c057600080fd5b50516019549091506141db906001600160a01b031683613b08565b601954604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b15801561422657600080fd5b505afa15801561423a573d6000803e3d6000fd5b505050506040513d602081101561425057600080fd5b505190506000614260838361374a565b6000868152600560205260409020600c015490915061427f908261374a565b6000868152600560205260409020600c015561429a85612153565b6142ae576142aa600b548261374a565b600b555b505050614301565b6000828152600560205260409020600b01546142d2908261374a565b6000838152600560205260409020600b01556142ed82612153565b614301576142fd600a548261374a565b600a555b61430a82612153565b610f1d5761431a600d54826138af565b600d55610f1d611383565b600061432f611648565b60408051632aff3bff60e21b815230600482015290519192506060916001600160a01b0384169163abfceffc916024808301926000929190829003018186803b15801561437b57600080fd5b505afa15801561438f573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156143b857600080fd5b810190808051600160201b8111156143cf57600080fd5b820160208101848111156143e257600080fd5b81518560208202830111600160201b821117156143fe57600080fd5b509094506000935083925050505b825181101561444f57846001600160a01b031683828151811061442b57fe5b60200260200101516001600160a01b0316141561444757600191505b60010161440c565b5080613a785760408051600180825281830190925260609160208083019080388339019050509050848160008151811061448557fe5b6001600160a01b03928316602091820292909201810191909152604051631853304760e31b8152600481018281528451602483015284519388169363c29982389386938392604490910191858101910280838360005b838110156144f35781810151838201526020016144db565b5050505090500192505050600060405180830381600087803b15801561451857600080fd5b505af115801561452c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561455557600080fd5b810190808051600160201b81111561456c57600080fd5b8201602081018481111561457f57600080fd5b81518560208202830111600160201b8211171561459b57600080fd5b5050505050505050505050565b60408051636eb1769f60e11b81523060048201526001600160a01b038381166024830152915185926000929084169163dd62ed3e91604480820192602092909190829003018186803b1580156145fd57600080fd5b505afa158015614611573d6000803e3d6000fd5b505050506040513d602081101561462757600080fd5b5051905080841115613cb4576040805163095ea7b360e01b81526001600160a01b038581166004830152600160ff1b602483015291519184169163095ea7b39160448082019260009290919082900301818387803b15801561411057600080fd5b6146906148bd565b6001600160a01b0382166000908152600360205260409020546146b49060046138af565b6001600160a01b03831660009081526003602052604090208190556146d883612646565b10156147155760405162461bcd60e51b815260040180806020018281038252603a815260200180615312603a913960400191505060405180910390fd5b604080516080810182526001600160a01b0384166000908152600260209081528382206003909152929020549091829161475090600461374a565b8154811061475a57fe5b600091825260208083209091015483526001600160a01b03861682526002815260408083206003808452919093205493909101926147979161374a565b815481106147a157fe5b600091825260208083209091015483526001600160a01b0386168252600280825260408084206003845293205493909101926147dc9161374a565b815481106147e657fe5b600091825260208083209091015483526001600160a01b03861682526002815260408083206003835292205492019161482090600161374a565b8154811061482a57fe5b90600052602060002001548152509050919050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106148805782800160ff198235161785556148ad565b828001600101855582156148ad579182015b828111156148ad578235825591602001919060010190614892565b506148b99291506148db565b5090565b60405180608001604052806004906020820280388339509192915050565b61165591905b808211156148b957600081556001016148e156fe46756e64732e7365745574696c697a6174696f6e496e74657265737444697669736f723a207574696c697a6174696f6e496e74657265737444697669736f72206973207a65726f46756e64732e656e61626c65436f6d706f756e643a20436f6d706f756e6420697320616c726561647920656e61626c656446756e64732e7365744c6f616e733a20546f6b656e732063616e6e6f7420626520617070726f76656446756e64732e736574436f6d706f756e643a20636f6d7074726f6c6c65722061646472657373206d757374206265206e6f6e2d7a65726f46756e64732e64697361626c65436f6d706f756e643a20436f6d706f756e6420697320616c72656164792064697361626c656446756e64732e7365745574696c697a6174696f6e496e74657265737444697669736f723a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e7365744d696e496e746572657374526174654e756d657261746f723a206d696e496e746572657374526174654e756d657261746f72206973207a65726f46756e64732e726571756573743a204c6f616e206475726174696f6e206d757374206265206c657373207468616e206d61784c6f616e44757220616e642065787069727946756e64732e637265617465437573746f6d3a2043616e6e6f7420656e61626c6520436f6d706f756e6420617320697420686173206e6f74206265656e20636f6e6669677572656446756e64732e736574496e74657265737455706461746544656c61793a20696e74657265737455706461746544656c6179206973207a65726f46756e64732e736574476c6f62616c496e746572657374526174654e756d657261746f723a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e726571756573743a20416d6f756e7420726571756573746564206d757374206265206c657373207468616e206d61784c6f616e416d7446756e64732e7570646174653a2066756e6445787069727920616e64206d61784c6f616e4475722063616e6e6f742065786365656420313020796561727346756e64732e736574436f6d706f756e643a204f6e6c7920746865206465706c6f7965722063616e20656e61626c6520436f6d706f756e64206c656e64696e6746756e64732e757064617465437573746f6d3a206d61784c6f616e416d74206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c6f616e416d7446756e64732e7365744c6f616e733a204c6f616e7320616464726573732068617320616c7265616479206265656e2073657446756e64732e7365744d696e496e746572657374526174654e756d657261746f723a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e6465637265617365546f74616c426f72726f773a204f6e6c7920746865204c6f616e7320636f6e74726163742063616e20706572666f726d207468697346756e64732e64697361626c65436f6d706f756e643a204f6e6c7920746865206c656e6465722063616e2064697361626c6520436f6d706f756e6446756e64732e6372656174653a2066756e6445787069727920616e64206d61784c6f616e4475722063616e6e6f742065786365656420313020796561727346756e64732e726571756573743a20496e73756666696369656e742062616c616e636546756e64732e7365744c6f616e733a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e7570646174653a204f6e6c7920746865206c656e6465722063616e20757064617465207468652066756e6446756e64732e7365744d61785574696c697a6174696f6e44656c74613a206d61785574696c697a6174696f6e44656c7461206973207a65726f46756e64732e6372656174653a204f6e6c79206f6e65206c6f616e2066756e6420616c6c6f77656420706572206164647265737346756e64732e726571756573743a20416d6f756e7420726571756573746564206d7573742062652067726561746572207468616e206d696e4c6f616e416d7446756e64732e736574436f6d706f756e643a20436f6d706f756e6420616464726573732068617320616c7265616479206265656e2073657446756e64732e726571756573743a20426f72726f7765722061646472657373206d757374206265206e6f6e2d7a65726f46756e64732e637265617465437573746f6d3a206d61784c6f616e447572206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c6f616e44757246756e64732e73657444656661756c74417262697465724665653a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e736574496e74657265737455706461746544656c61793a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e736574476c6f62616c496e746572657374526174654e756d657261746f723a20676c6f62616c496e746572657374526174654e756d657261746f72206973207a65726f46756e64732e726571756573743a20536563726574486173683720262053656372657448617368382073686f756c64206265206e6f6e2d7a65726f46756e64732e726571756573743a204f6e6c7920746865206c656e6465722063616e2066756c66696c6c2061206c6f616e207265717565737446756e64732e6465706f7369743a204661696c656420746f207472616e7366657220746f6b656e7346756e64732e7769746864726177546f3a20546f6b656e207472616e73666572206661696c656446756e64732e7365744d6178496e746572657374526174654e756d657261746f723a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e637265617465437573746f6d3a206d61784c6f616e416d74206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c6f616e416d7446756e64732e6372656174653a2043616e6e6f7420656e61626c6520436f6d706f756e6420617320697420686173206e6f74206265656e20636f6e6669677572656446756e64732e736574476c6f62616c496e746572657374526174653a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e656e61626c65436f6d706f756e643a2043616e6e6f7420656e61626c6520436f6d706f756e6420617320697420686173206e6f74206265656e20636f6e6669677572656446756e64732e736574476c6f62616c496e746572657374526174653a20676c6f62616c496e74657265737452617465206973207a65726f46756e64732e637265617465437573746f6d3a2066756e6445787069727920616e64206d61784c6f616e4475722063616e6e6f742065786365656420313020796561727346756e64732e676574536563726574486173686573466f724c6f616e3a204e6f7420656e6f75676820736563726574732067656e65726174656446756e64732e757064617465437573746f6d3a206d61784c6f616e447572206d7573742062652067726561746572207468616e206f7220657175616c20746f206d696e4c6f616e44757246756e64732e726571756573743a20536563726574486173683520262053656372657448617368362073686f756c64206265206e6f6e2d7a65726f46756e64732e7769746864726177546f3a204f6e6c7920746865206c656e6465722063616e20776974686472617720746f6b656e7346756e64732e7365744d6178496e746572657374526174654e756d657261746f723a206d6178496e746572657374526174654e756d657261746f72206973207a65726f46756e64732e7365744c6f616e733a204c6f616e732061646472657373206d757374206265206e6f6e2d7a65726f46756e64732e656e61626c65436f6d706f756e643a204f6e6c7920746865206c656e6465722063616e20656e61626c6520436f6d706f756e6446756e64732e73657444656661756c74417262697465724665653a2064656661756c74417262697465724665652063616e6e6f74206265206c657373207468616e202d312546756e64732e757064617465437573746f6d3a2046756e64206d757374206265206120637573746f6d2066756e6446756e64732e7769746864726177546f3a20496e73756666696369656e742062616c616e636546756e64732e7365744d61785574696c697a6174696f6e44656c74613a204f6e6c7920746865206465706c6f7965722063616e20706572666f726d207468697346756e64732e736574436f6d706f756e643a2063546f6b656e2061646472657373206d757374206265206e6f6e2d7a65726f46756e64732e726571756573743a20536563726574486173683120262053656372657448617368322073686f756c64206265206e6f6e2d7a65726f46756e64732e726571756573743a20536563726574486173683320262053656372657448617368342073686f756c64206265206e6f6e2d7a65726f46756e64732e726571756573743a204c6f616e206475726174696f6e206d7573742062652067726561746572207468616e206d696e4c6f616e447572a265627a7a7230582001ece922c650df050f16dab7220a9a0e1dcfd2986d994476756a09a8d47974bd64736f6c634300050a0032
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb480000000000000000000000000000000000000000000000000000000000000006
-----Decoded View---------------
Arg [0] : token_ (address): 0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48
Arg [1] : decimals_ (uint256): 6
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000a0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000006
Deployed Bytecode Sourcemap
62843:27474:0:-;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62843:27474:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63527:53;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63527:53:0;-1:-1:-1;;;;;63527:53:0;;:::i;:::-;;;;;;;;;;;;;;;;64189:34;;;:::i;70917:234::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70917:234:0;;:::i;81808:114::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;81808:114:0;;;;;;;:::i;:::-;;64411:32;;;:::i;63945:36::-;;;:::i;62907:80::-;;;:::i;70403:376::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70403:376:0;;:::i;64058:42::-;;;:::i;68457:412::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;68457:412:0;;:::i;76951:840::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;76951:840:0;;;;;;;:::i;63696:47::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63696:47:0;-1:-1:-1;;;;;63696:47:0;;:::i;72059:203::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72059:203:0;;:::i;72276:185::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72276:185:0;;:::i;63856:40::-;;;:::i;64477:23::-;;;:::i;85655:1272::-;;;:::i;63410:47::-;;;:::i;71165:202::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71165:202:0;;:::i;72708:106::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72708:106:0;;:::i;:::-;;;;-1:-1:-1;;;;;72708:106:0;;;;;;;;;;;;;;63087:55;;;:::i;77805:690::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;77805:690:0;;;;;;;;;;;;;;;;-1:-1:-1;;;;;77805:690:0;;:::i;60391:130::-;;;:::i;64230:41::-;;;:::i;78509:1105::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;78509:1105:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;78509:1105:0;;:::i;70041:348::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70041:348:0;;:::i;63466:50::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;63466:50:0;;;;;;;;:::i;64149:33::-;;;:::i;60350:26::-;;;:::i;63988:30::-;;;:::i;63337:66::-;;;:::i;87133:276::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;87133:276:0;;;;;;;;;:::i;64324:39::-;;;:::i;64507:29::-;;;:::i;63646:43::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63646:43:0;;:::i;:::-;;;;-1:-1:-1;;;;;63646:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73552:1277;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;73552:1277:0;;;;;;;;-1:-1:-1;;;;;73552:1277:0;;;;;;;;;;;;;;;;;:::i;63750:43::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63750:43:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;71597:112;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71597:112:0;;:::i;72475:219::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72475:219:0;;:::i;84547:848::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84547:848:0;;:::i;64025:26::-;;;:::i;72828:256::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72828:256:0;;:::i;68883:340::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;68883:340:0;;:::i;86941:178::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;86941:178:0;;;;;;;;;;;;:::i;66530:480::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66530:480:0;-1:-1:-1;;;;;66530:480:0;;:::i;70799:104::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;70799:104:0;;:::i;73299:101::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73299:101:0;;:::i;:::-;;;;;;;;;;;;;;;;;;68095:348;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;68095:348:0;;:::i;63800:47::-;;;:::i;83553:980::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;83553:980:0;;:::i;71381:202::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71381:202:0;;:::i;63213:54::-;;;:::i;71723:112::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71723:112:0;;:::i;67677:404::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;67677:404:0;;:::i;62997:82::-;;;:::i;63590:45::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;63590:45:0;-1:-1:-1;;;;;63590:45:0;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;63590:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;73414:124;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73414:124:0;-1:-1:-1;;;;;73414:124:0;;:::i;69639:388::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;69639:388:0;;:::i;83223:201::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;83223:201:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;83223:201:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;83223:201:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;-1:-1;;;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;-1:-1;83223:201:0;;-1:-1:-1;83223:201:0;-1:-1:-1;83223:201:0;:::i;67024:589::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;;;;;;67024:589:0;;;;;;;;;;:::i;63276:54::-;;;:::i;64370:34::-;;;:::i;81936:1273::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;81936:1273:0;;;;;;;;;;;-1:-1:-1;;;;;81936:1273:0;;:::i;83438:101::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;83438:101:0;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;83438:101:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;83438:101:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;83438:101:0;;-1:-1:-1;83438:101:0;-1:-1:-1;83438:101:0;:::i;85409:232::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;85409:232:0;;:::i;71849:196::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;71849:196:0;;:::i;64278:39::-;;;:::i;64107:35::-;;;:::i;73092:193::-;;;:::i;79628:2166::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;79628:2166:0;;;-1:-1:-1;;;;;79628:2166:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;79628:2166:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;79628:2166:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;79628:2166:0;;;;;;;;;;;-1:-1:-1;;;5:28;;2:2;;;46:1;43;36:12;2:2;79628:2166:0;;35:9:-1;28:4;12:14;8:25;5:40;2:2;;;58:1;55;48:12;2:2;79628:2166:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;-1:-1;;;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;-1:-1;79628:2166:0;;-1:-1:-1;79628:2166:0;-1:-1:-1;79628:2166:0;:::i;74843:2094::-;;;;;;13:3:-1;8;5:12;2:2;;;30:1;27;20:12;2:2;-1:-1;74843:2094:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;74843:2094:0;;;;;;;;;;;;;;;;;:::i;34196:111::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;34196:111:0;;;;;;;:::i;69237:388::-;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;69237:388:0;;:::i;64452:18::-;;;:::i;63903:35::-;;;:::i;63527:53::-;;;;;;;;;;;;;:::o;64189:34::-;;;;:::o;70917:234::-;70972:7;70996:11;;;:5;:11;;;;;:18;;;70992:152;;;-1:-1:-1;71024:11:0;;;;:5;:11;;;;;:22;;;71017:29;;70992:152;71090:52;63134:8;71123:17;71127:2;71131:8;;71123:3;:17::i;:::-;71117:2;:23;71090:3;:52::i;:::-;71083:59;;70992:152;70917:234;;;:::o;81808:114::-;81877:37;81888:4;81894:7;81903:10;81877;:37::i;:::-;81808:114;;:::o;64411:32::-;;;;:::o;63945:36::-;;;;:::o;62907:80::-;62959:28;62907:80;:::o;70403:376::-;70503:8;;-1:-1:-1;;;;;70503:8:0;70489:10;:22;70481:97;;;;-1:-1:-1;;;70481:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70619:28;70597:18;:50;;70589:132;;;;-1:-1:-1;;;70589:132:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70733:17;:38;70403:376::o;64058:42::-;;;;:::o;68457:412::-;68577:8;;-1:-1:-1;;;;;68577:8:0;68563:10;:22;68555:107;;;;-1:-1:-1;;;68555:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68681:33;68673:119;;;;-1:-1:-1;;;68673:119:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68803:27;:58;68457:412::o;76951:840::-;77025:5;;:54;;;-1:-1:-1;;;77025:54:0;;77044:10;77025:54;;;;77064:4;77025:54;;;;;;;;;;;;-1:-1:-1;;;;;77025:5:0;;;;:18;;:54;;;;;;;;;;;;;;;:5;;:54;;;5:2:-1;;;;30:1;27;20:12;5:2;77025:54:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77025:54:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;77025:54:0;77017:107;;;;-1:-1:-1;;;77017:107:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77139:11;;;;:5;:11;;;;;:27;;;;;;77135:557;;;77202:5;;77218:6;;77183:52;;-1:-1:-1;;;;;77202:5:0;;;;77218:6;77227:7;77183:10;:52::i;:::-;77250:19;77272:52;77276:17;77280:7;34143:8;77276:3;:17::i;:::-;77295:6;;;;;;;;;-1:-1:-1;;;;;77295:6:0;-1:-1:-1;;;;;77295:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;77295:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;77295:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;77295:28:0;77272:3;:52::i;:::-;77366:11;;;;:5;:11;;;;;:20;;;77250:74;;-1:-1:-1;77362:38:0;;77250:74;77362:3;:38::i;:::-;77339:11;;;;:5;:11;;;;;:20;;:61;77420:12;77345:4;77420:6;:12::i;:::-;77415:85;;77459:39;77463:21;;77486:11;77459:3;:39::i;:::-;77435:21;:63;77415:85;77135:557;;;;77558:11;;;;:5;:11;;;;;:19;;;77554:33;;77579:7;77554:3;:33::i;:::-;77532:11;;;;:5;:11;;;;;:19;;:55;77607:12;77538:4;77607:6;:12::i;:::-;77602:79;;77645:34;77649:20;;77671:7;77645:3;:34::i;:::-;77622:20;:57;77602:79;77707:12;77714:4;77707:6;:12::i;:::-;77702:42;;77722:20;:18;:20::i;:::-;77761:22;;;;;;;;;;;;;;;;;;;;;;;;;76951:840;;:::o;63696:47::-;;;;;;;;;;;;;:::o;72059:203::-;72111:7;72135:11;;;:5;:11;;;;;:18;;;72131:124;;;-1:-1:-1;72163:11:0;;;;:5;:11;;;;;:19;;;72156:26;;72131:124;-1:-1:-1;63051:28:0;72219:34;;72276:185;72324:7;72348:11;;;:5;:11;;;;;:18;;;72344:110;;;-1:-1:-1;72376:11:0;;;;:5;:11;;;;;:15;;;72369:22;;72344:110;-1:-1:-1;72435:17:0;;72428:24;;63856:40;;;;:::o;64477:23::-;;;;:::o;85655:1272::-;85721:76;85725:20;;85747:49;85752:21;;85775:20;:18;:20::i;:::-;85747:4;:49::i;:::-;85721:3;:76::i;:::-;85703:15;:94;85825:25;;85852:19;;85821:51;;85825:25;85821:3;:51::i;:::-;85814:3;:59;85810:1110;;;85890:24;85933:11;;85948:1;85933:16;85929:96;;85971:52;85976:11;;85989:33;85993:15;;86010:11;;85989:3;:33::i;:::-;85971:4;:52::i;:::-;85952:71;;85929:96;86064:20;;86045:16;:39;86041:665;;;86105:30;86138:43;86142:16;86160:20;;86138:3;:43::i;:::-;86105:76;;86230:147;86234:24;;86260:116;86264:27;;86293:82;86298:48;86302:19;;86323:22;86298:3;:48::i;:::-;86348:26;;86293:4;:82::i;86260:116::-;86230:3;:147::i;:::-;86200:27;:177;-1:-1:-1;86041:665:0;;;86418:30;86451:43;86455:20;;86477:16;86451:3;:43::i;:::-;86418:76;;86543:147;86547:24;;86573:116;86577:27;;86606:82;86611:48;86615:19;;86636:22;86611:3;:48::i;86606:82::-;86573:3;:116::i;:::-;86543:3;:147::i;:::-;86513:27;:177;-1:-1:-1;86041:665:0;86743:63;34179:8;86752:53;86756:27;;63322:8;86752:3;:53::i;86743:63::-;86722:18;:84;86851:3;86823:25;:31;86869:20;:39;85810:1110;85655:1272::o;63410:47::-;-1:-1:-1;;63410:47:0;:::o;71165:202::-;71220:7;71244:11;;;:5;:11;;;;;:18;;;71240:120;;;-1:-1:-1;71272:11:0;;;;:5;:11;;;;;:22;;;71265:29;;71240:120;-1:-1:-1;;;71331:27:0;;72708:106;72760:7;72787:11;;;:5;:11;;;;;:19;;;-1:-1:-1;;;;;72787:19:0;;72708:106::o;63087:55::-;63134:8;63087:55;:::o;77805:690::-;77982:12;77989:4;77982:6;:12::i;:::-;-1:-1:-1;;;;;77968:26:0;:10;-1:-1:-1;;;;;77968:26:0;;77960:88;;;;-1:-1:-1;;;77960:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63379:24;78081:33;78095:11;78108:5;78081:13;:33::i;:::-;:52;;:113;;;;-1:-1:-1;78173:3:0;63379:24;78173:21;78137:32;78151:11;78164:4;78137:13;:32::i;:::-;:57;;78081:113;78059:225;;;;-1:-1:-1;;;78059:225:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78297:11;;;;:5;:11;;;;;;;;;:22;;;:36;;;78344:22;;;:36;;;78391:19;;;;:30;;-1:-1:-1;;;;;78391:30:0;;-1:-1:-1;;;;;;78391:30:0;;;;;;;;78439:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77805:690;;;;:::o;60391:130::-;60445:7;60502:11;-1:-1:-1;;;;;60502:11:0;60391:130;;:::o;64230:41::-;;;;:::o;78509:1105::-;78891:11;;;;:5;:11;;;;;:18;;;78883:77;;;;-1:-1:-1;;;78883:77:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78994:11;78979;:26;;78971:113;;;;-1:-1:-1;;;78971:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79140:11;79103:33;79117:11;79130:5;79103:13;:33::i;:::-;:48;;79095:135;;;;-1:-1:-1;;;79095:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79241:48;79248:4;79254:11;79267;79280:8;79241:6;:48::i;:::-;-1:-1:-1;79300:11:0;;;;:5;:11;;;;;;:22;;;:36;;;;79347:22;;;:36;;;;79394:22;;;:36;;;;79441:20;;;:32;-1:-1:-1;;79484:19:0;;;:30;79525:15;;;:22;79558:28;;:48;78509:1105::o;70041:348::-;70145:8;;-1:-1:-1;;;;;70145:8:0;70131:10;:22;70123:99;;;;-1:-1:-1;;;70123:99:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70241:25;70233:95;;;;-1:-1:-1;;;70233:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70339:19;:42;70041:348::o;63466:50::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;64149:33::-;;;;:::o;60350:26::-;;;-1:-1:-1;;;;;60350:26:0;;:::o;63988:30::-;;;;:::o;63337:66::-;63379:24;63337:66;:::o;87133:276::-;87205:7;87229:10;87225:154;;87260:6;87256:75;;;-1:-1:-1;87294:3:0;63379:24;87294:21;87287:28;;87256:75;-1:-1:-1;63379:24:0;87345:22;;87225:154;-1:-1:-1;87396:5:0;87133:276;;;;;:::o;64324:39::-;;;;:::o;64507:29::-;;;-1:-1:-1;;;;;64507:29:0;;:::o;63646:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63646:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;73552:1277::-;73848:10;73746:12;73815:21;;;:9;:21;;;;;;;;;73809:28;;:5;:28;;;;;:35;73746:12;;-1:-1:-1;;;;;73809:35:0;;;:49;;73801:114;;;;-1:-1:-1;;;73801:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63379:24;73959:33;73973:11;73986:5;73959:13;:33::i;:::-;:51;:111;;;;-1:-1:-1;74049:3:0;63379:24;74049:21;74014:32;74028:11;74041:4;74014:13;:32::i;:::-;:56;73959:111;73937:223;;;;-1:-1:-1;;;73937:223:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74177:11;;-1:-1:-1;;;74177:11:0;;;;74172:125;;74199:25;;74191:104;;;;-1:-1:-1;;;74191:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74319:17;74323:9;;74334:1;74319:3;:17::i;:::-;74307:9;:29;;;74354:18;74383:11;;;:5;:11;;;;;:31;;-1:-1:-1;;;;;;74383:31:0;74404:10;74383:31;;;74307:29;;-1:-1:-1;74450:33:0;;74464:11;;74450:13;:33::i;:::-;74425:11;;;;:5;:11;;;;;:22;;:58;74519:32;74533:11;74546:4;74519:13;:32::i;:::-;74494:11;;;;:5;:11;;;;;;;;:22;;;:57;;;;74562:19;;;;:30;;-1:-1:-1;;;;;;74562:30:0;-1:-1:-1;;;;;74562:30:0;;;;;74603:5;:11;;;;;:26;;-1:-1:-1;;74640:46:0;74562:30;74640:46;;;;;;;74729:9;;74707:10;74697:21;;:9;:21;;;;;;:42;74754:11;;74750:42;;74768:22;74776:4;74782:7;74768;:22::i;:::-;74809:12;;;;;;;;;;;;;;;;;73552:1277;;;;;;;:::o;63750:43::-;;;;;;;;;;;;;;;;;;;;;;:::o;71597:112::-;71652:7;71679:11;;;:5;:11;;;;;:22;;;;71597:112::o;72475:219::-;72536:7;72560:11;;;:5;:11;;;;;:18;;;72556:131;;;-1:-1:-1;72588:11:0;;;;:5;:11;;;;;:28;;;72581:35;;72556:131;-1:-1:-1;62959:28:0;72653:32;;84547:848;84614:11;;;;:5;:11;;;;;:27;;;;;;84606:91;;;;-1:-1:-1;;;84606:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84730:12;84737:4;84730:6;:12::i;:::-;-1:-1:-1;;;;;84716:26:0;:10;-1:-1:-1;;;;;84716:26:0;;84708:98;;;;-1:-1:-1;;;84708:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84841:5;;:30;;;-1:-1:-1;;;84841:30:0;;84865:4;84841:30;;;;;;84817:21;;-1:-1:-1;;;;;84841:5:0;;:15;;:30;;;;;;;;;;;;;;:5;:30;;;5:2:-1;;;;30:1;27;20:12;5:2;84841:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84841:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84841:30:0;84903:6;;;84912:11;;;:5;84841:30;84912:11;;;;:20;;;84841:30;;-1:-1:-1;84882:51:0;;-1:-1:-1;;;;;84903:6:0;;;;84882:12;:51::i;:::-;84967:5;;:30;;;-1:-1:-1;;;84967:30:0;;84991:4;84967:30;;;;;;84944:20;;-1:-1:-1;;;;;84967:5:0;;:15;;:30;;;;;;;;;;;;;;:5;:30;;;5:2:-1;;;;30:1;27;20:12;5:2;84967:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84967:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84967:30:0;;-1:-1:-1;85008:21:0;85032:32;84967:30;85050:13;85032:3;:32::i;:::-;85008:56;;85098:40;85102:20;;85124:13;85098:3;:40::i;:::-;85075:20;:63;85177:21;;85200:11;;;;:5;:11;;;;;:20;;;85173:48;;85177:21;85173:3;:48::i;:::-;85149:21;:72;;;85262:5;85232:11;;;:5;:11;;;;;;;;:35;;-1:-1:-1;;85232:35:0;;;85278:5;:11;;;;;:20;;;:24;;;;85313:19;;;;:35;;;85366:21;;;;;;;;;;;;;;;;;;84547:848;;;;:::o;64025:26::-;;;;:::o;72828:256::-;72875:7;72899:11;;;:5;:11;;;;;:27;;;;;;72895:182;;;72955:11;;;;:5;:11;;;;;;;;:20;;;72977:6;;:28;;-1:-1:-1;;;72977:28:0;;;;72950:56;;72955:20;;-1:-1:-1;;;;;72977:6:0;;;;:26;;:28;;;;;72955:11;72977:28;;;;;;;;:6;:28;;;5:2:-1;;;;30:1;27;20:12;5:2;72977:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;72977:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;72977:28:0;72950:4;:56::i;72895:182::-;-1:-1:-1;73046:11:0;;;;:5;:11;;;;;:19;;;73039:26;;68883:340;68985:8;;-1:-1:-1;;;;;68985:8:0;68971:10;:22;68963:98;;;;-1:-1:-1;;;68963:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69080:24;69072:92;;;;-1:-1:-1;;;69072:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69175:18;:40;68883:340::o;86941:178::-;87034:7;87061:50;87065:36;87070:7;87079:21;87084:5;87091:8;87079:4;:21::i;:::-;87065:4;:36::i;:::-;87103:7;87061:3;:50::i;:::-;87054:57;86941:178;-1:-1:-1;;;;86941:178:0:o;66530:480::-;66604:8;;-1:-1:-1;;;;;66604:8:0;66590:10;:22;66582:85;;;;-1:-1:-1;;;66582:85:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66694:5;;-1:-1:-1;;;;;66694:5:0;66686:28;66678:91;;;;-1:-1:-1;;;66678:91:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;66788:29:0;;66780:88;;;;-1:-1:-1;;;66780:88:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66879:5;:14;;-1:-1:-1;;;;;;66879:14:0;-1:-1:-1;;;;;66879:14:0;;;;;;;;;66912:5;;:44;;;-1:-1:-1;;;66912:44:0;;;;;;;;;-1:-1:-1;;66912:44:0;;;;;:5;;;:13;;:44;;;;;;;;;;;;;;;-1:-1:-1;66912:5:0;:44;;;5:2:-1;;;;30:1;27;20:12;5:2;66912:44:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;66912:44:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;66912:44:0;66904:98;;;;-1:-1:-1;;;66904:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66530:480;:::o;70799:104::-;70850:7;70877:11;;;:5;:11;;;;;:18;-1:-1:-1;;;;;70877:18:0;;70799:104::o;73299:101::-;73350:4;73374:11;;;:5;:11;;;;;:18;;;;73299:101::o;68095:348::-;68199:8;;-1:-1:-1;;;;;68199:8:0;68185:10;:22;68177:99;;;;-1:-1:-1;;;68177:99:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68295:25;68287:95;;;;-1:-1:-1;;;68287:95:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68393:19;:42;68095:348::o;63800:47::-;;;;:::o;83553:980::-;83619:11;;-1:-1:-1;;;83619:11:0;;;;83611:98;;;;-1:-1:-1;;;83611:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83728:11;;;;:5;:11;;;;;:27;;;;;;:36;83720:98;;;;-1:-1:-1;;;83720:98:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83851:12;83858:4;83851:6;:12::i;:::-;-1:-1:-1;;;;;83837:26:0;:10;-1:-1:-1;;;;;83837:26:0;;83829:96;;;;-1:-1:-1;;;83829:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83961:6;;:31;;;-1:-1:-1;;;83961:31:0;;83986:4;83961:31;;;;;;83936:22;;-1:-1:-1;;;;;83961:6:0;;:16;;:31;;;;;;;;;;;;;;:6;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;83961:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;83961:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;83961:31:0;84022:5;;84038:6;;84022:5;84047:11;;;:5;83961:31;84047:11;;;;:19;;;83961:31;;-1:-1:-1;84003:64:0;;-1:-1:-1;;;;;84022:5:0;;;;84038:6;;;;84003:10;:64::i;:::-;84102:6;;:31;;;-1:-1:-1;;;84102:31:0;;84127:4;84102:31;;;;;;84078:21;;-1:-1:-1;;;;;84102:6:0;;:16;;:31;;;;;;;;;;;;;;:6;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;84102:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;84102:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;84102:31:0;;-1:-1:-1;84144:22:0;84169:34;84102:31;84188:14;84169:3;:34::i;:::-;84241:20;;84263:11;;;;:5;:11;;;;;:19;;;84144:59;;-1:-1:-1;84237:46:0;;:3;:46::i;:::-;84214:20;:69;84322:21;;84318:42;;84345:14;84318:3;:42::i;:::-;84294:21;:66;;;84371:11;;;;:5;:11;;;;;;;;:34;;-1:-1:-1;;84371:34:0;;;;;84416:5;:11;;;;;:19;;;:23;;;;84450:20;;;;:37;;;84505:20;;;;;;;;;;;;;;;;;;83553:980;;;;:::o;71381:202::-;71436:7;71460:11;;;:5;:11;;;;;:18;;;71456:120;;;-1:-1:-1;71488:11:0;;;;:5;:11;;;;;:22;;;71481:29;;71456:120;-1:-1:-1;63260:7:0;71547:27;;63213:54;63260:7;63213:54;:::o;71723:112::-;71778:7;71805:11;;;:5;:11;;;;;;;;:22;;;71723:112::o;67677:404::-;67795:8;;-1:-1:-1;;;;;67795:8:0;67781:10;:22;67773:106;;;;-1:-1:-1;;;67773:106:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67898:32;67890:116;;;;-1:-1:-1;;;67890:116:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68017:26;:56;67677:404::o;62997:82::-;63051:28;62997:82;:::o;63590:45::-;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;63590:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;73414:124::-;-1:-1:-1;;;;;73504:19:0;73477:7;73504:19;;;:12;:19;;;;;:26;;73414:124::o;69639:388::-;69753:8;;-1:-1:-1;;;;;69753:8:0;69739:10;:22;69731:104;;;;-1:-1:-1;;;69731:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69854:30;69846:110;;;;-1:-1:-1;;;69846:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69967:24;:52;69639:388::o;83223:201::-;83300:6;83295:122;83312:24;;;83295:122;;;83371:10;83358:24;;;;:12;:24;;;;;83388:13;;83402:1;83388:16;;;;;;;27:10:-1;;39:1;23:18;;;45:23;;-1:-1;83358:47:0;;;83388:16;83358:47;;;;83388:16;;;;;;;;;83358:47;;;;;;-1:-1:-1;83338:3:0;83295:122;;;;83223:201;;:::o;67024:589::-;67134:8;;-1:-1:-1;;;;;67134:8:0;67120:10;:22;67112:99;;;;-1:-1:-1;;;67112:99:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67231:11;;-1:-1:-1;;;67231:11:0;;;;67230:12;67222:81;;;;-1:-1:-1;;;67222:81:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;67322:30:0;;67314:93;;;;-1:-1:-1;;;67314:93:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;67426:26:0;;67418:94;;;;-1:-1:-1;;;67418:94:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67523:6;:16;;:6;67550:26;;-1:-1:-1;;;;;67550:26:0;;;-1:-1:-1;;;;;;67550:26:0;;;;;;;-1:-1:-1;;;;67523:16:0;;;;;;;;;;67587:18;-1:-1:-1;;;67587:18:0;;;67024:589::o;63276:54::-;63322:8;63276:54;:::o;64370:34::-;;;;:::o;81936:1273::-;82047:12;82054:4;82047:6;:12::i;:::-;-1:-1:-1;;;;;82033:26:0;:10;-1:-1:-1;;;;;82033:26:0;;82025:92;;;;-1:-1:-1;;;82025:92:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82153:7;82136:13;82144:4;82136:7;:13::i;:::-;:24;;82128:75;;;;-1:-1:-1;;;82128:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82218:11;;;;:5;:11;;;;;:27;;;;;;82214:883;;;82287:6;;:31;;;-1:-1:-1;;;82287:31:0;;82312:4;82287:31;;;;;;82262:22;;-1:-1:-1;;;;;82287:6:0;;:16;;:31;;;;;;;;;;;;;;:6;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;82287:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;82287:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;82287:31:0;82358:6;;82287:31;;-1:-1:-1;82333:42:0;;-1:-1:-1;;;;;82358:6:0;82367:7;82333:16;:42::i;:::-;82414:6;;:31;;;-1:-1:-1;;;82414:31:0;;82439:4;82414:31;;;;;;82390:21;;-1:-1:-1;;;;;82414:6:0;;:16;;:31;;;;;;;;;;;;;;:6;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;82414:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;82414:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;82414:31:0;;-1:-1:-1;82460:22:0;82485:34;82489:14;82414:31;82485:3;:34::i;:::-;82561:11;;;;:5;:11;;;;;:20;;;82460:59;;-1:-1:-1;82557:41:0;;82460:59;82557:3;:41::i;:::-;82534:11;;;;:5;:11;;;;;;;;:20;;:64;;;;82621:5;;:35;;-1:-1:-1;;;82621:35:0;;-1:-1:-1;;;;;82621:35:0;;;;;;;;;;;;;;;:5;;;;;:14;;:35;;;;;82534:11;82621:35;;;;;;;:5;:35;;;5:2:-1;;;;30:1;27;20:12;5:2;82621:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;82621:35:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;82621:35:0;82613:87;;;;-1:-1:-1;;;82613:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82720:12;82727:4;82720:6;:12::i;:::-;82715:88;;82759:42;82763:21;;82786:14;82759:3;:42::i;:::-;82735:21;:66;82715:88;82214:883;;;;;;82861:11;;;;:5;:11;;;;;:19;;;82857:33;;82882:7;82857:3;:33::i;:::-;82835:11;;;;:5;:11;;;;;;;;:19;;:55;;;;82913:5;;:35;;-1:-1:-1;;;82913:35:0;;-1:-1:-1;;;;;82913:35:0;;;;;;;;;;;;;;;:5;;;;;:14;;:35;;;;;82835:11;82913:35;;;;;;;:5;:35;;;5:2:-1;;;;30:1;27;20:12;5:2;82913:35:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;82913:35:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;82913:35:0;82905:87;;;;-1:-1:-1;;;82905:87:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83012:12;83019:4;83012:6;:12::i;:::-;83007:79;;83050:34;83054:20;;83076:7;83050:3;:34::i;:::-;83027:20;:57;83007:79;83112:12;83119:4;83112:6;:12::i;:::-;83107:42;;83127:20;:18;:20::i;:::-;83166:35;;;;;;;;;;;;-1:-1:-1;;;;;83166:35:0;;;;;;;;;;;;;;;;;81936:1273;;;:::o;83438:101::-;83510:10;83502:19;;;;:7;:19;;;;;:29;;83524:7;;83502:29;:::i;85409:232::-;85505:5;;-1:-1:-1;;;;;85505:5:0;85483:10;:28;85475:108;;;;-1:-1:-1;;;85475:108:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85608:25;85612:11;;85625:7;85608:3;:25::i;:::-;85594:11;:39;-1:-1:-1;85409:232:0:o;71849:196::-;71902:7;71926:11;;;:5;:11;;;;;:18;;;71922:116;;;-1:-1:-1;71954:11:0;;;;:5;:11;;;;;:20;;;71947:27;;71922:116;-1:-1:-1;72018:18:0;;72011:25;;64278:39;;;;:::o;64107:35::-;;;;:::o;73092:193::-;73162:11;;73138:7;;-1:-1:-1;;;73162:11:0;;;;73158:120;;;73197:6;;;;;;;;;-1:-1:-1;;;;;73197:6:0;-1:-1:-1;;;;;73197:26:0;;:28;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;73197:28:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;73197:28:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;73197:28:0;;-1:-1:-1;73190:35:0;;73158:120;-1:-1:-1;73265:1:0;73258:8;;79628:2166;80034:17;80086:12;80093:4;80086:6;:12::i;:::-;-1:-1:-1;;;;;80072:26:0;:10;-1:-1:-1;;;;;80072:26:0;;80064:96;;;;-1:-1:-1;;;80064:96:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80190:13;80198:4;80190:7;:13::i;:::-;80179:7;:24;;80171:72;;;;-1:-1:-1;;;80171:72:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80273:16;80284:4;80273:10;:16::i;:::-;80262:7;:27;;80254:103;;;;-1:-1:-1;;;80254:103:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80387:16;80398:4;80387:10;:16::i;:::-;80376:7;:27;;80368:100;;;;-1:-1:-1;;;80368:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80499:16;80510:4;80499:10;:16::i;:::-;80487:8;:28;;80479:101;;;;-1:-1:-1;;;80479:101:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80611:26;80615:16;80626:4;80615:10;:16::i;:::-;80633:3;80611;:26::i;:::-;80599:8;:38;;:70;;;;;80653:16;80664:4;80653:10;:16::i;:::-;80641:8;:28;;80599:70;80591:151;;;;-1:-1:-1;;;80591:151:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;80761:23:0;;80753:84;;;;-1:-1:-1;;;80753:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80856:16;;:30;;;;:64;;-1:-1:-1;80890:16:0;;;;:30;;80856:64;80848:136;;;;-1:-1:-1;;;80848:136:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81003:16;;;;:30;;;;:64;;-1:-1:-1;81037:16:0;;;;:30;;81003:64;80995:136;;;;-1:-1:-1;;;80995:136:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81150:16;;;;:30;;;;:64;;-1:-1:-1;81184:16:0;;;;:30;;81150:64;81142:136;;;;-1:-1:-1;;;81142:136:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81297:16;;;;:30;;;;:64;;-1:-1:-1;81331:16:0;;;;:30;;81297:64;81289:136;;;;-1:-1:-1;;;81289:136:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81450:78;81461:4;81467:9;81478:7;81487:11;81500:8;81510:17;81450:10;:78::i;:::-;81438:90;;81539:71;81559:4;81565:9;81576:13;81539:71;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;81:16;;74:27;;;;-1:-1;;81539:71:0;;;;137:4:-1;81539:71:0;;;;;;;;;;;;;;;;;;-1:-1:-1;81591:8:0;;;;;;81539:71;;81591:8;;;;81539:71;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;;81539:71:0;;;;137:4:-1;81539:71:0;;;;;;;;;;;;;;;;;;-1:-1:-1;81601:8:0;;-1:-1:-1;81601:8:0;;;;81539:71;;81601:8;;;;81539:71;1:33:-1;99:1;81:16;;74:27;;;;-1:-1;81539:19:0;;-1:-1:-1;;;81539:71:0:i;:::-;81621:40;81647:4;81653:7;81621:25;:40::i;:::-;81672:5;;:21;;;-1:-1:-1;;;81672:21:0;;;;;;;;;;-1:-1:-1;;;;;81672:5:0;;;;:10;;:21;;;;;:5;;:21;;;;;;;;:5;;:21;;;5:2:-1;;;;30:1;27;20:12;5:2;81672:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;-1:-1;;81711:75:0;;;;;;-1:-1:-1;;;;;81711:75:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;81711:75:0;;;;;;;-1:-1:-1;81711:75:0;79628:2166;;;;;;;;;;;;;:::o;74843:2094::-;75356:10;75254:12;75323:21;;;:9;:21;;;;;;;;;75317:28;;:5;:28;;;;;:35;75254:12;;-1:-1:-1;;;;;75317:35:0;;;:49;;75309:114;;;;-1:-1:-1;;;75309:114:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63379:24;75467:33;75481:11;75494:5;75467:13;:33::i;:::-;:51;:111;;;;-1:-1:-1;75557:3:0;63379:24;75557:21;75522:32;75536:11;75549:4;75522:13;:32::i;:::-;:56;75467:111;75445:229;;;;-1:-1:-1;;;75445:229:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75709:11;75694;:26;;75686:113;;;;-1:-1:-1;;;75686:113:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75855:11;75818:33;75832:11;75845:5;75818:13;:33::i;:::-;:48;;75810:135;;;;-1:-1:-1;;;75810:135:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75963:11;;-1:-1:-1;;;75963:11:0;;;;75958:131;;75985:25;;75977:110;;;;-1:-1:-1;;;75977:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76111:17;76115:9;;76126:1;76111:3;:17::i;:::-;76099:9;:29;;;;76154:9;;76146:18;;76139:25;;76196:10;76175:5;:11;76181:4;76175:11;;;;;;;;;;;:18;;;:31;;;;;-1:-1:-1;;;;;76175:31:0;;;;;-1:-1:-1;;;;;76175:31:0;;;;;;76242:11;76217:5;:11;76223:4;76217:11;;;;;;;;;;;:22;;:36;;;;76289:11;76264:5;:11;76270:4;76264:11;;;;;;;;;;;:22;;:36;;;;76336:11;76311:5;:11;76317:4;76311:11;;;;;;;;;;;:22;;:36;;;;76383:33;76397:11;76410:5;76383:13;:33::i;:::-;76358:11;;;;:5;:11;;;;;:22;;:58;76452:32;76466:11;76479:4;76452:13;:32::i;:::-;76427:11;;;;:5;:11;;;;;;;;:22;;;:57;;;;76495:20;;;;:32;;;76538:19;;;;:30;;;76579:15;;;;:22;;;76612:28;;;:48;;;76671:19;;;;:30;;-1:-1:-1;;;;;;76671:30:0;-1:-1:-1;;;;;76671:30:0;;;;;76712:11;;;;;:25;;-1:-1:-1;;76712:25:0;-1:-1:-1;76712:25:0;-1:-1:-1;;76748:46:0;76671:30;76748:46;;;;;;;76837:9;;76815:10;76805:21;;;;;;;;:42;76862:11;;76858:42;;76876:22;76884:4;76890:7;76876;:22::i;:::-;76917:12;;;;;;;;;;;;;;;;;74843:2094;;;;;;;;;;;;;;:::o;34196:111::-;34247:6;34108:7;34270:23;34274:9;34278:1;34281;34274:3;:9::i;:::-;34291:1;34108:7;34285;;34270:3;:23::i;:::-;:29;;;;;;;34196:111;-1:-1:-1;;;34196:111:0:o;69237:388::-;69351:8;;-1:-1:-1;;;;;69351:8:0;69337:10;:22;69329:104;;;;-1:-1:-1;;;69329:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69452:30;69444:110;;;;-1:-1:-1;;;69444:110:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69565:24;:52;69237:388::o;64452:18::-;;;-1:-1:-1;;;;;64452:18:0;;:::o;63903:35::-;;;;:::o;33310:104::-;33394:5;;;33389:16;;;;33381:25;;;;;33544:113;33596:6;33627:1;33623;:5;33615:14;;;;;;33648:1;33644;:5;;;;61478:462;61564:19;61576:6;61564:11;:19::i;:::-;61666:30;;;-1:-1:-1;;;61666:30:0;;61690:4;61666:30;;;;;;61632:5;;61594:20;;-1:-1:-1;;;;;61666:15:0;;;;;:30;;;;;;;;;;;;;;:15;:30;;;5:2:-1;;;;30:1;27;20:12;5:2;61666:30:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61666:30:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;61666:30:0;;-1:-1:-1;61711:20:0;;;61707:73;;;-1:-1:-1;61760:8:0;61707:73;61831:6;61849:37;61861:5;61868:9;61831:6;61849:11;:37::i;:::-;61904:6;-1:-1:-1;;;;;61904:11:0;;61916:9;61904:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61904:22:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61904:22:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;61904:22:0;:27;61897:35;;;;61478:462;;;;;;:::o;33420:118::-;33472:6;33499;;;:30;;-1:-1:-1;;33514:5:0;;;33528:1;33523;33514:5;33523:1;33509:15;;;;;:20;33499:30;33491:39;;;;;33200:104;33284:5;;;33279:16;;;;33271:25;;;;;34313:113;34366:6;34143:8;34389:23;34393:9;34397:1;34400;34393:3;:9::i;:::-;34410:1;34143:8;34404:7;;34785:111;34838:6;34887:1;34861:23;34865:11;34869:1;34179:8;34865:3;:11::i;:::-;34882:1;34878;:5;;33665:100;33717:6;33748:1;33743;:6;;:14;;33756:1;33743:14;33736:21;33665:100;-1:-1:-1;;;33665:100:0:o;33771:::-;33823:6;33854:1;33849;:6;;:14;;33862:1;33849:14;;62455:381;62602:31;;;-1:-1:-1;;;62602:31:0;;62627:4;62602:31;;;;;;62570:6;;62529:22;;-1:-1:-1;;;;;62602:16:0;;;;;:31;;;;;;;;;;;;;;:16;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;62602:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62602:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62602:31:0;;-1:-1:-1;62648:18:0;;;62644:69;;;-1:-1:-1;62692:9:0;62644:69;62723:35;62735:6;62743;62751;62723:11;:35::i;:::-;62777:6;-1:-1:-1;;;;;62777:13:0;;62791:6;62777:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62777:21:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62777:21:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62777:21:0;:26;62769:59;;;;;-1:-1:-1;;;62769:59:0;;;;;;;;;;;;-1:-1:-1;;;62769:59:0;;;;;;;;;;;;;;;62455:381;;;;:::o;34994:267::-;35047:6;35074:1;35070;:5;:20;;34179:8;35070:20;;;35083:1;35070:20;35066:24;-1:-1:-1;35113:1:0;35108:6;;;;35103:151;35116:6;;35103:151;;35151:10;35156:1;35159;35151:4;:10::i;:::-;35147:14;-1:-1:-1;35186:1:0;35182;:5;:10;35178:65;;35217:10;35222:1;35225;35217:4;:10::i;:::-;35213:14;;35178:65;35129:1;35124:6;;;;35103:151;;34432:113;34485:6;34179:8;34508:23;34512:9;34516:1;34519;34512:3;:9::i;:::-;34529:1;34179:8;34523:7;;61954:487;62072:6;62090:35;62072:6;62110;62072;62090:11;:35::i;:::-;62150:31;;;-1:-1:-1;;;62150:31:0;;62175:4;62150:31;;;;;;62136:11;;-1:-1:-1;;;;;62150:16:0;;;;;:31;;;;;;;;;;;;;;;:16;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;62150:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62150:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62150:31:0;62226:28;;;-1:-1:-1;;;62226:28:0;;;;62150:31;;-1:-1:-1;62192:18:0;;62213:42;;62150:31;;-1:-1:-1;;;;;62226:26:0;;;;;:28;;;;;62150:31;;62226:28;;;;;;;62192:18;62226:26;:28;;;5:2:-1;;;;30:1;27;20:12;62213:42:0;62192:63;;62286:8;62270:13;:24;62266:81;;;-1:-1:-1;62327:8:0;62266:81;62365:6;-1:-1:-1;;;;;62365:23:0;;62389:13;62365:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;62365:38:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;62365:38:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;62365:38:0;:43;62357:76;;;;;-1:-1:-1;;;62357:76:0;;;;;;;;;;;;-1:-1:-1;;;62357:76:0;;;;;;;;;;;;;;;61954:487;;;;;:::o;87423:757::-;87685:5;;:487;;;;;;;;;-1:-1:-1;;;;;87685:487:0;;;;;87643:17;;87685:5;;:12;;87712:3;:14;;;87685:487;;;87753:12;87760:4;87753:6;:12::i;:::-;-1:-1:-1;;;;;87685:487:0;;;;;87767:11;;;;:5;87685:487;87767:11;;;;;;;;:19;;;;;;87685:487;;;;;;;;;;;;;;;;;;;;87847:47;87821:7;87869:14;87773:4;87869:8;:14::i;:::-;87885:8;87847:12;:47::i;:::-;87685:487;;;;87913:46;87926:7;87935:13;87943:4;87935:7;:13::i;87913:46::-;87685:487;;;;87978:42;87991:7;88000:9;88004:4;88000:3;:9::i;87978:42::-;87685:487;;;;88039:11;87685:487;;;;88069:22;88086:4;88069:16;:22::i;:::-;87685:487;;;;;;;;;-1:-1:-1;;;;;;87685:487:0;;;;;;;;;;;;;88157:4;;87685:487;;;;;;;-1:-1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;87685:487:0;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;87685:487:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;87685:487:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;87685:487:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;87685:487:0;;87423:757;-1:-1:-1;;;;;;;87423:757:0:o;88194:609::-;88431:5;;:364;;;;;;;;;88488:16;;88431:364;;88488:16;88506;;;;88431:364;;;;88524:16;;;;88431:364;;;;;88542:16;;;;88431:364;;;;;;;;;;;88577:16;;;;88431:364;;88595:16;;;;88431:364;;;;-1:-1:-1;;;;;88431:5:0;;;;:21;;88467:4;;88431:364;;;;88488:16;88627:1;88613:16;;;;88431:364;;;;88631:13;88645:1;88631:16;;;;;;;;;;;88431:364;;88664:37;88687:13;88695:4;88687:7;:13::i;:::-;88664:22;:37::i;:::-;88716:8;88739;88762:7;:22;88770:13;88778:4;88770:7;:13::i;:::-;-1:-1:-1;;;;;88762:22:0;-1:-1:-1;;;;;88762:22:0;;;;;;;;;;;;88431:364;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;88431:364:0;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;88431:364:0;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;88431:364:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;88431:364:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;88431:364:0;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;88431:364:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;88431:364:0;;;;;;;;-1:-1:-1;;88431:364:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;88431:364:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;88431:364:0;;;;88194:609;;;;;:::o;88817:901::-;88906:11;;;;:5;:11;;;;;:27;;;;;;88902:679;;;88975:6;;:31;;;-1:-1:-1;;;88975:31:0;;89000:4;88975:31;;;;;;88950:22;;-1:-1:-1;;;;;88975:6:0;;:16;;:31;;;;;;;;;;;;;;:6;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;88975:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;88975:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;88975:31:0;89046:6;;88975:31;;-1:-1:-1;89021:42:0;;-1:-1:-1;;;;;89046:6:0;89055:7;89021:16;:42::i;:::-;89102:6;;:31;;;-1:-1:-1;;;89102:31:0;;89127:4;89102:31;;;;;;89078:21;;-1:-1:-1;;;;;89102:6:0;;:16;;:31;;;;;;;;;;;;;;:6;:31;;;5:2:-1;;;;30:1;27;20:12;5:2;89102:31:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;89102:31:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;89102:31:0;;-1:-1:-1;89148:22:0;89173:34;89177:14;89102:31;89173:3;:34::i;:::-;89249:11;;;;:5;:11;;;;;:20;;;89148:59;;-1:-1:-1;89245:41:0;;89148:59;89245:3;:41::i;:::-;89222:11;;;;:5;:11;;;;;:20;;:64;89306:12;89228:4;89306:6;:12::i;:::-;89301:88;;89345:42;89349:21;;89372:14;89345:3;:42::i;:::-;89321:21;:66;89301:88;88902:679;;;;;;89447:11;;;;:5;:11;;;;;:19;;;89443:33;;89468:7;89443:3;:33::i;:::-;89421:11;;;;:5;:11;;;;;:19;;:55;89496:12;89427:4;89496:6;:12::i;:::-;89491:79;;89534:34;89538:20;;89560:7;89534:3;:34::i;:::-;89511:20;:57;89491:79;89596:12;89603:4;89596:6;:12::i;:::-;89591:120;;89639:25;89643:11;;89656:7;89639:3;:25::i;:::-;89625:11;:39;89679:20;:18;:20::i;60529:567::-;60586:24;60630:23;:21;:23::i;:::-;60692:34;;;-1:-1:-1;;;60692:34:0;;60720:4;60692:34;;;;;;60586:68;;-1:-1:-1;60665:24:0;;-1:-1:-1;;;;;60692:19:0;;;;;:34;;;;;-1:-1:-1;;60692:34:0;;;;;;;:19;:34;;;5:2:-1;;;;30:1;27;20:12;5:2;60692:34:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;60692:34:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;60692:34:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;60692:34:0;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;-1:-1;60692:34:0;;-1:-1:-1;60737:14:0;;-1:-1:-1;60737:14:0;;-1:-1:-1;;;60770:145:0;60791:7;:14;60787:1;:18;60770:145;;;60845:6;-1:-1:-1;;;;;60831:20:0;:7;60839:1;60831:10;;;;;;;;;;;;;;-1:-1:-1;;;;;60831:20:0;;60827:77;;;60884:4;60872:16;;60827:77;60807:3;;60770:145;;;;60930:9;60925:164;;60983:16;;;60997:1;60983:16;;;;;;;;;60956:24;;60983:16;;;;;;105:10:-1;60983:16:0;88:34:-1;136:17;;-1:-1;60983:16:0;60956:43;;61027:6;61014:7;61022:1;61014:10;;;;;;;;-1:-1:-1;;;;;61014:19:0;;;:10;;;;;;;;;;:19;;;;61048:29;;-1:-1:-1;;;61048:29:0;;;;;;;;;;;;;;;;:20;;;;;;61069:7;;61048:29;;;;;;;;;;;;;;;;8:100:-1;33:3;30:1;27:10;8:100;;;90:11;;;84:18;71:11;;;64:39;52:2;45:10;8:100;;;12:14;61048:29:0;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;61048:29:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61048:29:0;;;;;;39:16:-1;36:1;17:17;2:54;101:4;61048:29:0;80:15:-1;;;-1:-1;;76:31;65:43;;120:4;113:20;13:2;5:11;;2:2;;;29:1;26;19:12;2:2;61048:29:0;;;;;;-1:-1:-1;;;14:3;11:20;8:2;;;44:1;41;34:12;8:2;62:21;;123:4;114:14;;138:31;;;135:2;;;182:1;179;172:12;135:2;219:3;213:10;331:9;325:2;311:12;307:21;289:16;285:44;282:59;-1:-1;;;247:12;244:29;233:116;230:2;;;362:1;359;352:12;230:2;-1:-1;;;;;;;60529:567:0;;;;:::o;61110:315::-;61276:42;;;-1:-1:-1;;;61276:42:0;;61308:4;61276:42;;;;-1:-1:-1;;;;;61276:42:0;;;;;;;;;61237:5;;61191:28;;61276:23;;;;;;:42;;;;;;;;;;;;;;;:23;:42;;;5:2:-1;;;;30:1;27;20:12;5:2;61276:42:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;61276:42:0;;;;;;;13:2:-1;8:3;5:11;2:2;;;29:1;26;19:12;2:2;-1:-1;61276:42:0;;-1:-1:-1;61333:23:0;;;61329:89;;;61373:33;;;-1:-1:-1;;;61373:33:0;;-1:-1:-1;;;;;61373:33:0;;;;;;;-1:-1:-1;;;61373:33:0;;;;;;:21;;;;;;:33;;;;;-1:-1:-1;;61373:33:0;;;;;;;;-1:-1:-1;61373:21:0;:33;;;5:2:-1;;;;30:1;27;20:12;89732:582:0;89796:17;;:::i;:::-;-1:-1:-1;;;;;89855:22:0;;;;;;:15;:22;;;;;;89851:30;;89879:1;89851:3;:30::i;:::-;-1:-1:-1;;;;;89826:22:0;;;;;;:15;:22;;;;;:55;;;89900:24;89842:5;89900:17;:24::i;:::-;:50;;89892:121;;;;-1:-1:-1;;;89892:121:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90024:282;;;;;;;;-1:-1:-1;;;;;90046:19:0;;-1:-1:-1;90046:19:0;;;:12;:19;;;;;;;90070:15;:22;;;;;;;90024:282;;;;90066:30;;90094:1;90066:3;:30::i;:::-;90046:51;;;;;;;;;;;;;;;;;;;;90024:282;;-1:-1:-1;;;;;90112:19:0;;;;:12;:19;;;;;;90136:15;:22;;;;;;;;90024:282;;;;;90132:30;;:3;:30::i;:::-;90112:51;;;;;;;;;;;;;;;;;;;;90024:282;;-1:-1:-1;;;;;90178:19:0;;;;:12;:19;;;;;;;90202:15;:22;;;;;90024:282;;;;;90198:30;;:3;:30::i;:::-;90178:51;;;;;;;;;;;;;;;;;;;;90024:282;;-1:-1:-1;;;;;90244:19:0;;;;:12;:19;;;;;;90268:15;:22;;;;;90024:282;;;90264:30;;90292:1;90264:3;:30::i;:::-;90244:51;;;;;;;;;;;;;;;;90024:282;;;;;89732:582;;;:::o;62843:27474::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;62843:27474:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62843:27474:0;;;-1:-1:-1;62843:27474:0;:::i;:::-;;;:::o;:::-;;;;;;;;;;;29:2:-1;21:6;17:15;117:4;105:10;97:6;88:34;-1:-1;62843:27474:0;;;-1:-1:-1;;62843:27474:0:o;:::-;;;;;;;;;;;;;;;;;
Swarm Source
bzzr://01ece922c650df050f16dab7220a9a0e1dcfd2986d994476756a09a8d47974bd
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.