Transactions
Token Transfers
Tokens
Internal Transactions
Coin Balance History
Logs
Code
Read Contract
Write Contract
Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
This contract has been verified via Sourcify.
View contract in Sourcify repository
- Contract name:
- SCADAFuturesFactory
- Optimization enabled
- true
- Compiler version
- v0.8.20+commit.a1b79de6
- Optimization runs
- 200
- EVM Version
- paris
- Verified at
- 2026-04-02T22:16:15.962034Z
Constructor Arguments
000000000000000000000000915b4145e169ce7352936e88546ac8667d22723c000000000000000000000000915b4145e169ce7352936e88546ac8667d22723c0000000000000000000000000000000000000000000000000000000000000019
Arg [0] (address) : 0x915b4145e169ce7352936e88546ac8667d22723c
Arg [1] (address) : 0x915b4145e169ce7352936e88546ac8667d22723c
Arg [2] (uint256) : 25
SCADAFuturesFactory.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title SCADAFuturesFactory
* @notice Permissionless factory for physically-settled SCADA/PLS futures on PulseChain.
*
* Each contract represents an obligation to swap exactly contractSize SCADA
* for PLS at a pre-agreed futuresPrice on a standardized monthly expiry date.
* contractSize is owner-configurable (100–100,000 SCADA) and snapshotted into
* each Future at creation — changes do not affect existing contracts.
*
* Roles
* ─────
* SHORT (maker) — deposits contractSize SCADA as collateral.
* Sets futuresPrice (PLS wei per 1 SCADA) and picks an approved expiry.
* Can cancel() while the contract is still OPEN (unfilled).
*
* LONG (taker) — deposits the full PLS notional (contractSize × futuresPrice / 1e18).
* Locks both parties in; no exit until expiry.
*
* Settlement
* ──────────
* Anyone may call settle() after expiry.
* SHORT receives the PLS notional via pendingWithdrawals.
* LONG receives contractSize SCADA via pendingScadaWithdrawals.
* Both call withdraw() / withdrawScada() to collect.
*
* Expiry dates
* ────────────
* The owner maintains a whitelist of valid expiry timestamps (monthly dates).
* SHORTs may only create contracts for approved future expiries.
* Removing an expiry from the whitelist does not affect existing contracts.
*
* Fee
* ───
* Fee is taker-only: only LONG pays a fee at accept().
* - SHORT (maker) pays no fee — creating a contract is free beyond SCADA collateral.
* - LONG (taker) pays notional × fee / 10000 PLS at accept() (on top of the notional).
* Fee is snapshotted per contract at creation and cannot change mid-life.
* Hard-capped at MAX_FEE (50 bp = 0.5%).
*
* Bookkeeping
* ───────────
* openContractIds[] — OPEN (unfilled) contracts only; swap-and-pop O(1) removal.
* futures mapping — live state for OPEN and ACTIVE contracts only.
* Struct is deleted after settlement or cancellation (gas refund).
* Events — permanent historical record for portfolio queries.
*
* Strike price convention
* ───────────────────────
* futuresPrice = PLS wei per 1 SCADA token (1e18 base units).
* Example: 500e18 → 1 SCADA = 500 PLS
* Notional = contractSize × futuresPrice / 1e18.
* contractSize is always a whole-token multiple of 1e18, so division is always exact.
*/
contract SCADAFuturesFactory {
// Constants
address public constant SCADA = 0x69e23263927Ae53E5FF3A898d082a83B7D6fB438;
address public constant PRICE_PAIR = 0x629075c537633132C645a18F265d59e4153CE1C6;
bool private constant SCADA_IS_TOKEN0 = true;
uint256 public constant MIN_CONTRACT_SIZE = 100e18; // 100 SCADA minimum
uint256 public constant MAX_CONTRACT_SIZE = 100_000e18; // 100,000 SCADA maximum
uint256 public constant MAX_FEE = 50; // 50 bps = 0.5%
uint256 public constant MAX_EXPIRY_DATES = 1200; // ~100 years of monthly expiries
// Types
enum State { OPEN, ACTIVE }
struct Future {
address short;
address long; // address(0) while OPEN
uint256 futuresPrice; // PLS wei per 1 SCADA
uint256 expiry;
uint256 feeBps;
uint256 contractSize; // snapshotted at creation
address feeRecipient;
State state;
}
// Custom errors
error NotOwner();
error NotPendingOwner();
error InvalidOwner();
error Paused();
error FeeExceedsMaximum();
error FeeRecipientRequired();
error FeeRecipientLocked();
error ValueExceedsMax();
error ValueBelowMin();
error ExpiryAlreadyExists();
error ExpiryNotFound();
error ExpiryInPast();
error ExpiryHasActiveContracts();
error FutureNotFound();
error NotShort();
error NotOpen();
error NotActive();
error NotExpired();
error FutureExpired();
error SelfAccept();
error ExpiryTooFar();
error ContractSizeOutOfRange();
error FuturesPriceTooLow();
error IncorrectAcceptPayment();
error InvalidRange();
error PageTooLarge();
error ReentrantCall();
error NothingToWithdraw();
error WithdrawalFailed();
error ScadaTransferFailed();
error UnexpectedPayment();
error PairCallFailed();
// Ownership & fee config
address public owner;
address public pendingOwner;
address public feeRecipient;
uint256 public fee; // basis points
// Spam limits
uint256 public contractSize;
uint256 public minFuturesPrice;
uint256 public maxExpiryDuration;
bool public paused;
// Valid expiry dates
mapping(uint256 => bool) public validExpiry;
uint256[] public expiryDates;
mapping(uint256 => uint256) private _expiryIndex;
// Contract registry
uint256 public nextId; // equals total contracts ever created after N create() calls
mapping(uint256 => Future) public futures;
mapping(uint256 => uint256) public activeCountByExpiry; // expiry timestamp → live contract count
// Open contracts (marketplace)
uint256[] public openContractIds;
mapping(uint256 => uint256) private _openIndex;
// Pull-payment
mapping(address => uint256) public pendingWithdrawals; // PLS
mapping(address => uint256) public pendingScadaWithdrawals; // SCADA
// Events
event FutureCreated (uint256 indexed id, address indexed short, uint256 futuresPrice, uint256 indexed expiry);
event FutureAccepted (uint256 indexed id, address indexed long);
event FutureSettled (uint256 indexed id, address indexed short, address indexed long);
event FutureCancelled(uint256 indexed id, address indexed short);
event ExpiryAdded (uint256 indexed expiry);
event ExpiryRemoved(uint256 indexed expiry);
event OwnershipTransferred (address indexed previousOwner, address indexed newOwner);
event FeeUpdated (uint256 previousFee, uint256 newFee);
event FeeRecipientUpdated (address indexed previousRecipient, address indexed newRecipient);
event ContractSizeUpdated (uint256 previousValue, uint256 newValue);
event MinFuturesPriceUpdated (uint256 previousValue, uint256 newValue);
event MaxExpiryDurationUpdated(uint256 previousValue, uint256 newValue);
event PausedStateChanged (bool indexed paused);
event FeeCollected (uint256 indexed id, address indexed recipient, uint256 amount);
event Withdrawn (address indexed recipient, uint256 amount);
event ScadaWithdrawn(address indexed recipient, uint256 amount);
// Reentrancy guard
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status = _NOT_ENTERED;
modifier nonReentrant() {
if (_status == _ENTERED) revert ReentrantCall();
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
modifier onlyOwner() {
if (msg.sender != owner) revert NotOwner();
_;
}
modifier whenNotPaused() {
if (paused) revert Paused();
_;
}
// Constructor
constructor(address _owner, address _feeRecipient, uint256 _fee) {
if (_owner == address(0)) revert InvalidOwner();
if (_fee > MAX_FEE) revert FeeExceedsMaximum();
if (_fee > 0 && _feeRecipient == address(0)) revert FeeRecipientRequired();
owner = _owner;
feeRecipient = _feeRecipient;
fee = _fee;
contractSize = 10_000e18; // default 10,000 SCADA per contract
minFuturesPrice = 10e18; // 10 PLS/SCADA minimum
maxExpiryDuration = 31 days; // contracts cannot expire more than 31 days out
emit OwnershipTransferred(address(0), _owner);
}
// Admin — ownership
function transferOwnership(address newOwner) external onlyOwner {
if (newOwner == address(0)) revert InvalidOwner();
pendingOwner = newOwner;
}
function acceptOwnership() external {
if (msg.sender != pendingOwner) revert NotPendingOwner();
emit OwnershipTransferred(owner, pendingOwner);
owner = pendingOwner;
pendingOwner = address(0);
}
function renounceOwnership() external onlyOwner {
if (paused) revert Paused();
emit OwnershipTransferred(owner, address(0));
owner = address(0);
pendingOwner = address(0);
}
// Admin — fee
function setFee(uint256 newFee) external onlyOwner {
if (newFee > MAX_FEE) revert FeeExceedsMaximum();
if (newFee > 0 && feeRecipient == address(0)) revert FeeRecipientRequired();
emit FeeUpdated(fee, newFee);
fee = newFee;
}
function setFeeRecipient(address newRecipient) external onlyOwner {
if (newRecipient == address(0) && fee > 0) revert FeeRecipientLocked();
emit FeeRecipientUpdated(feeRecipient, newRecipient);
feeRecipient = newRecipient;
}
// Admin — expiry whitelist
/// @notice Add a valid monthly expiry timestamp. Must be in the future.
function addExpiry(uint256 timestamp) external onlyOwner {
if (expiryDates.length >= MAX_EXPIRY_DATES) revert ValueExceedsMax();
if (timestamp <= block.timestamp) revert ExpiryInPast();
if (validExpiry[timestamp]) revert ExpiryAlreadyExists();
validExpiry[timestamp] = true;
_expiryIndex[timestamp] = expiryDates.length;
expiryDates.push(timestamp);
emit ExpiryAdded(timestamp);
}
/// @notice Remove an expiry from the whitelist.
/// Reverts if any OPEN or ACTIVE contract exists for this expiry.
function removeExpiry(uint256 timestamp) external onlyOwner {
if (!validExpiry[timestamp]) revert ExpiryNotFound();
if (activeCountByExpiry[timestamp] > 0) revert ExpiryHasActiveContracts();
validExpiry[timestamp] = false;
uint256 idx = _expiryIndex[timestamp];
uint256 last = expiryDates.length - 1;
if (idx != last) {
uint256 tail = expiryDates[last];
expiryDates[idx] = tail;
_expiryIndex[tail] = idx;
}
expiryDates.pop();
delete _expiryIndex[timestamp];
emit ExpiryRemoved(timestamp);
}
// Admin — spam limits
function setContractSize(uint256 newSize) external onlyOwner {
if (newSize < MIN_CONTRACT_SIZE || newSize > MAX_CONTRACT_SIZE) revert ContractSizeOutOfRange();
if (newSize % 1e18 != 0) revert ContractSizeOutOfRange(); // whole tokens only
emit ContractSizeUpdated(contractSize, newSize);
contractSize = newSize;
}
function setMinFuturesPrice(uint256 newValue) external onlyOwner {
if (newValue == 0) revert FuturesPriceTooLow();
if (newValue > 1_000_000e18) revert ValueExceedsMax(); // hard cap: 1,000,000 PLS/SCADA
emit MinFuturesPriceUpdated(minFuturesPrice, newValue);
minFuturesPrice = newValue;
}
function setMaxExpiryDuration(uint256 newValue) external onlyOwner {
if (newValue == 0) revert ValueBelowMin();
if (newValue > 366 days) revert ValueExceedsMax(); // hard cap: 1 year
emit MaxExpiryDurationUpdated(maxExpiryDuration, newValue);
maxExpiryDuration = newValue;
}
function setPaused(bool _paused) external onlyOwner {
paused = _paused;
emit PausedStateChanged(_paused);
}
// Core: create
/// @notice SHORT creates a futures contract. No PLS fee — makers pay no fee.
/// Caller must approve this factory for contractSize SCADA before calling.
function create(uint256 futuresPrice, uint256 expiry)
external whenNotPaused nonReentrant
returns (uint256 id)
{
if (futuresPrice < minFuturesPrice) revert FuturesPriceTooLow();
if (!validExpiry[expiry]) revert ExpiryNotFound();
if (expiry <= block.timestamp) revert ExpiryInPast();
if (expiry > block.timestamp + maxExpiryDuration) revert ExpiryTooFar();
id = nextId++;
uint256 size = contractSize; // snapshot current size
futures[id] = Future({
short: msg.sender,
long: address(0),
futuresPrice: futuresPrice,
expiry: expiry,
feeBps: fee,
contractSize: size,
feeRecipient: feeRecipient,
state: State.OPEN
});
_openIndex[id] = openContractIds.length;
openContractIds.push(id);
activeCountByExpiry[expiry]++;
_safeTransferFrom(SCADA, msg.sender, address(this), size);
emit FutureCreated(id, msg.sender, futuresPrice, expiry);
}
// Core: accept
/// @notice LONG accepts an open contract. Both parties are locked in until expiry.
/// msg.value must equal acceptCostById(id) — notional + LONG's fee.
function accept(uint256 id)
external payable whenNotPaused nonReentrant
{
Future storage fut = futures[id];
if (fut.short == address(0)) revert FutureNotFound();
if (fut.state != State.OPEN) revert NotOpen();
if (block.timestamp >= fut.expiry) revert FutureExpired();
if (msg.sender == fut.short) revert SelfAccept();
uint256 n = _notional(fut.contractSize, fut.futuresPrice);
uint256 longFee = n * fut.feeBps / 10000;
if (msg.value != n + longFee) revert IncorrectAcceptPayment();
fut.long = msg.sender;
fut.state = State.ACTIVE;
_removeFromOpen(id);
_forwardFee(fut.feeRecipient, longFee);
if (longFee > 0) emit FeeCollected(id, fut.feeRecipient, longFee);
emit FutureAccepted(id, msg.sender);
}
// Core: settle
/// @notice Settle an expired ACTIVE contract. Callable by anyone after expiry.
/// SHORT's PLS notional is credited to pendingWithdrawals.
/// LONG's SCADA is credited to pendingScadaWithdrawals.
/// Both parties call withdraw() / withdrawScada() to collect.
function settle(uint256 id) external nonReentrant {
Future memory fut = futures[id];
if (fut.short == address(0)) revert FutureNotFound();
if (fut.state != State.ACTIVE) revert NotActive();
if (block.timestamp < fut.expiry) revert NotExpired();
delete futures[id];
activeCountByExpiry[fut.expiry]--;
uint256 n = _notional(fut.contractSize, fut.futuresPrice);
pendingWithdrawals[fut.short] += n;
pendingScadaWithdrawals[fut.long] += fut.contractSize;
emit FutureSettled(id, fut.short, fut.long);
}
// Core: cancel
/// @notice Cancel an unfilled (OPEN) contract. SHORT's SCADA is credited to pendingScadaWithdrawals.
/// SHORT may cancel at any time.
/// Anyone may cancel once the contract has expired (permissionless cleanup of stale listings).
function cancel(uint256 id) external nonReentrant {
Future memory fut = futures[id];
if (fut.short == address(0)) revert FutureNotFound();
if (fut.state != State.OPEN) revert NotOpen();
if (msg.sender != fut.short && block.timestamp < fut.expiry) revert NotShort();
delete futures[id];
_removeFromOpen(id);
activeCountByExpiry[fut.expiry]--;
pendingScadaWithdrawals[fut.short] += fut.contractSize;
emit FutureCancelled(id, fut.short);
}
// Pull-payment
/// @notice Collect PLS owed to caller (from settlement or fee accumulation).
function withdraw() external nonReentrant {
uint256 amount = pendingWithdrawals[msg.sender];
if (amount == 0) revert NothingToWithdraw();
pendingWithdrawals[msg.sender] = 0;
(bool ok,) = msg.sender.call{value: amount}("");
if (!ok) revert WithdrawalFailed();
emit Withdrawn(msg.sender, amount);
}
/// @notice Collect SCADA owed to caller (from settlement or cancellation).
function withdrawScada() external nonReentrant {
uint256 amount = pendingScadaWithdrawals[msg.sender];
if (amount == 0) revert NothingToWithdraw();
pendingScadaWithdrawals[msg.sender] = 0;
_safeTransfer(SCADA, msg.sender, amount);
emit ScadaWithdrawn(msg.sender, amount);
}
// View helpers
function notional(uint256 futuresPrice) external view returns (uint256) {
return _notional(contractSize, futuresPrice);
}
function quoteAcceptCost(uint256 futuresPrice) external view returns (uint256) {
uint256 n = _notional(contractSize, futuresPrice);
return n + n * fee / 10000;
}
/// @notice Exact PLS the LONG must send to accept a specific contract by id.
function acceptCostById(uint256 id) external view returns (uint256) {
Future storage fut = futures[id];
if (fut.short == address(0)) revert FutureNotFound();
uint256 n = _notional(fut.contractSize, fut.futuresPrice);
return n + n * fut.feeBps / 10000;
}
/// @notice Instantaneous AMM spot price of SCADA in PLS wei.
/// @dev WARNING: Flash-loan manipulable within a single tx. Display only.
function spotPrice() external view returns (uint256) {
(bool ok, bytes memory data) = PRICE_PAIR.staticcall(abi.encodeWithSelector(0x0902f1ac));
if (!ok) revert PairCallFailed();
(uint112 r0, uint112 r1,) = abi.decode(data, (uint112, uint112, uint32));
(uint256 reserveSCADA, uint256 reservePLS) = SCADA_IS_TOKEN0
? (uint256(r0), uint256(r1))
: (uint256(r1), uint256(r0));
if (reserveSCADA == 0) return 0;
return (reservePLS * 1e18) / reserveSCADA;
}
function totalOpenContracts() external view returns (uint256) {
return openContractIds.length;
}
function getOpenContracts(uint256 from, uint256 to) external view returns (uint256[] memory) {
if (from > to || to > openContractIds.length) revert InvalidRange();
if (to - from > 200) revert PageTooLarge();
uint256[] memory result = new uint256[](to - from);
for (uint256 i = from; i < to; i++) result[i - from] = openContractIds[i];
return result;
}
function getFuture(uint256 id) external view returns (Future memory) {
return futures[id];
}
function getValidExpiries() external view returns (uint256[] memory) {
return expiryDates;
}
/// @notice Returns only future expiry timestamps (block.timestamp < expiry).
function getActiveExpiries() external view returns (uint256[] memory) {
uint256 count = 0;
for (uint256 i = 0; i < expiryDates.length; i++) {
if (expiryDates[i] > block.timestamp) count++;
}
uint256[] memory result = new uint256[](count);
uint256 j = 0;
for (uint256 i = 0; i < expiryDates.length; i++) {
if (expiryDates[i] > block.timestamp) result[j++] = expiryDates[i];
}
return result;
}
function totalExpiryDates() external view returns (uint256) {
return expiryDates.length;
}
// Internal helpers
function _notional(uint256 size, uint256 futuresPrice) internal pure returns (uint256) {
return size * futuresPrice / 1e18;
}
function _forwardFee(address recipient, uint256 amount) internal {
assert(amount == 0 || recipient != address(0));
if (amount > 0) {
pendingWithdrawals[recipient] += amount;
}
}
function _removeFromOpen(uint256 id) internal {
uint256 idx = _openIndex[id];
uint256 last = openContractIds.length - 1;
if (idx != last) {
uint256 tailId = openContractIds[last];
openContractIds[idx] = tailId;
_openIndex[tailId] = idx;
}
openContractIds.pop();
delete _openIndex[id];
}
receive() external payable { revert UnexpectedPayment(); }
function _safeTransfer(address token, address to, uint256 value) internal {
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0xa9059cbb, to, value)
);
if (!success || (data.length > 0 && !abi.decode(data, (bool))))
revert ScadaTransferFailed();
}
function _safeTransferFrom(address token, address from, address to, uint256 value) internal {
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0x23b872dd, from, to, value)
);
if (!success || (data.length > 0 && !abi.decode(data, (bool))))
revert ScadaTransferFailed();
}
}
Compiler Settings
{"remappings":[],"optimizer":{"runs":200,"enabled":true},"metadata":{"bytecodeHash":"ipfs"},"libraries":{},"evmVersion":"paris","compilationTarget":{"SCADAFuturesFactory.sol":"SCADAFuturesFactory"}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"_owner","internalType":"address"},{"type":"address","name":"_feeRecipient","internalType":"address"},{"type":"uint256","name":"_fee","internalType":"uint256"}]},{"type":"error","name":"ContractSizeOutOfRange","inputs":[]},{"type":"error","name":"ExpiryAlreadyExists","inputs":[]},{"type":"error","name":"ExpiryHasActiveContracts","inputs":[]},{"type":"error","name":"ExpiryInPast","inputs":[]},{"type":"error","name":"ExpiryNotFound","inputs":[]},{"type":"error","name":"ExpiryTooFar","inputs":[]},{"type":"error","name":"FeeExceedsMaximum","inputs":[]},{"type":"error","name":"FeeRecipientLocked","inputs":[]},{"type":"error","name":"FeeRecipientRequired","inputs":[]},{"type":"error","name":"FutureExpired","inputs":[]},{"type":"error","name":"FutureNotFound","inputs":[]},{"type":"error","name":"FuturesPriceTooLow","inputs":[]},{"type":"error","name":"IncorrectAcceptPayment","inputs":[]},{"type":"error","name":"InvalidOwner","inputs":[]},{"type":"error","name":"InvalidRange","inputs":[]},{"type":"error","name":"NotActive","inputs":[]},{"type":"error","name":"NotExpired","inputs":[]},{"type":"error","name":"NotOpen","inputs":[]},{"type":"error","name":"NotOwner","inputs":[]},{"type":"error","name":"NotPendingOwner","inputs":[]},{"type":"error","name":"NotShort","inputs":[]},{"type":"error","name":"NothingToWithdraw","inputs":[]},{"type":"error","name":"PageTooLarge","inputs":[]},{"type":"error","name":"PairCallFailed","inputs":[]},{"type":"error","name":"Paused","inputs":[]},{"type":"error","name":"ReentrantCall","inputs":[]},{"type":"error","name":"ScadaTransferFailed","inputs":[]},{"type":"error","name":"SelfAccept","inputs":[]},{"type":"error","name":"UnexpectedPayment","inputs":[]},{"type":"error","name":"ValueBelowMin","inputs":[]},{"type":"error","name":"ValueExceedsMax","inputs":[]},{"type":"error","name":"WithdrawalFailed","inputs":[]},{"type":"event","name":"ContractSizeUpdated","inputs":[{"type":"uint256","name":"previousValue","internalType":"uint256","indexed":false},{"type":"uint256","name":"newValue","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"ExpiryAdded","inputs":[{"type":"uint256","name":"expiry","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"ExpiryRemoved","inputs":[{"type":"uint256","name":"expiry","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"FeeCollected","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":true},{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"FeeRecipientUpdated","inputs":[{"type":"address","name":"previousRecipient","internalType":"address","indexed":true},{"type":"address","name":"newRecipient","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"FeeUpdated","inputs":[{"type":"uint256","name":"previousFee","internalType":"uint256","indexed":false},{"type":"uint256","name":"newFee","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"FutureAccepted","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":true},{"type":"address","name":"long","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"FutureCancelled","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":true},{"type":"address","name":"short","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"FutureCreated","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":true},{"type":"address","name":"short","internalType":"address","indexed":true},{"type":"uint256","name":"futuresPrice","internalType":"uint256","indexed":false},{"type":"uint256","name":"expiry","internalType":"uint256","indexed":true}],"anonymous":false},{"type":"event","name":"FutureSettled","inputs":[{"type":"uint256","name":"id","internalType":"uint256","indexed":true},{"type":"address","name":"short","internalType":"address","indexed":true},{"type":"address","name":"long","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"MaxExpiryDurationUpdated","inputs":[{"type":"uint256","name":"previousValue","internalType":"uint256","indexed":false},{"type":"uint256","name":"newValue","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"MinFuturesPriceUpdated","inputs":[{"type":"uint256","name":"previousValue","internalType":"uint256","indexed":false},{"type":"uint256","name":"newValue","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"OwnershipTransferred","inputs":[{"type":"address","name":"previousOwner","internalType":"address","indexed":true},{"type":"address","name":"newOwner","internalType":"address","indexed":true}],"anonymous":false},{"type":"event","name":"PausedStateChanged","inputs":[{"type":"bool","name":"paused","internalType":"bool","indexed":true}],"anonymous":false},{"type":"event","name":"ScadaWithdrawn","inputs":[{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"Withdrawn","inputs":[{"type":"address","name":"recipient","internalType":"address","indexed":true},{"type":"uint256","name":"amount","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_CONTRACT_SIZE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_EXPIRY_DATES","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MAX_FEE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"MIN_CONTRACT_SIZE","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"PRICE_PAIR","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"SCADA","inputs":[]},{"type":"function","stateMutability":"payable","outputs":[],"name":"accept","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"acceptCostById","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"acceptOwnership","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"activeCountByExpiry","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"addExpiry","inputs":[{"type":"uint256","name":"timestamp","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"cancel","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"contractSize","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"uint256","name":"id","internalType":"uint256"}],"name":"create","inputs":[{"type":"uint256","name":"futuresPrice","internalType":"uint256"},{"type":"uint256","name":"expiry","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"expiryDates","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"fee","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"feeRecipient","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"short","internalType":"address"},{"type":"address","name":"long","internalType":"address"},{"type":"uint256","name":"futuresPrice","internalType":"uint256"},{"type":"uint256","name":"expiry","internalType":"uint256"},{"type":"uint256","name":"feeBps","internalType":"uint256"},{"type":"uint256","name":"contractSize","internalType":"uint256"},{"type":"address","name":"feeRecipient","internalType":"address"},{"type":"uint8","name":"state","internalType":"enum SCADAFuturesFactory.State"}],"name":"futures","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getActiveExpiries","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"tuple","name":"","internalType":"struct SCADAFuturesFactory.Future","components":[{"type":"address","name":"short","internalType":"address"},{"type":"address","name":"long","internalType":"address"},{"type":"uint256","name":"futuresPrice","internalType":"uint256"},{"type":"uint256","name":"expiry","internalType":"uint256"},{"type":"uint256","name":"feeBps","internalType":"uint256"},{"type":"uint256","name":"contractSize","internalType":"uint256"},{"type":"address","name":"feeRecipient","internalType":"address"},{"type":"uint8","name":"state","internalType":"enum SCADAFuturesFactory.State"}]}],"name":"getFuture","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getOpenContracts","inputs":[{"type":"uint256","name":"from","internalType":"uint256"},{"type":"uint256","name":"to","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256[]","name":"","internalType":"uint256[]"}],"name":"getValidExpiries","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"maxExpiryDuration","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"minFuturesPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"nextId","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"notional","inputs":[{"type":"uint256","name":"futuresPrice","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"openContractIds","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"owner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"paused","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"pendingOwner","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pendingScadaWithdrawals","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"pendingWithdrawals","inputs":[{"type":"address","name":"","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"quoteAcceptCost","inputs":[{"type":"uint256","name":"futuresPrice","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"removeExpiry","inputs":[{"type":"uint256","name":"timestamp","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"renounceOwnership","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setContractSize","inputs":[{"type":"uint256","name":"newSize","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFee","inputs":[{"type":"uint256","name":"newFee","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setFeeRecipient","inputs":[{"type":"address","name":"newRecipient","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMaxExpiryDuration","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setMinFuturesPrice","inputs":[{"type":"uint256","name":"newValue","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setPaused","inputs":[{"type":"bool","name":"_paused","internalType":"bool"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"settle","inputs":[{"type":"uint256","name":"id","internalType":"uint256"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"spotPrice","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalExpiryDates","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"totalOpenContracts","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferOwnership","inputs":[{"type":"address","name":"newOwner","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"bool","name":"","internalType":"bool"}],"name":"validExpiry","inputs":[{"type":"uint256","name":"","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdraw","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"withdrawScada","inputs":[]},{"type":"receive","stateMutability":"payable"}]
Contract Creation Code
0x608060405260016012553480156200001657600080fd5b5060405162002c3338038062002c33833981016040819052620000399162000160565b6001600160a01b03831662000061576040516349e27cff60e01b815260040160405180910390fd5b60328111156200008457604051632be7087760e21b815260040160405180910390fd5b6000811180156200009c57506001600160a01b038216155b15620000bb57604051630b8ed10b60e31b815260040160405180910390fd5b600080546001600160a01b03199081166001600160a01b0386811691821784556002805490931690861617909155600383905569021e19e0c9bab2400000600455678ac7230489e800006005556228de806006556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3505050620001a1565b80516001600160a01b03811681146200015b57600080fd5b919050565b6000806000606084860312156200017657600080fd5b620001818462000143565b9250620001916020850162000143565b9150604084015190509250925092565b612a8280620001b16000396000f3fe6080604052600436106102b25760003560e01c8063884c2a1d11610175578063d6cd9d91116100dc578063eb0582ad11610095578063f3f437031161006f578063f3f43703146108a3578063fd0ce9dc146108d0578063fd2595f0146108f0578063fd90341f1461091857600080fd5b8063eb0582ad1461083e578063f2821b3b1461086e578063f2fde38b1461088357600080fd5b8063d6cd9d911461079d578063ddca3f43146107bd578063ddf4787c146107d3578063e30c3978146107e9578063e74b981b14610809578063e88ad70d1461082957600080fd5b80639f7b45791161012e5780639f7b4579146106e8578063b869792a14610708578063bc063e1a14610728578063c6da1d8d1461073d578063cd1cbe8f1461075d578063ce8e80c11461077d57600080fd5b8063884c2a1d146105c65780638a1a110d146105ee5780638da5cb5b146106735780638df828001461069357806399f98931146106b35780639c981338146106c857600080fd5b806340e58ee51161021957806369fe0e2d116101d257806369fe0e2d1461050d5780636eb29a031461052d578063701a1fc21461055a578063715018a61461056f57806379ba509714610584578063839e703a1461059957600080fd5b806340e58ee51461042857806346414f141461044857806346904840146104755780635c975abb146104ad57806361b8ce8c146104d757806363fe5e9f146104ed57600080fd5b806324361c4d1161026b57806324361c4d146103a05780632a982785146103b6578063398482d8146103cb5780633ccfd60b146103e05780633d7cc610146103f55780633e7690b11461040b57600080fd5b806305f0e0fb146102d557806316a039ac1461031557806316c38b3c1461032b578063188e98d91461034d57806319b05f491461036d57806322d180551461038057600080fd5b366102d0576040516390b25a6760e01b815260040160405180910390fd5b600080fd5b3480156102e157600080fd5b506103026102f03660046126a6565b60116020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561032157600080fd5b506103026104b081565b34801561033757600080fd5b5061034b6103463660046126e0565b610936565b005b34801561035957600080fd5b5061034b6103683660046126fd565b61099e565b61034b61037b3660046126fd565b610a56565b34801561038c57600080fd5b5061034b61039b3660046126fd565b610c99565b3480156103ac57600080fd5b5061030260065481565b3480156103c257600080fd5b5061034b610e18565b3480156103d757600080fd5b50610302610ede565b3480156103ec57600080fd5b5061034b611026565b34801561040157600080fd5b5061030260045481565b34801561041757600080fd5b5061030268056bc75e2d6310000081565b34801561043457600080fd5b5061034b6104433660046126fd565b611135565b34801561045457600080fd5b506103026104633660046126fd565b600d6020526000908152604090205481565b34801561048157600080fd5b50600254610495906001600160a01b031681565b6040516001600160a01b03909116815260200161030c565b3480156104b957600080fd5b506007546104c79060ff1681565b604051901515815260200161030c565b3480156104e357600080fd5b50610302600b5481565b3480156104f957600080fd5b506103026105083660046126fd565b61139a565b34801561051957600080fd5b5061034b6105283660046126fd565b611415565b34801561053957600080fd5b5061054d610548366004612716565b6114da565b60405161030c9190612738565b34801561056657600080fd5b50600954610302565b34801561057b57600080fd5b5061034b6115f0565b34801561059057600080fd5b5061034b611695565b3480156105a557600080fd5b506105b96105b43660046126fd565b611724565b60405161030c91906127b4565b3480156105d257600080fd5b5061049573629075c537633132c645a18f265d59e4153ce1c681565b3480156105fa57600080fd5b5061065f6106093660046126fd565b600c6020526000908152604090208054600182015460028301546003840154600485015460058601546006909601546001600160a01b03958616969486169593949293919291811690600160a01b900460ff1688565b60405161030c989796959493929190612824565b34801561067f57600080fd5b50600054610495906001600160a01b031681565b34801561069f57600080fd5b5061034b6106ae3660046126fd565b611815565b3480156106bf57600080fd5b5061054d611ab6565b3480156106d457600080fd5b506103026106e33660046126fd565b611bea565b3480156106f457600080fd5b50610302610703366004612716565b611c0b565b34801561071457600080fd5b506103026107233660046126fd565b611eef565b34801561073457600080fd5b50610302603281565b34801561074957600080fd5b5061034b6107583660046126fd565b611efd565b34801561076957600080fd5b5061034b6107783660046126fd565b611fd7565b34801561078957600080fd5b506103026107983660046126fd565b612089565b3480156107a957600080fd5b5061034b6107b83660046126fd565b612099565b3480156107c957600080fd5b5061030260035481565b3480156107df57600080fd5b5061030260055481565b3480156107f557600080fd5b50600154610495906001600160a01b031681565b34801561081557600080fd5b5061034b6108243660046126a6565b6121bd565b34801561083557600080fd5b5061054d61227b565b34801561084a57600080fd5b506104c76108593660046126fd565b60086020526000908152604090205460ff1681565b34801561087a57600080fd5b50600e54610302565b34801561088f57600080fd5b5061034b61089e3660046126a6565b6122d3565b3480156108af57600080fd5b506103026108be3660046126a6565b60106020526000908152604090205481565b3480156108dc57600080fd5b506103026108eb3660046126fd565b612347565b3480156108fc57600080fd5b506104957369e23263927ae53e5ff3a898d082a83b7d6fb43881565b34801561092457600080fd5b5061030269152d02c7e14af680000081565b6000546001600160a01b03163314610961576040516330cd747160e01b815260040160405180910390fd5b6007805460ff19168215159081179091556040517f9e3a5e37224532dea67b89face185703738a228a6e8a23dee546960180d3be6490600090a250565b6000546001600160a01b031633146109c9576040516330cd747160e01b815260040160405180910390fd5b806000036109ea57604051636b81a62760e11b815260040160405180910390fd5b69d3c21bcecceda1000000811115610a155760405163751bd59f60e11b815260040160405180910390fd5b60055460408051918252602082018390527fca4cf4eae5efb9a30c5c06f74b1f0fbf706424568d0399550a56f02317095aa2910160405180910390a1600555565b60075460ff1615610a7a576040516313d0ff5960e31b815260040160405180910390fd5b600260125403610a9d576040516306fda65d60e31b815260040160405180910390fd5b60026012556000818152600c6020526040902080546001600160a01b0316610ad85760405163644b7b2160e11b815260040160405180910390fd5b60006006820154600160a01b900460ff166001811115610afa57610afa61277c565b14610b1857604051631bb5f5b360e31b815260040160405180910390fd5b80600301544210610b3c5760405163cd2810ef60e01b815260040160405180910390fd5b80546001600160a01b03163303610b665760405163c330855960e01b815260040160405180910390fd5b6000610b7a82600501548360020154612384565b90506000612710836004015483610b919190612891565b610b9b91906128be565b9050610ba781836128d2565b3414610bc6576040516359c0851f60e11b815260040160405180910390fd5b600180840180546001600160a01b0319163317905560068401805460ff60a01b1916600160a01b830217905550610bfc846123a3565b6006830154610c14906001600160a01b031682612460565b8015610c615760068301546040518281526001600160a01b039091169085907ff1d6c8ee14081f641e2073a1064d870f135f1001a301c6b14a7b9655672fec119060200160405180910390a35b604051339085907f6551e44c1e8ec713c7a4e7675a142d18af09eb92d01826ad9075e3e380f950b290600090a3505060016012555050565b6000546001600160a01b03163314610cc4576040516330cd747160e01b815260040160405180910390fd5b60008181526008602052604090205460ff16610cf357604051630169ae4b60e41b815260040160405180910390fd5b6000818152600d602052604090205415610d205760405163f1ba07a760e01b815260040160405180910390fd5b6000818152600860209081526040808320805460ff19169055600a909152812054600954909190610d53906001906128e5565b9050808214610db257600060098281548110610d7157610d716128f8565b906000526020600020015490508060098481548110610d9257610d926128f8565b6000918252602080832090910192909255918252600a9052604090208290555b6009805480610dc357610dc361290e565b600082815260208082208301600019908101839055909201909255848252600a905260408082208290555184917f8ee1131e547cdf75e14a5580303ceed0e68b75a1edcabeaac6b4912c236a36fd91a2505050565b600260125403610e3b576040516306fda65d60e31b815260040160405180910390fd5b60026012553360009081526011602052604081205490819003610e7157604051630686827b60e51b815260040160405180910390fd5b33600081815260116020526040812055610ea1907369e23263927ae53e5ff3a898d082a83b7d6fb43890836124b9565b60405181815233907fa425cd2f25f0f5e5b42a51b5666f0f053529fe6a261d0fb5b60f43f645a4523d9060200160405180910390a2506001601255565b60408051600481526024810182526020810180516001600160e01b0316630240bc6b60e21b17905290516000918291829173629075c537633132c645a18f265d59e4153ce1c691610f2f9190612924565b600060405180830381855afa9150503d8060008114610f6a576040519150601f19603f3d011682016040523d82523d6000602084013e610f6f565b606091505b509150915081610f9257604051631c6750f960e21b815260040160405180910390fd5b60008082806020019051810190610fa9919061296f565b50915091506000806001610fd057826001600160701b0316846001600160701b0316610fe5565b836001600160701b0316836001600160701b03165b9150915081600003610ffe576000965050505050505090565b8161101182670de0b6b3a7640000612891565b61101b91906128be565b965050505050505090565b600260125403611049576040516306fda65d60e31b815260040160405180910390fd5b6002601255336000908152601060205260408120549081900361107f57604051630686827b60e51b815260040160405180910390fd5b336000818152601060205260408082208290555190919083908381818185875af1925050503d80600081146110d0576040519150601f19603f3d011682016040523d82523d6000602084013e6110d5565b606091505b50509050806110f7576040516327fcd9d160e01b815260040160405180910390fd5b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d59060200160405180910390a250506001601255565b600260125403611158576040516306fda65d60e31b815260040160405180910390fd5b600260128190556000828152600c6020908152604080832081516101008101835281546001600160a01b03908116825260018084015482169583019590955295820154928101929092526003810154606083015260048101546080830152600581015460a0830152600681015494851660c0830152929390929160e0840191600160a01b900460ff16908111156111f1576111f161277c565b60018111156112025761120261277c565b90525080519091506001600160a01b03166112305760405163644b7b2160e11b815260040160405180910390fd5b60008160e0015160018111156112485761124861277c565b1461126657604051631bb5f5b360e31b815260040160405180910390fd5b80516001600160a01b031633148015906112835750806060015142105b156112a15760405163942325c960e01b815260040160405180910390fd5b6000828152600c6020526040812080546001600160a01b031990811682556001820180549091169055600281018290556003810182905560048101829055600581019190915560060180546001600160a81b0319169055611301826123a3565b60608101516000908152600d60205260408120805491611320836129bf565b909155505060a081015181516001600160a01b0316600090815260116020526040812080549091906113539084906128d2565b909155505080516040516001600160a01b039091169083907fb06e9f105d9c9095d543b9cd5bfccc5690099c9d74629c34907c857b9d594e2290600090a350506001601255565b6000818152600c6020526040812080546001600160a01b03166113d05760405163644b7b2160e11b815260040160405180910390fd5b60006113e482600501548360020154612384565b90506127108260040154826113f99190612891565b61140391906128be565b61140d90826128d2565b949350505050565b6000546001600160a01b03163314611440576040516330cd747160e01b815260040160405180910390fd5b603281111561146257604051632be7087760e21b815260040160405180910390fd5b60008111801561147b57506002546001600160a01b0316155b1561149957604051630b8ed10b60e31b815260040160405180910390fd5b60035460408051918252602082018390527f528d9479e9f9889a87a3c30c7f7ba537e5e59c4c85a37733b16e57c62df61302910160405180910390a1600355565b6060818311806114eb5750600e5482115b156115095760405163561ce9bb60e01b815260040160405180910390fd5b60c861151584846128e5565b11156115345760405163784931eb60e11b815260040160405180910390fd5b600061154084846128e5565b67ffffffffffffffff811115611558576115586129d6565b604051908082528060200260200182016040528015611581578160200160208202803683370190505b509050835b838110156115e657600e81815481106115a1576115a16128f8565b90600052602060002001548286836115b991906128e5565b815181106115c9576115c96128f8565b6020908102919091010152806115de816129ec565b915050611586565b5090505b92915050565b6000546001600160a01b0316331461161b576040516330cd747160e01b815260040160405180910390fd5b60075460ff161561163f576040516313d0ff5960e31b815260040160405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319908116909155600180549091169055565b6001546001600160a01b031633146116c057604051630614e5c760e21b815260040160405180910390fd5b600154600080546040516001600160a01b0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a360018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6117696040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290529060e082015290565b6000828152600c602090815260409182902082516101008101845281546001600160a01b0390811682526001808401548216948301949094526002830154948201949094526003820154606082015260048201546080820152600582015460a0820152600682015493841660c082015292909160e0840191600160a01b900460ff16908111156117fb576117fb61277c565b600181111561180c5761180c61277c565b90525092915050565b600260125403611838576040516306fda65d60e31b815260040160405180910390fd5b600260128190556000828152600c6020908152604080832081516101008101835281546001600160a01b03908116825260018084015482169583019590955295820154928101929092526003810154606083015260048101546080830152600581015460a0830152600681015494851660c0830152929390929160e0840191600160a01b900460ff16908111156118d1576118d161277c565b60018111156118e2576118e261277c565b90525080519091506001600160a01b03166119105760405163644b7b2160e11b815260040160405180910390fd5b60018160e0015160018111156119285761192861277c565b1461194657604051634065aaf160e11b815260040160405180910390fd5b806060015142101561196b5760405163d0404f8560e01b815260040160405180910390fd5b6000828152600c6020908152604080832080546001600160a01b0319908116825560018201805490911690556002810184905560038101849055600481018490556005810184905560060180546001600160a81b031916905560608401518352600d90915281208054916119de836129bf565b919050555060006119f78260a001518360400151612384565b82516001600160a01b0316600090815260106020526040812080549293508392909190611a259084906128d2565b909155505060a08201516020808401516001600160a01b031660009081526011909152604081208054909190611a5c9084906128d2565b9250508190555081602001516001600160a01b031682600001516001600160a01b0316847f4b3784916640b601962572cc8a071940c0b21f692a52df0c32e6945c4738995460405160405180910390a45050600160125550565b60606000805b600954811015611b0b574260098281548110611ada57611ada6128f8565b90600052602060002001541115611af95781611af5816129ec565b9250505b80611b03816129ec565b915050611abc565b5060008167ffffffffffffffff811115611b2757611b276129d6565b604051908082528060200260200182016040528015611b50578160200160208202803683370190505b5090506000805b600954811015611be1574260098281548110611b7557611b756128f8565b90600052602060002001541115611bcf5760098181548110611b9957611b996128f8565b9060005260206000200154838380611bb0906129ec565b945081518110611bc257611bc26128f8565b6020026020010181815250505b80611bd9816129ec565b915050611b57565b50909392505050565b600e8181548110611bfa57600080fd5b600091825260209091200154905081565b60075460009060ff1615611c32576040516313d0ff5960e31b815260040160405180910390fd5b600260125403611c55576040516306fda65d60e31b815260040160405180910390fd5b6002601255600554831015611c7d57604051636b81a62760e11b815260040160405180910390fd5b60008281526008602052604090205460ff16611cac57604051630169ae4b60e41b815260040160405180910390fd5b428211611ccc5760405163079955a160e41b815260040160405180910390fd5b600654611cd990426128d2565b821115611cf957604051632414776560e11b815260040160405180910390fd5b600b8054906000611d09836129ec565b90915550600454604080516101008101825233815260006020820181905291810187905260608101869052600354608082015260a081018390526002546001600160a01b031660c082015292935090919060e08201526000838152600c6020908152604091829020835181546001600160a01b03199081166001600160a01b039283161783559285015160018084018054861692841692909217909155938501516002830155606085015160038301556080850151600483015560a0850151600583015560c085015160068301805494851691909216908117825560e08601519294929391926001600160a81b03199092161790600160a01b908490811115611e1457611e1461277c565b021790555050600e80546000858152600f60209081526040808320849055600184019094557fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd909201869055868152600d9091529081208054925090611e79836129ec565b9190505550611e9e7369e23263927ae53e5ff3a898d082a83b7d6fb4383330846125ab565b82336001600160a01b0316837f146495679bcf320eb08782de7ec9445e5df6c7e605c8fd3e1c529b6dbca73cd687604051611edb91815260200190565b60405180910390a450600160125592915050565b60006115ea60045483612384565b6000546001600160a01b03163314611f28576040516330cd747160e01b815260040160405180910390fd5b68056bc75e2d63100000811080611f48575069152d02c7e14af680000081115b15611f66576040516334c7a5e160e21b815260040160405180910390fd5b611f78670de0b6b3a764000082612a05565b15611f96576040516334c7a5e160e21b815260040160405180910390fd5b60045460408051918252602082018390527f0f2cfa1d57de81a69554b8d29c87f925791ee174792d6023e4e154ac11fff4f4910160405180910390a1600455565b6000546001600160a01b03163314612002576040516330cd747160e01b815260040160405180910390fd5b806000036120235760405163841a468560e01b815260040160405180910390fd5b6301e285008111156120485760405163751bd59f60e11b815260040160405180910390fd5b60065460408051918252602082018390527f073abaf7e45ed9cbaece9163c31bebd5fcb246f1071042474650c2c5885a5047910160405180910390a1600655565b60098181548110611bfa57600080fd5b6000546001600160a01b031633146120c4576040516330cd747160e01b815260040160405180910390fd5b6009546104b0116120e85760405163751bd59f60e11b815260040160405180910390fd5b4281116121085760405163079955a160e41b815260040160405180910390fd5b60008181526008602052604090205460ff161561213857604051633d29014b60e01b815260040160405180910390fd5b6000818152600860209081526040808320805460ff1916600190811790915560098054600a909452828520849055908301815583527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af9091018390555182917f7385558d62442e3e76f42474f7caaa194432a0e6be9c74f4c59f854061df656091a250565b6000546001600160a01b031633146121e8576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b03811615801561220157506000600354115b1561221f5760405163dfe5a74960e01b815260040160405180910390fd5b6002546040516001600160a01b038084169216907faaebcf1bfa00580e41d966056b48521fa9f202645c86d4ddf28113e617c1b1d390600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b606060098054806020026020016040519081016040528092919081815260200182805480156122c957602002820191906000526020600020905b8154815260200190600101908083116122b5575b5050505050905090565b6000546001600160a01b031633146122fe576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b038116612325576040516349e27cff60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008061235660045484612384565b9050612710600354826123699190612891565b61237391906128be565b61237d90826128d2565b9392505050565b6000670de0b6b3a76400006123998385612891565b61237d91906128be565b6000818152600f6020526040812054600e549091906123c4906001906128e5565b9050808214612423576000600e82815481106123e2576123e26128f8565b9060005260206000200154905080600e8481548110612403576124036128f8565b6000918252602080832090910192909255918252600f9052604090208290555b600e8054806124345761243461290e565b600082815260208082208301600019908101839055909201909255938152600f90935250506040812055565b80158061247557506001600160a01b03821615155b61248157612481612a19565b80156124b5576001600160a01b038216600090815260106020526040812080548392906124af9084906128d2565b90915550505b5050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916125159190612924565b6000604051808303816000865af19150503d8060008114612552576040519150601f19603f3d011682016040523d82523d6000602084013e612557565b606091505b50915091508115806125865750600081511180156125865750808060200190518101906125849190612a2f565b155b156125a45760405163fe66d06160e01b815260040160405180910390fd5b5050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b179052915160009283929088169161260f9190612924565b6000604051808303816000865af19150503d806000811461264c576040519150601f19603f3d011682016040523d82523d6000602084013e612651565b606091505b509150915081158061268057506000815111801561268057508080602001905181019061267e9190612a2f565b155b1561269e5760405163fe66d06160e01b815260040160405180910390fd5b505050505050565b6000602082840312156126b857600080fd5b81356001600160a01b038116811461237d57600080fd5b80151581146126dd57600080fd5b50565b6000602082840312156126f257600080fd5b813561237d816126cf565b60006020828403121561270f57600080fd5b5035919050565b6000806040838503121561272957600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b8181101561277057835183529284019291840191600101612754565b50909695505050505050565b634e487b7160e01b600052602160045260246000fd5b600281106127b057634e487b7160e01b600052602160045260246000fd5b9052565b60006101008201905060018060a01b0380845116835280602085015116602084015260408401516040840152606084015160608401526080840151608084015260a084015160a08401528060c08501511660c08401525060e083015161281d60e0840182612792565b5092915050565b6001600160a01b038981168252888116602083015260408201889052606082018790526080820186905260a08201859052831660c0820152610100810161286e60e0830184612792565b9998505050505050505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176115ea576115ea61287b565b634e487b7160e01b600052601260045260246000fd5b6000826128cd576128cd6128a8565b500490565b808201808211156115ea576115ea61287b565b818103818111156115ea576115ea61287b565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b6000825160005b81811015612945576020818601810151858301520161292b565b506000920191825250919050565b80516001600160701b038116811461296a57600080fd5b919050565b60008060006060848603121561298457600080fd5b61298d84612953565b925061299b60208501612953565b9150604084015163ffffffff811681146129b457600080fd5b809150509250925092565b6000816129ce576129ce61287b565b506000190190565b634e487b7160e01b600052604160045260246000fd5b6000600182016129fe576129fe61287b565b5060010190565b600082612a1457612a146128a8565b500690565b634e487b7160e01b600052600160045260246000fd5b600060208284031215612a4157600080fd5b815161237d816126cf56fea2646970667358221220cbe25f22d90e44b6684b84c2ae357da7f7727b497f2e81956587d5e2d225793a64736f6c63430008140033000000000000000000000000915b4145e169ce7352936e88546ac8667d22723c000000000000000000000000915b4145e169ce7352936e88546ac8667d22723c0000000000000000000000000000000000000000000000000000000000000019
Deployed ByteCode
0x6080604052600436106102b25760003560e01c8063884c2a1d11610175578063d6cd9d91116100dc578063eb0582ad11610095578063f3f437031161006f578063f3f43703146108a3578063fd0ce9dc146108d0578063fd2595f0146108f0578063fd90341f1461091857600080fd5b8063eb0582ad1461083e578063f2821b3b1461086e578063f2fde38b1461088357600080fd5b8063d6cd9d911461079d578063ddca3f43146107bd578063ddf4787c146107d3578063e30c3978146107e9578063e74b981b14610809578063e88ad70d1461082957600080fd5b80639f7b45791161012e5780639f7b4579146106e8578063b869792a14610708578063bc063e1a14610728578063c6da1d8d1461073d578063cd1cbe8f1461075d578063ce8e80c11461077d57600080fd5b8063884c2a1d146105c65780638a1a110d146105ee5780638da5cb5b146106735780638df828001461069357806399f98931146106b35780639c981338146106c857600080fd5b806340e58ee51161021957806369fe0e2d116101d257806369fe0e2d1461050d5780636eb29a031461052d578063701a1fc21461055a578063715018a61461056f57806379ba509714610584578063839e703a1461059957600080fd5b806340e58ee51461042857806346414f141461044857806346904840146104755780635c975abb146104ad57806361b8ce8c146104d757806363fe5e9f146104ed57600080fd5b806324361c4d1161026b57806324361c4d146103a05780632a982785146103b6578063398482d8146103cb5780633ccfd60b146103e05780633d7cc610146103f55780633e7690b11461040b57600080fd5b806305f0e0fb146102d557806316a039ac1461031557806316c38b3c1461032b578063188e98d91461034d57806319b05f491461036d57806322d180551461038057600080fd5b366102d0576040516390b25a6760e01b815260040160405180910390fd5b600080fd5b3480156102e157600080fd5b506103026102f03660046126a6565b60116020526000908152604090205481565b6040519081526020015b60405180910390f35b34801561032157600080fd5b506103026104b081565b34801561033757600080fd5b5061034b6103463660046126e0565b610936565b005b34801561035957600080fd5b5061034b6103683660046126fd565b61099e565b61034b61037b3660046126fd565b610a56565b34801561038c57600080fd5b5061034b61039b3660046126fd565b610c99565b3480156103ac57600080fd5b5061030260065481565b3480156103c257600080fd5b5061034b610e18565b3480156103d757600080fd5b50610302610ede565b3480156103ec57600080fd5b5061034b611026565b34801561040157600080fd5b5061030260045481565b34801561041757600080fd5b5061030268056bc75e2d6310000081565b34801561043457600080fd5b5061034b6104433660046126fd565b611135565b34801561045457600080fd5b506103026104633660046126fd565b600d6020526000908152604090205481565b34801561048157600080fd5b50600254610495906001600160a01b031681565b6040516001600160a01b03909116815260200161030c565b3480156104b957600080fd5b506007546104c79060ff1681565b604051901515815260200161030c565b3480156104e357600080fd5b50610302600b5481565b3480156104f957600080fd5b506103026105083660046126fd565b61139a565b34801561051957600080fd5b5061034b6105283660046126fd565b611415565b34801561053957600080fd5b5061054d610548366004612716565b6114da565b60405161030c9190612738565b34801561056657600080fd5b50600954610302565b34801561057b57600080fd5b5061034b6115f0565b34801561059057600080fd5b5061034b611695565b3480156105a557600080fd5b506105b96105b43660046126fd565b611724565b60405161030c91906127b4565b3480156105d257600080fd5b5061049573629075c537633132c645a18f265d59e4153ce1c681565b3480156105fa57600080fd5b5061065f6106093660046126fd565b600c6020526000908152604090208054600182015460028301546003840154600485015460058601546006909601546001600160a01b03958616969486169593949293919291811690600160a01b900460ff1688565b60405161030c989796959493929190612824565b34801561067f57600080fd5b50600054610495906001600160a01b031681565b34801561069f57600080fd5b5061034b6106ae3660046126fd565b611815565b3480156106bf57600080fd5b5061054d611ab6565b3480156106d457600080fd5b506103026106e33660046126fd565b611bea565b3480156106f457600080fd5b50610302610703366004612716565b611c0b565b34801561071457600080fd5b506103026107233660046126fd565b611eef565b34801561073457600080fd5b50610302603281565b34801561074957600080fd5b5061034b6107583660046126fd565b611efd565b34801561076957600080fd5b5061034b6107783660046126fd565b611fd7565b34801561078957600080fd5b506103026107983660046126fd565b612089565b3480156107a957600080fd5b5061034b6107b83660046126fd565b612099565b3480156107c957600080fd5b5061030260035481565b3480156107df57600080fd5b5061030260055481565b3480156107f557600080fd5b50600154610495906001600160a01b031681565b34801561081557600080fd5b5061034b6108243660046126a6565b6121bd565b34801561083557600080fd5b5061054d61227b565b34801561084a57600080fd5b506104c76108593660046126fd565b60086020526000908152604090205460ff1681565b34801561087a57600080fd5b50600e54610302565b34801561088f57600080fd5b5061034b61089e3660046126a6565b6122d3565b3480156108af57600080fd5b506103026108be3660046126a6565b60106020526000908152604090205481565b3480156108dc57600080fd5b506103026108eb3660046126fd565b612347565b3480156108fc57600080fd5b506104957369e23263927ae53e5ff3a898d082a83b7d6fb43881565b34801561092457600080fd5b5061030269152d02c7e14af680000081565b6000546001600160a01b03163314610961576040516330cd747160e01b815260040160405180910390fd5b6007805460ff19168215159081179091556040517f9e3a5e37224532dea67b89face185703738a228a6e8a23dee546960180d3be6490600090a250565b6000546001600160a01b031633146109c9576040516330cd747160e01b815260040160405180910390fd5b806000036109ea57604051636b81a62760e11b815260040160405180910390fd5b69d3c21bcecceda1000000811115610a155760405163751bd59f60e11b815260040160405180910390fd5b60055460408051918252602082018390527fca4cf4eae5efb9a30c5c06f74b1f0fbf706424568d0399550a56f02317095aa2910160405180910390a1600555565b60075460ff1615610a7a576040516313d0ff5960e31b815260040160405180910390fd5b600260125403610a9d576040516306fda65d60e31b815260040160405180910390fd5b60026012556000818152600c6020526040902080546001600160a01b0316610ad85760405163644b7b2160e11b815260040160405180910390fd5b60006006820154600160a01b900460ff166001811115610afa57610afa61277c565b14610b1857604051631bb5f5b360e31b815260040160405180910390fd5b80600301544210610b3c5760405163cd2810ef60e01b815260040160405180910390fd5b80546001600160a01b03163303610b665760405163c330855960e01b815260040160405180910390fd5b6000610b7a82600501548360020154612384565b90506000612710836004015483610b919190612891565b610b9b91906128be565b9050610ba781836128d2565b3414610bc6576040516359c0851f60e11b815260040160405180910390fd5b600180840180546001600160a01b0319163317905560068401805460ff60a01b1916600160a01b830217905550610bfc846123a3565b6006830154610c14906001600160a01b031682612460565b8015610c615760068301546040518281526001600160a01b039091169085907ff1d6c8ee14081f641e2073a1064d870f135f1001a301c6b14a7b9655672fec119060200160405180910390a35b604051339085907f6551e44c1e8ec713c7a4e7675a142d18af09eb92d01826ad9075e3e380f950b290600090a3505060016012555050565b6000546001600160a01b03163314610cc4576040516330cd747160e01b815260040160405180910390fd5b60008181526008602052604090205460ff16610cf357604051630169ae4b60e41b815260040160405180910390fd5b6000818152600d602052604090205415610d205760405163f1ba07a760e01b815260040160405180910390fd5b6000818152600860209081526040808320805460ff19169055600a909152812054600954909190610d53906001906128e5565b9050808214610db257600060098281548110610d7157610d716128f8565b906000526020600020015490508060098481548110610d9257610d926128f8565b6000918252602080832090910192909255918252600a9052604090208290555b6009805480610dc357610dc361290e565b600082815260208082208301600019908101839055909201909255848252600a905260408082208290555184917f8ee1131e547cdf75e14a5580303ceed0e68b75a1edcabeaac6b4912c236a36fd91a2505050565b600260125403610e3b576040516306fda65d60e31b815260040160405180910390fd5b60026012553360009081526011602052604081205490819003610e7157604051630686827b60e51b815260040160405180910390fd5b33600081815260116020526040812055610ea1907369e23263927ae53e5ff3a898d082a83b7d6fb43890836124b9565b60405181815233907fa425cd2f25f0f5e5b42a51b5666f0f053529fe6a261d0fb5b60f43f645a4523d9060200160405180910390a2506001601255565b60408051600481526024810182526020810180516001600160e01b0316630240bc6b60e21b17905290516000918291829173629075c537633132c645a18f265d59e4153ce1c691610f2f9190612924565b600060405180830381855afa9150503d8060008114610f6a576040519150601f19603f3d011682016040523d82523d6000602084013e610f6f565b606091505b509150915081610f9257604051631c6750f960e21b815260040160405180910390fd5b60008082806020019051810190610fa9919061296f565b50915091506000806001610fd057826001600160701b0316846001600160701b0316610fe5565b836001600160701b0316836001600160701b03165b9150915081600003610ffe576000965050505050505090565b8161101182670de0b6b3a7640000612891565b61101b91906128be565b965050505050505090565b600260125403611049576040516306fda65d60e31b815260040160405180910390fd5b6002601255336000908152601060205260408120549081900361107f57604051630686827b60e51b815260040160405180910390fd5b336000818152601060205260408082208290555190919083908381818185875af1925050503d80600081146110d0576040519150601f19603f3d011682016040523d82523d6000602084013e6110d5565b606091505b50509050806110f7576040516327fcd9d160e01b815260040160405180910390fd5b60405182815233907f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d59060200160405180910390a250506001601255565b600260125403611158576040516306fda65d60e31b815260040160405180910390fd5b600260128190556000828152600c6020908152604080832081516101008101835281546001600160a01b03908116825260018084015482169583019590955295820154928101929092526003810154606083015260048101546080830152600581015460a0830152600681015494851660c0830152929390929160e0840191600160a01b900460ff16908111156111f1576111f161277c565b60018111156112025761120261277c565b90525080519091506001600160a01b03166112305760405163644b7b2160e11b815260040160405180910390fd5b60008160e0015160018111156112485761124861277c565b1461126657604051631bb5f5b360e31b815260040160405180910390fd5b80516001600160a01b031633148015906112835750806060015142105b156112a15760405163942325c960e01b815260040160405180910390fd5b6000828152600c6020526040812080546001600160a01b031990811682556001820180549091169055600281018290556003810182905560048101829055600581019190915560060180546001600160a81b0319169055611301826123a3565b60608101516000908152600d60205260408120805491611320836129bf565b909155505060a081015181516001600160a01b0316600090815260116020526040812080549091906113539084906128d2565b909155505080516040516001600160a01b039091169083907fb06e9f105d9c9095d543b9cd5bfccc5690099c9d74629c34907c857b9d594e2290600090a350506001601255565b6000818152600c6020526040812080546001600160a01b03166113d05760405163644b7b2160e11b815260040160405180910390fd5b60006113e482600501548360020154612384565b90506127108260040154826113f99190612891565b61140391906128be565b61140d90826128d2565b949350505050565b6000546001600160a01b03163314611440576040516330cd747160e01b815260040160405180910390fd5b603281111561146257604051632be7087760e21b815260040160405180910390fd5b60008111801561147b57506002546001600160a01b0316155b1561149957604051630b8ed10b60e31b815260040160405180910390fd5b60035460408051918252602082018390527f528d9479e9f9889a87a3c30c7f7ba537e5e59c4c85a37733b16e57c62df61302910160405180910390a1600355565b6060818311806114eb5750600e5482115b156115095760405163561ce9bb60e01b815260040160405180910390fd5b60c861151584846128e5565b11156115345760405163784931eb60e11b815260040160405180910390fd5b600061154084846128e5565b67ffffffffffffffff811115611558576115586129d6565b604051908082528060200260200182016040528015611581578160200160208202803683370190505b509050835b838110156115e657600e81815481106115a1576115a16128f8565b90600052602060002001548286836115b991906128e5565b815181106115c9576115c96128f8565b6020908102919091010152806115de816129ec565b915050611586565b5090505b92915050565b6000546001600160a01b0316331461161b576040516330cd747160e01b815260040160405180910390fd5b60075460ff161561163f576040516313d0ff5960e31b815260040160405180910390fd5b600080546040516001600160a01b03909116907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600080546001600160a01b0319908116909155600180549091169055565b6001546001600160a01b031633146116c057604051630614e5c760e21b815260040160405180910390fd5b600154600080546040516001600160a01b0393841693909116917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e091a360018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b6117696040805161010081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081018290529060e082015290565b6000828152600c602090815260409182902082516101008101845281546001600160a01b0390811682526001808401548216948301949094526002830154948201949094526003820154606082015260048201546080820152600582015460a0820152600682015493841660c082015292909160e0840191600160a01b900460ff16908111156117fb576117fb61277c565b600181111561180c5761180c61277c565b90525092915050565b600260125403611838576040516306fda65d60e31b815260040160405180910390fd5b600260128190556000828152600c6020908152604080832081516101008101835281546001600160a01b03908116825260018084015482169583019590955295820154928101929092526003810154606083015260048101546080830152600581015460a0830152600681015494851660c0830152929390929160e0840191600160a01b900460ff16908111156118d1576118d161277c565b60018111156118e2576118e261277c565b90525080519091506001600160a01b03166119105760405163644b7b2160e11b815260040160405180910390fd5b60018160e0015160018111156119285761192861277c565b1461194657604051634065aaf160e11b815260040160405180910390fd5b806060015142101561196b5760405163d0404f8560e01b815260040160405180910390fd5b6000828152600c6020908152604080832080546001600160a01b0319908116825560018201805490911690556002810184905560038101849055600481018490556005810184905560060180546001600160a81b031916905560608401518352600d90915281208054916119de836129bf565b919050555060006119f78260a001518360400151612384565b82516001600160a01b0316600090815260106020526040812080549293508392909190611a259084906128d2565b909155505060a08201516020808401516001600160a01b031660009081526011909152604081208054909190611a5c9084906128d2565b9250508190555081602001516001600160a01b031682600001516001600160a01b0316847f4b3784916640b601962572cc8a071940c0b21f692a52df0c32e6945c4738995460405160405180910390a45050600160125550565b60606000805b600954811015611b0b574260098281548110611ada57611ada6128f8565b90600052602060002001541115611af95781611af5816129ec565b9250505b80611b03816129ec565b915050611abc565b5060008167ffffffffffffffff811115611b2757611b276129d6565b604051908082528060200260200182016040528015611b50578160200160208202803683370190505b5090506000805b600954811015611be1574260098281548110611b7557611b756128f8565b90600052602060002001541115611bcf5760098181548110611b9957611b996128f8565b9060005260206000200154838380611bb0906129ec565b945081518110611bc257611bc26128f8565b6020026020010181815250505b80611bd9816129ec565b915050611b57565b50909392505050565b600e8181548110611bfa57600080fd5b600091825260209091200154905081565b60075460009060ff1615611c32576040516313d0ff5960e31b815260040160405180910390fd5b600260125403611c55576040516306fda65d60e31b815260040160405180910390fd5b6002601255600554831015611c7d57604051636b81a62760e11b815260040160405180910390fd5b60008281526008602052604090205460ff16611cac57604051630169ae4b60e41b815260040160405180910390fd5b428211611ccc5760405163079955a160e41b815260040160405180910390fd5b600654611cd990426128d2565b821115611cf957604051632414776560e11b815260040160405180910390fd5b600b8054906000611d09836129ec565b90915550600454604080516101008101825233815260006020820181905291810187905260608101869052600354608082015260a081018390526002546001600160a01b031660c082015292935090919060e08201526000838152600c6020908152604091829020835181546001600160a01b03199081166001600160a01b039283161783559285015160018084018054861692841692909217909155938501516002830155606085015160038301556080850151600483015560a0850151600583015560c085015160068301805494851691909216908117825560e08601519294929391926001600160a81b03199092161790600160a01b908490811115611e1457611e1461277c565b021790555050600e80546000858152600f60209081526040808320849055600184019094557fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd909201869055868152600d9091529081208054925090611e79836129ec565b9190505550611e9e7369e23263927ae53e5ff3a898d082a83b7d6fb4383330846125ab565b82336001600160a01b0316837f146495679bcf320eb08782de7ec9445e5df6c7e605c8fd3e1c529b6dbca73cd687604051611edb91815260200190565b60405180910390a450600160125592915050565b60006115ea60045483612384565b6000546001600160a01b03163314611f28576040516330cd747160e01b815260040160405180910390fd5b68056bc75e2d63100000811080611f48575069152d02c7e14af680000081115b15611f66576040516334c7a5e160e21b815260040160405180910390fd5b611f78670de0b6b3a764000082612a05565b15611f96576040516334c7a5e160e21b815260040160405180910390fd5b60045460408051918252602082018390527f0f2cfa1d57de81a69554b8d29c87f925791ee174792d6023e4e154ac11fff4f4910160405180910390a1600455565b6000546001600160a01b03163314612002576040516330cd747160e01b815260040160405180910390fd5b806000036120235760405163841a468560e01b815260040160405180910390fd5b6301e285008111156120485760405163751bd59f60e11b815260040160405180910390fd5b60065460408051918252602082018390527f073abaf7e45ed9cbaece9163c31bebd5fcb246f1071042474650c2c5885a5047910160405180910390a1600655565b60098181548110611bfa57600080fd5b6000546001600160a01b031633146120c4576040516330cd747160e01b815260040160405180910390fd5b6009546104b0116120e85760405163751bd59f60e11b815260040160405180910390fd5b4281116121085760405163079955a160e41b815260040160405180910390fd5b60008181526008602052604090205460ff161561213857604051633d29014b60e01b815260040160405180910390fd5b6000818152600860209081526040808320805460ff1916600190811790915560098054600a909452828520849055908301815583527f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af9091018390555182917f7385558d62442e3e76f42474f7caaa194432a0e6be9c74f4c59f854061df656091a250565b6000546001600160a01b031633146121e8576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b03811615801561220157506000600354115b1561221f5760405163dfe5a74960e01b815260040160405180910390fd5b6002546040516001600160a01b038084169216907faaebcf1bfa00580e41d966056b48521fa9f202645c86d4ddf28113e617c1b1d390600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b606060098054806020026020016040519081016040528092919081815260200182805480156122c957602002820191906000526020600020905b8154815260200190600101908083116122b5575b5050505050905090565b6000546001600160a01b031633146122fe576040516330cd747160e01b815260040160405180910390fd5b6001600160a01b038116612325576040516349e27cff60e01b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b0392909216919091179055565b60008061235660045484612384565b9050612710600354826123699190612891565b61237391906128be565b61237d90826128d2565b9392505050565b6000670de0b6b3a76400006123998385612891565b61237d91906128be565b6000818152600f6020526040812054600e549091906123c4906001906128e5565b9050808214612423576000600e82815481106123e2576123e26128f8565b9060005260206000200154905080600e8481548110612403576124036128f8565b6000918252602080832090910192909255918252600f9052604090208290555b600e8054806124345761243461290e565b600082815260208082208301600019908101839055909201909255938152600f90935250506040812055565b80158061247557506001600160a01b03821615155b61248157612481612a19565b80156124b5576001600160a01b038216600090815260106020526040812080548392906124af9084906128d2565b90915550505b5050565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180516001600160e01b031663a9059cbb60e01b17905291516000928392908716916125159190612924565b6000604051808303816000865af19150503d8060008114612552576040519150601f19603f3d011682016040523d82523d6000602084013e612557565b606091505b50915091508115806125865750600081511180156125865750808060200190518101906125849190612a2f565b155b156125a45760405163fe66d06160e01b815260040160405180910390fd5b5050505050565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180516001600160e01b03166323b872dd60e01b179052915160009283929088169161260f9190612924565b6000604051808303816000865af19150503d806000811461264c576040519150601f19603f3d011682016040523d82523d6000602084013e612651565b606091505b509150915081158061268057506000815111801561268057508080602001905181019061267e9190612a2f565b155b1561269e5760405163fe66d06160e01b815260040160405180910390fd5b505050505050565b6000602082840312156126b857600080fd5b81356001600160a01b038116811461237d57600080fd5b80151581146126dd57600080fd5b50565b6000602082840312156126f257600080fd5b813561237d816126cf565b60006020828403121561270f57600080fd5b5035919050565b6000806040838503121561272957600080fd5b50508035926020909101359150565b6020808252825182820181905260009190848201906040850190845b8181101561277057835183529284019291840191600101612754565b50909695505050505050565b634e487b7160e01b600052602160045260246000fd5b600281106127b057634e487b7160e01b600052602160045260246000fd5b9052565b60006101008201905060018060a01b0380845116835280602085015116602084015260408401516040840152606084015160608401526080840151608084015260a084015160a08401528060c08501511660c08401525060e083015161281d60e0840182612792565b5092915050565b6001600160a01b038981168252888116602083015260408201889052606082018790526080820186905260a08201859052831660c0820152610100810161286e60e0830184612792565b9998505050505050505050565b634e487b7160e01b600052601160045260246000fd5b80820281158282048414176115ea576115ea61287b565b634e487b7160e01b600052601260045260246000fd5b6000826128cd576128cd6128a8565b500490565b808201808211156115ea576115ea61287b565b818103818111156115ea576115ea61287b565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b6000825160005b81811015612945576020818601810151858301520161292b565b506000920191825250919050565b80516001600160701b038116811461296a57600080fd5b919050565b60008060006060848603121561298457600080fd5b61298d84612953565b925061299b60208501612953565b9150604084015163ffffffff811681146129b457600080fd5b809150509250925092565b6000816129ce576129ce61287b565b506000190190565b634e487b7160e01b600052604160045260246000fd5b6000600182016129fe576129fe61287b565b5060010190565b600082612a1457612a146128a8565b500690565b634e487b7160e01b600052600160045260246000fd5b600060208284031215612a4157600080fd5b815161237d816126cf56fea2646970667358221220cbe25f22d90e44b6684b84c2ae357da7f7727b497f2e81956587d5e2d225793a64736f6c63430008140033