Contract Address Details

0x1000000000000000000000000000000000000003

Contract Name
PriceSubmitter
Creator
Balance
0 SGB
Tokens
Fetching tokens...
Transactions
21,920,873 Transactions
Transfers
0 Transfers
Gas Used
13,316,616,615,309
Last Balance Update
19119899
Contract name:
PriceSubmitter




Optimization enabled
true
Compiler version
v0.7.6+commit.7338295f




Optimization runs
200
EVM Version
default




Verified at
2021-09-17 15:42:52.127946Z

Contract source code

// Sources flattened with hardhat v2.3.0 https://hardhat.org
// File contracts/governance/implementation/GovernedBase.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.7.6;
/**
* @title Governed Base
* @notice This abstract base class defines behaviors for a governed contract.
* @dev This class is abstract so that specific behaviors can be defined for the constructor.
* Contracts should not be left ungoverned, but not all contract will have a constructor
* (for example those pre-defined in genesis).
**/
abstract contract GovernedBase {
address public governance;
address public proposedGovernance;
bool private initialised;
event GovernanceProposed(address proposedGovernance);
event GovernanceUpdated (address oldGovernance, address newGoveranance);
modifier onlyGovernance () {
require (msg.sender == governance, "only governance");
_;
}
constructor(address _governance) {
if (_governance != address(0)) {
initialise(_governance);
}
}
/**
* @notice First of a two step process for turning over governance to another address.
* @param _governance The address to propose to receive governance role.
* @dev Must hold governance to propose another address.
*/
function proposeGovernance(address _governance) external onlyGovernance {
proposedGovernance = _governance;
emit GovernanceProposed(_governance);
}
/**
* @notice Once proposed, claimant can claim the governance role as the second of a two-step process.
*/
function claimGovernance() external {
require(msg.sender == proposedGovernance, "not claimaint");
emit GovernanceUpdated(governance, proposedGovernance);
governance = proposedGovernance;
proposedGovernance = address(0);
}
/**
* @notice In a one-step process, turn over governance to another address.
* @dev Must hold governance to transfer.
*/
function transferGovernance(address _governance) external onlyGovernance {
emit GovernanceUpdated(governance, _governance);
governance = _governance;
proposedGovernance = address(0);
}
/**
* @notice Initialize the governance address if not first initialized.
*/
function initialise(address _governance) public virtual {
require(initialised == false, "initialised != false");
initialised = true;
emit GovernanceUpdated(governance, _governance);
governance = _governance;
proposedGovernance = address(0);
}
}
// File contracts/governance/implementation/GovernedAtGenesis.sol
//
pragma solidity 0.7.6;
/**
* @title Governed At Genesis
* @dev This contract enforces a fixed governance address when the constructor
* is not executed on a contract (for instance when directly loaded to the genesis block).
* This is required to fix governance on a contract when the network starts, at such point
* where theoretically no accounts yet exist, and leaving it ungoverned could result in a race
* to claim governance by an unauthorized address.
**/
contract GovernedAtGenesis is GovernedBase {
constructor(address _governance) GovernedBase(_governance) { }
/**
* @notice Set governance to a fixed address when constructor is not called.
**/
function initialiseFixedAddress() public virtual returns (address) {
address governanceAddress = address(0xfffEc6C83c8BF5c3F4AE0cCF8c45CE20E4560BD7);
super.initialise(governanceAddress);
return governanceAddress;
}
/**
* @notice Disallow initialise to be called
* @param _governance The governance address for initial claiming
**/
// solhint-disable-next-line no-unused-vars
function initialise(address _governance) public override pure {
assert(false);
}
}
// File contracts/genesis/interface/IFtsoGenesis.sol
//
pragma solidity 0.7.6;
interface IFtsoGenesis {
/**
* @notice Submits price hash for current epoch - only price submitter
* @param _sender Sender address
* @param _epochId Target epoch id to which hashes are submitted
* @param _hash Hashed price and random number
* @notice Emits PriceHashSubmitted event.
*/
function submitPriceHashSubmitter(address _sender, uint256 _epochId, bytes32 _hash) external;
/**
* @notice Reveals submitted price during epoch reveal period - only price submitter
* @param _voter Voter address
* @param _epochId Id of the epoch in which the price hash was submitted
* @param _price Submitted price in USD
* @param _random Submitted random number
* @notice The hash of _price and _random must be equal to the submitted hash
* @notice Emits PriceRevealed event
*/
function revealPriceSubmitter(
address _voter,
uint256 _epochId,
uint256 _price,
uint256 _random,
uint256 _wNatVP
) external;
/**
* @notice Get (and cache) wNat vote power for specified voter and given epoch id
* @param _voter Voter address
* @param _epochId Id of the epoch in which the price hash was submitted
* @return wNat vote power
*/
function wNatVotePowerCached(address _voter, uint256 _epochId) external returns (uint256);
}
// File contracts/genesis/interface/IFtsoRegistryGenesis.sol
//
pragma solidity 0.7.6;
interface IFtsoRegistryGenesis {
function getFtsos(uint256[] memory _indices) external view returns(IFtsoGenesis[] memory _ftsos);
}
// File contracts/userInterfaces/IPriceSubmitter.sol
//
pragma solidity 0.7.6;
interface IPriceSubmitter {
/**
* Event emitted when price hashes were submitted through PriceSubmitter.
* @param submitter the address of the sender
* @param epochId current price epoch id
* @param ftsos array of ftsos that correspond to the indexes in call
* @param hashes the submitted hashes
* @param timestamp current block timestamp
*/
event PriceHashesSubmitted(
address indexed submitter,
uint256 indexed epochId,
IFtsoGenesis[] ftsos,
bytes32[] hashes,
uint256 timestamp
);
/**
* Event emitted when prices were revealed through PriceSubmitter.
* @param voter the address of the sender
* @param epochId id of the epoch in which the price hash was submitted
* @param ftsos array of ftsos that correspond to the indexes in the call
* @param prices the submitted prices
* @param timestamp current block timestamp
*/
event PricesRevealed(
address indexed voter,
uint256 indexed epochId,
IFtsoGenesis[] ftsos,
uint256[] prices,
uint256[] randoms,
uint256 timestamp
);
/**
* @notice Submits price hashes for current epoch
* @param _epochId Target epoch id to which hashes are submitted
* @param _ftsoIndices List of ftso indices
* @param _hashes List of hashed price and random number
* @notice Emits PriceHashesSubmitted event
*/
function submitPriceHashes(
uint256 _epochId,
uint256[] memory _ftsoIndices,
bytes32[] memory _hashes
) external;
/**
* @notice Reveals submitted prices during epoch reveal period
* @param _epochId Id of the epoch in which the price hashes was submitted
* @param _ftsoIndices List of ftso indices
* @param _prices List of submitted prices in USD
* @param _randoms List of submitted random numbers
* @notice The hash of _price and _random must be equal to the submitted hash
* @notice Emits PricesRevealed event
*/
function revealPrices(
uint256 _epochId,
uint256[] memory _ftsoIndices,
uint256[] memory _prices,
uint256[] memory _randoms
) external;
/**
* Returns bitmap of all ftso's for which `_voter` is allowed to submit prices/hashes.
* If voter is allowed to vote for ftso at index (see *_FTSO_INDEX), the corrsponding
* bit in the result will be 1.
*/
function voterWhitelistBitmap(address _voter) external view returns (uint256);
function getVoterWhitelister() external view returns (address);
function getFtsoRegistry() external view returns (IFtsoRegistryGenesis);
function getFtsoManager() external view returns (address);
}
// File contracts/genesis/interface/IIPriceSubmitter.sol
//
pragma solidity 0.7.6;
interface IIPriceSubmitter is IPriceSubmitter {
/**
* Sets ftso registry, voter whitelist and ftso manager contracts.
* Only governance can call this method.
* If replacing the registry or the whitelist and the old one is not empty, make sure to replicate the state,
* otherwise internal whitelist bitmaps won't match.
*/
function setContractAddresses(
IFtsoRegistryGenesis _ftsoRegistry,
address _voterWhitelister,
address _ftsoManager
) external;
/**
* Set trusted addresses that are always allowed to submit and reveal.
* Only ftso manager can call this method.
*/
function setTrustedAddresses(address[] memory _trustedAddresses) external;
/**
* Called from whitelister when new voter has been whitelisted.
*/
function voterWhitelisted(address _voter, uint256 _ftsoIndex) external;
/**
* Called from whitelister when one or more voters have been removed.
*/
function votersRemovedFromWhitelist(address[] memory _voters, uint256 _ftsoIndex) external;
/**
* Returns a list of trusted addresses that are always allowed to submit and reveal.
*/
function getTrustedAddresses() external view returns (address[] memory);
}
// File contracts/genesis/implementation/PriceSubmitter.sol
//
pragma solidity 0.7.6;
/**
* @title Price submitter
* @notice A contract used to submit/reveal prices to multiple Flare Time Series Oracles in one transaction
*/
contract PriceSubmitter is IIPriceSubmitter, GovernedAtGenesis {
string internal constant ERR_ARRAY_LENGTHS = "Array lengths do not match";
string internal constant ERR_NOT_WHITELISTED = "Not whitelisted";
string internal constant ERR_FTSO_MANAGER_ONLY = "FTSOManager only";
string internal constant ERR_WHITELISTER_ONLY = "Voter whitelister only";
IFtsoRegistryGenesis internal ftsoRegistry;
address internal ftsoManager;
address internal voterWhitelister;
// Bit at index `i` corresponds to being whitelisted for vote on ftso at index `i`
mapping(address => uint256) internal whitelistedFtsoBitmap;
address[] internal trustedAddresses;
// for checking addresses at submit/reveal
mapping(address => bool) internal trustedAddressesMapping;
modifier onlyFtsoManager {
require(msg.sender == ftsoManager, ERR_FTSO_MANAGER_ONLY);
_;
}
modifier onlyWhitelister {
require(msg.sender == voterWhitelister, ERR_WHITELISTER_ONLY);
_;
}
/**
* @dev This constructor should contain no code as this contract is pre-loaded into the genesis block.
* The super constructor is called for testing convenience.
*/
constructor() GovernedAtGenesis(address(0)) {
/* empty block */
}
/**
* Sets ftso registry, voter whitelist and ftso manager contracts.
* Only governance can call this method.
* If replacing the registry or the whitelist and the old one is not empty, make sure to replicate the state,
* otherwise internal whitelist bitmaps won't match.
*/
function setContractAddresses(
IFtsoRegistryGenesis _ftsoRegistry,
address _voterWhitelister,
address _ftsoManager
)
external override
onlyGovernance
{
ftsoRegistry = _ftsoRegistry;
voterWhitelister = _voterWhitelister;
ftsoManager = _ftsoManager;
}
/**
* Set trusted addresses that are always allowed to submit and reveal.
* Only ftso manager can call this method.
*/
function setTrustedAddresses(address[] memory _trustedAddresses) external override onlyFtsoManager {
// remove old addresses mapping
uint256 len = trustedAddresses.length;
for (uint256 i = 0; i < len; i++) {
trustedAddressesMapping[trustedAddresses[i]] = false;
}
// set new addresses mapping
len = _trustedAddresses.length;
for (uint256 i = 0; i < len; i++) {
trustedAddressesMapping[_trustedAddresses[i]] = true;
}
trustedAddresses = _trustedAddresses;
}
/**
* Called from whitelister when new voter has been whitelisted.
*/
function voterWhitelisted(address _voter, uint256 _ftsoIndex) external override onlyWhitelister {
whitelistedFtsoBitmap[_voter] |= 1 << _ftsoIndex;
}
/**
* Called from whitelister when one or more voters have been removed.
*/
function votersRemovedFromWhitelist(address[] memory _removedVoters, uint256 _ftsoIndex)
external override
onlyWhitelister
{
for (uint256 i = 0; i < _removedVoters.length; i++) {
whitelistedFtsoBitmap[_removedVoters[i]] &= ~(1 << _ftsoIndex);
}
}
/**
* @notice Submits price hashes for current epoch
* @param _ftsoIndices List of ftso indices
* @param _hashes List of hashed price and random number
* @notice Emits PriceHashesSubmitted event
*/
function submitPriceHashes(
uint256 _epochId,
uint256[] memory _ftsoIndices,
bytes32[] memory _hashes
) external override {
// Submit the prices
uint256 length = _ftsoIndices.length;
require(length == _hashes.length, ERR_ARRAY_LENGTHS);
IFtsoGenesis[] memory ftsos = ftsoRegistry.getFtsos(_ftsoIndices);
uint256 allowedBitmask = whitelistedFtsoBitmap[msg.sender];
bool isTrustedAddress = false;
for (uint256 i = 0; i < length; i++) {
uint256 ind = _ftsoIndices[i];
if (allowedBitmask & (1 << ind) == 0) {
if (!isTrustedAddress) {
if (trustedAddressesMapping[msg.sender]) {
isTrustedAddress = true;
} else {
revert(ERR_NOT_WHITELISTED);
}
}
}
ftsos[i].submitPriceHashSubmitter(msg.sender, _epochId, _hashes[i]);
}
emit PriceHashesSubmitted(msg.sender, _epochId, ftsos, _hashes, block.timestamp);
}
/**
* @notice Reveals submitted prices during epoch reveal period
* @param _epochId Id of the epoch in which the price hashes was submitted
* @param _ftsoIndices List of ftso indices
* @param _prices List of submitted prices in USD
* @param _randoms List of submitted random numbers
* @notice The hash of _price and _random must be equal to the submitted hash
* @notice Emits PricesRevealed event
*/
function revealPrices(
uint256 _epochId,
uint256[] memory _ftsoIndices,
uint256[] memory _prices,
uint256[] memory _randoms
)
external override
{
uint256 length = _ftsoIndices.length;
require(length == _prices.length, ERR_ARRAY_LENGTHS);
require(length == _randoms.length, ERR_ARRAY_LENGTHS);
IFtsoGenesis[] memory ftsos = ftsoRegistry.getFtsos(_ftsoIndices);
uint256 allowedBitmask = whitelistedFtsoBitmap[msg.sender];
bool isTrustedAddress = false;
uint256 wNatVP = uint256(-1);
for (uint256 i = 0; i < length; i++) {
uint256 ind = _ftsoIndices[i];
if (allowedBitmask & (1 << ind) == 0) {
if (!isTrustedAddress) {
if (trustedAddressesMapping[msg.sender]) {
isTrustedAddress = true;
} else {
revert(ERR_NOT_WHITELISTED);
}
}
}
// read native VP only once
if (wNatVP == uint256(-1)) {
wNatVP = ftsos[i].wNatVotePowerCached(msg.sender, _epochId);
}
// call reveal price on ftso
ftsos[i].revealPriceSubmitter(msg.sender, _epochId, _prices[i], _randoms[i], wNatVP);
}
emit PricesRevealed(msg.sender, _epochId, ftsos, _prices, _randoms, block.timestamp);
}
/**
* Returns bitmap of all ftso's for which `_voter` is allowed to submit prices/hashes.
* If voter is allowed to vote for ftso at index (see *_FTSO_INDEX), the corrsponding
* bit in the result will be 1.
*/
function voterWhitelistBitmap(address _voter) external view override returns (uint256) {
return whitelistedFtsoBitmap[_voter];
}
function getTrustedAddresses() external view override returns (address[] memory) {
return trustedAddresses;
}
function getVoterWhitelister() external view override returns (address) {
return voterWhitelister;
}
function getFtsoRegistry() external view override returns (IFtsoRegistryGenesis) {
return ftsoRegistry;
}
function getFtsoManager() external view override returns (address) {
return ftsoManager;
}
}

Contract ABI

[{"type":"constructor","stateMutability":"nonpayable","inputs":[]},{"type":"event","name":"GovernanceProposed","inputs":[{"type":"address","name":"proposedGovernance","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"GovernanceUpdated","inputs":[{"type":"address","name":"oldGovernance","internalType":"address","indexed":false},{"type":"address","name":"newGoveranance","internalType":"address","indexed":false}],"anonymous":false},{"type":"event","name":"PriceHashesSubmitted","inputs":[{"type":"address","name":"submitter","internalType":"address","indexed":true},{"type":"uint256","name":"epochId","internalType":"uint256","indexed":true},{"type":"address[]","name":"ftsos","internalType":"contract IFtsoGenesis[]","indexed":false},{"type":"bytes32[]","name":"hashes","internalType":"bytes32[]","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"event","name":"PricesRevealed","inputs":[{"type":"address","name":"voter","internalType":"address","indexed":true},{"type":"uint256","name":"epochId","internalType":"uint256","indexed":true},{"type":"address[]","name":"ftsos","internalType":"contract IFtsoGenesis[]","indexed":false},{"type":"uint256[]","name":"prices","internalType":"uint256[]","indexed":false},{"type":"uint256[]","name":"randoms","internalType":"uint256[]","indexed":false},{"type":"uint256","name":"timestamp","internalType":"uint256","indexed":false}],"anonymous":false},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"claimGovernance","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getFtsoManager","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"contract IFtsoRegistryGenesis"}],"name":"getFtsoRegistry","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address[]","name":"","internalType":"address[]"}],"name":"getTrustedAddresses","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"getVoterWhitelister","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"governance","inputs":[]},{"type":"function","stateMutability":"pure","outputs":[],"name":"initialise","inputs":[{"type":"address","name":"_governance","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"initialiseFixedAddress","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"proposeGovernance","inputs":[{"type":"address","name":"_governance","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"proposedGovernance","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"revealPrices","inputs":[{"type":"uint256","name":"_epochId","internalType":"uint256"},{"type":"uint256[]","name":"_ftsoIndices","internalType":"uint256[]"},{"type":"uint256[]","name":"_prices","internalType":"uint256[]"},{"type":"uint256[]","name":"_randoms","internalType":"uint256[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setContractAddresses","inputs":[{"type":"address","name":"_ftsoRegistry","internalType":"contract IFtsoRegistryGenesis"},{"type":"address","name":"_voterWhitelister","internalType":"address"},{"type":"address","name":"_ftsoManager","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"setTrustedAddresses","inputs":[{"type":"address[]","name":"_trustedAddresses","internalType":"address[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"submitPriceHashes","inputs":[{"type":"uint256","name":"_epochId","internalType":"uint256"},{"type":"uint256[]","name":"_ftsoIndices","internalType":"uint256[]"},{"type":"bytes32[]","name":"_hashes","internalType":"bytes32[]"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"transferGovernance","inputs":[{"type":"address","name":"_governance","internalType":"address"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"voterWhitelistBitmap","inputs":[{"type":"address","name":"_voter","internalType":"address"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"voterWhitelisted","inputs":[{"type":"address","name":"_voter","internalType":"address"},{"type":"uint256","name":"_ftsoIndex","internalType":"uint256"}]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"votersRemovedFromWhitelist","inputs":[{"type":"address[]","name":"_removedVoters","internalType":"address[]"},{"type":"uint256","name":"_ftsoIndex","internalType":"uint256"}]}]
            

Deployed ByteCode

0x608060405234801561001057600080fd5b50600436106101165760003560e01c80639d6a890f116100a2578063c373a08e11610071578063c373a08e1461051b578063c5adc53914610541578063c9f960eb1461066b578063d38bfff414610673578063ffacb84e1461069957610116565b80639d6a890f146104205780639d986f91146104465780639ec2b58114610472578063b39c68581461051357610116565b806371e1fad9116100e957806371e1fad9146102fd57806376794efb146103055780637ac420ad146103a85780638ab63380146103e05780638c9d28b61461041857610116565b80635aa6e6751461011b5780635d36b1901461013f57806360848b441461014957806360f7ac97146102f5575b600080fd5b6101236106f1565b604080516001600160a01b039092168252519081900360200190f35b610147610700565b005b6101476004803603608081101561015f57600080fd5b81359190810190604081016020820135600160201b81111561018057600080fd5b82018360208201111561019257600080fd5b803590602001918460208302840111600160201b831117156101b357600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561020257600080fd5b82018360208201111561021457600080fd5b803590602001918460208302840111600160201b8311171561023557600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b81111561028457600080fd5b82018360208201111561029657600080fd5b803590602001918460208302840111600160201b831117156102b757600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295506107c2945050505050565b610123610dbe565b610123610dcd565b6101476004803603604081101561031b57600080fd5b810190602081018135600160201b81111561033557600080fd5b82018360208201111561034757600080fd5b803590602001918460208302840111600160201b8311171561036857600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295505091359250610ddc915050565b6103ce600480360360208110156103be57600080fd5b50356001600160a01b0316610ebd565b60408051918252519081900360200190f35b610147600480360360608110156103f657600080fd5b506001600160a01b038135811691602081013582169160409091013516610ed8565b610123610f68565b6101476004803603602081101561043657600080fd5b50356001600160a01b0316610f77565b6101476004803603604081101561045c57600080fd5b506001600160a01b038135169060200135610f79565b6101476004803603602081101561048857600080fd5b810190602081018135600160201b8111156104a257600080fd5b8201836020820111156104b457600080fd5b803590602001918460208302840111600160201b831117156104d557600080fd5b919080806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250929550611029945050505050565b610123611177565b6101476004803603602081101561053157600080fd5b50356001600160a01b0316611186565b6101476004803603606081101561055757600080fd5b81359190810190604081016020820135600160201b81111561057857600080fd5b82018360208201111561058a57600080fd5b803590602001918460208302840111600160201b831117156105ab57600080fd5b9190808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152509295949360208101935035915050600160201b8111156105fa57600080fd5b82018360208201111561060c57600080fd5b803590602001918460208302840111600160201b8311171561062d57600080fd5b91908080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525092955061122b945050505050565b6101236115e6565b6101476004803603602081101561068957600080fd5b50356001600160a01b031661160b565b6106a16116cd565b60408051602080825283518183015283519192839290830191858101910280838360005b838110156106dd5781810151838201526020016106c5565b505050509050019250505060405180910390f35b6000546001600160a01b031681565b6001546001600160a01b0316331461074f576040805162461bcd60e51b815260206004820152600d60248201526c1b9bdd0818db185a5b585a5b9d609a1b604482015290519081900360640190fd5b600054600154604080516001600160a01b03938416815292909116602083015280517f434a2db650703b36c824e745330d6397cdaa9ee2cc891a4938ae853e1c50b68d9281900390910190a160018054600080546001600160a01b03199081166001600160a01b03841617909155169055565b8251825160408051808201909152601a815279082e4e4c2f240d8cadccee8d0e640c8de40dcdee840dac2e8c6d60331b60208201529082146108825760405162461bcd60e51b81526004018080602001828103825283818151815260200191508051906020019080838360005b8381101561084757818101518382015260200161082f565b50505050905090810190601f1680156108745780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50815181146040518060400160405280601a815260200179082e4e4c2f240d8cadccee8d0e640c8de40dcdee840dac2e8c6d60331b815250906109065760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561084757818101518382015260200161082f565b506002546040516313968ea760e31b81526020600482018181528751602484015287516000946001600160a01b031693639cb47538938a939283926044019180860191028083838b5b8381101561096757818101518382015260200161094f565b505050509050019250505060006040518083038186803b15801561098a57600080fd5b505afa15801561099e573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405260208110156109c757600080fd5b8101908080516040519392919084600160201b8211156109e657600080fd5b9083019060208201858111156109fb57600080fd5b82518660208202830111600160201b82111715610a1757600080fd5b82525081516020918201928201910280838360005b83811015610a44578181015183820152602001610a2c565b5050505091909101604090815233600090815260056020529081205495965093506000199250839150505b85811015610c9e576000898281518110610a8557fe5b60200260200101519050806001901b851660001415610b2e5783610b2e573360009081526007602052604090205460ff1615610ac45760019350610b2e565b604080518082018252600f81526e139bdd081dda1a5d195b1a5cdd1959608a1b6020808301918252925162461bcd60e51b8152600481019384528251602482015282519293928392604490920191908083836000831561084757818101518382015260200161082f565b600019831415610bd157858281518110610b4457fe5b60200260200101516001600160a01b031663f72cab28338d6040518363ffffffff1660e01b815260040180836001600160a01b0316815260200182815260200192505050602060405180830381600087803b158015610ba257600080fd5b505af1158015610bb6573d6000803e3d6000fd5b505050506040513d6020811015610bcc57600080fd5b505192505b858281518110610bdd57fe5b60200260200101516001600160a01b03166355f7b69b338d8c8681518110610c0157fe5b60200260200101518c8781518110610c1557fe5b6020026020010151886040518663ffffffff1660e01b815260040180866001600160a01b0316815260200185815260200184815260200183815260200182815260200195505050505050600060405180830381600087803b158015610c7957600080fd5b505af1158015610c8d573d6000803e3d6000fd5b505060019093019250610a6f915050565b5088336001600160a01b03167fa32444a31df2f9a116229eec3193d223a6bad89f7670ff17b8e5c7014a377da1868a8a4260405180806020018060200180602001858152602001848103845288818151815260200191508051906020019060200280838360005b83811015610d1d578181015183820152602001610d05565b50505050905001848103835287818151815260200191508051906020019060200280838360005b83811015610d5c578181015183820152602001610d44565b50505050905001848103825286818151815260200191508051906020019060200280838360005b83811015610d9b578181015183820152602001610d83565b5050505090500197505050505050505060405180910390a3505050505050505050565b6001546001600160a01b031681565b6004546001600160a01b031690565b600454604080518082019091526016815275566f7465722077686974656c6973746572206f6e6c7960501b6020820152906001600160a01b03163314610e635760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561084757818101518382015260200161082f565b5060005b8251811015610eb857816001901b1960056000858481518110610e8657fe5b6020908102919091018101516001600160a01b0316825281019190915260400160002080549091169055600101610e67565b505050565b6001600160a01b031660009081526005602052604090205490565b6000546001600160a01b03163314610f29576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b600280546001600160a01b039485166001600160a01b031991821617909155600480549385169382169390931790925560038054919093169116179055565b6002546001600160a01b031690565bfe5b600454604080518082019091526016815275566f7465722077686974656c6973746572206f6e6c7960501b6020820152906001600160a01b031633146110005760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561084757818101518382015260200161082f565b506001600160a01b0390911660009081526005602052604090208054600190921b919091179055565b60035460408051808201909152601081526f4654534f4d616e61676572206f6e6c7960801b6020820152906001600160a01b031633146110aa5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561084757818101518382015260200161082f565b5060065460005b8181101561110857600060076000600684815481106110cc57fe5b6000918252602080832091909101546001600160a01b031683528201929092526040019020805460ff19169115159190911790556001016110b1565b5050805160005b818110156111635760016007600085848151811061112957fe5b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff191691151591909117905560010161110f565b508151610eb8906006906020850190611809565b6003546001600160a01b031690565b6000546001600160a01b031633146111d7576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b600180546001600160a01b0383166001600160a01b0319909116811790915560408051918252517f1f95fb40be3a947982072902a887b521248d1d8931a39eb38f84f4d6fd758b699181900360200190a150565b8151815160408051808201909152601a815279082e4e4c2f240d8cadccee8d0e640c8de40dcdee840dac2e8c6d60331b60208201529082146112ae5760405162461bcd60e51b815260206004820181815283516024840152835190928392604490910191908501908083836000831561084757818101518382015260200161082f565b506002546040516313968ea760e31b81526020600482018181528651602484015286516000946001600160a01b031693639cb475389389939283926044019180860191028083838b5b8381101561130f5781810151838201526020016112f7565b505050509050019250505060006040518083038186803b15801561133257600080fd5b505afa158015611346573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052602081101561136f57600080fd5b8101908080516040519392919084600160201b82111561138e57600080fd5b9083019060208201858111156113a357600080fd5b82518660208202830111600160201b821117156113bf57600080fd5b82525081516020918201928201910280838360005b838110156113ec5781810151838201526020016113d4565b50505050919091016040908152336000908152600560205290812054959650935083925050505b8481101561150e57600087828151811061142957fe5b60200260200101519050806001901b8416600014156114645782611464573360009081526007602052604090205460ff1615610ac457600192505b84828151811061147057fe5b60200260200101516001600160a01b03166327bd2ad5338b8a868151811061149457fe5b60200260200101516040518463ffffffff1660e01b815260040180846001600160a01b031681526020018381526020018281526020019350505050600060405180830381600087803b1580156114e957600080fd5b505af11580156114fd573d6000803e3d6000fd5b505060019093019250611413915050565b5086336001600160a01b03167f90c022ade239639b1f8c4ebb8a76df5e03a7129df46cf9bcdae3c1450ea35434858842604051808060200180602001848152602001838103835286818151815260200191508051906020019060200280838360005b83811015611588578181015183820152602001611570565b50505050905001838103825285818151815260200191508051906020019060200280838360005b838110156115c75781810151838201526020016115af565b505050509050019550505050505060405180910390a350505050505050565b600073fffec6c83c8bf5c3f4ae0ccf8c45ce20e4560bd76116068161172f565b905090565b6000546001600160a01b0316331461165c576040805162461bcd60e51b815260206004820152600f60248201526e6f6e6c7920676f7665726e616e636560881b604482015290519081900360640190fd5b600054604080516001600160a01b039283168152918316602083015280517f434a2db650703b36c824e745330d6397cdaa9ee2cc891a4938ae853e1c50b68d9281900390910190a1600080546001600160a01b039092166001600160a01b0319928316179055600180549091169055565b6060600680548060200260200160405190810160405280929190818152602001828054801561172557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311611707575b5050505050905090565b600154600160a01b900460ff1615611785576040805162461bcd60e51b8152602060048201526014602482015273696e697469616c6973656420213d2066616c736560601b604482015290519081900360640190fd5b6001805460ff60a01b1916600160a01b179055600054604080516001600160a01b039283168152918316602083015280517f434a2db650703b36c824e745330d6397cdaa9ee2cc891a4938ae853e1c50b68d9281900390910190a1600080546001600160a01b039092166001600160a01b0319928316179055600180549091169055565b82805482825590600052602060002090810192821561185e579160200282015b8281111561185e57825182546001600160a01b0319166001600160a01b03909116178255602090920191600190910190611829565b5061186a92915061186e565b5090565b5b8082111561186a576000815560010161186f56fea2646970667358221220c1d73dd5d713527b4b18f6ca6d3d915fe356fa5425b5776172fa3bf91a5476e564736f6c63430007060033