Source Code
Latest 25 from a total of 1,174 transactions
| Transaction Hash |
Method
|
Block
|
From
|
|
To
|
||||
|---|---|---|---|---|---|---|---|---|---|
| Send To Helios | 23983048 | 3 mins ago | IN | 0 ETH | 0.00001198 | ||||
| Submit Batch | 23983041 | 4 mins ago | IN | 0 ETH | 0.00002177 | ||||
| Submit Batch | 23982567 | 1 hr ago | IN | 0 ETH | 0.00001998 | ||||
| Send To Helios | 23982512 | 1 hr ago | IN | 0 ETH | 0.00001378 | ||||
| Send To Helios | 23982131 | 3 hrs ago | IN | 0 ETH | 0.00001278 | ||||
| Submit Batch | 23981998 | 3 hrs ago | IN | 0 ETH | 0.00002072 | ||||
| Send To Helios | 23981967 | 3 hrs ago | IN | 0 ETH | 0.00008715 | ||||
| Send To Helios | 23981426 | 5 hrs ago | IN | 0 ETH | 0.00016392 | ||||
| Send To Helios | 23981115 | 6 hrs ago | IN | 0 ETH | 0.00001286 | ||||
| Send To Helios | 23981100 | 6 hrs ago | IN | 0 ETH | 0.00001421 | ||||
| Send To Helios | 23981091 | 6 hrs ago | IN | 0 ETH | 0.00001389 | ||||
| Send To Helios | 23981082 | 6 hrs ago | IN | 0 ETH | 0.00001366 | ||||
| Submit Batch | 23981076 | 6 hrs ago | IN | 0 ETH | 0.00002316 | ||||
| Send To Helios | 23980865 | 7 hrs ago | IN | 0 ETH | 0.00006178 | ||||
| Send To Helios | 23980372 | 9 hrs ago | IN | 0 ETH | 0.00017296 | ||||
| Submit Batch | 23979787 | 11 hrs ago | IN | 0 ETH | 0.00002338 | ||||
| Send To Helios | 23978835 | 14 hrs ago | IN | 0 ETH | 0.00004216 | ||||
| Submit Batch | 23978502 | 15 hrs ago | IN | 0 ETH | 0.00002644 | ||||
| Send To Helios | 23978373 | 15 hrs ago | IN | 0 ETH | 0.00001456 | ||||
| Send To Helios | 23977222 | 19 hrs ago | IN | 0 ETH | 0.00005165 | ||||
| Send To Helios | 23977036 | 20 hrs ago | IN | 0 ETH | 0.00001529 | ||||
| Submit Batch | 23976502 | 22 hrs ago | IN | 0 ETH | 0.00008862 | ||||
| Send To Helios | 23975741 | 24 hrs ago | IN | 0 ETH | 0.00001675 | ||||
| Send To Helios | 23968364 | 2 days ago | IN | 0 ETH | 0.00006776 | ||||
| Send To Helios | 23967840 | 2 days ago | IN | 0 ETH | 0.00019985 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
Hyperion
Compiler Version
v0.8.25+commit.b61c2a91
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache-2.0
pragma solidity ^0.8.0;
import "./@openzeppelin/contracts/ERC20.sol";
import "./@openzeppelin/contracts/Ownable.sol";
import "./@openzeppelin/contracts/IERC20.sol";
import "./@openzeppelin/contracts/IERC20Metadata.sol";
import "./@openzeppelin/contracts/SafeERC20.sol";
import "./@openzeppelin/contracts/utils/Address.sol";
import "./@openzeppelin/contracts/utils/Initializable.sol";
import "./@openzeppelin/contracts/utils/Pausable.sol";
import "./@openzeppelin/contracts/security/ReentrancyGuard.sol";
import "./@openzeppelin/contracts/OwnableUpgradeableWithExpiry.sol";
contract HeliosERC20 is ERC20, Ownable {
uint8 private immutable _decimals;
constructor(
string memory name_,
string memory symbol_,
uint8 decimals_
) ERC20(name_, symbol_) {
_decimals = decimals_;
}
function decimals() public view virtual override returns (uint8) {
return _decimals;
}
function mint(address account, uint256 amount) public onlyOwner {
_mint(account, amount);
}
function burn(address account, uint256 amount) public onlyOwner {
_burn(account, amount);
}
}
// This is used purely to avoid stack too deep errors
// represents everything about a given validator set
struct ValsetArgs {
// the validators in this set, represented by an Ethereum address
address[] validators;
// the powers of the given validators in the same order as above
uint256[] powers;
// the nonce of this validator set
uint256 valsetNonce;
// the reward amount denominated in the below reward token, can be
// set to zero
uint256 rewardAmount;
// the reward token, should be set to the zero address if not being used
address rewardToken;
}
// Don't change the order of state for working upgrades.
// AND BE AWARE OF INHERITANCE VARIABLES!
// Inherited contracts contain storage slots and must be accounted for in any upgrades
// always test an exact upgrade on testnet and localhost before mainnet upgrades.
contract Hyperion is
Initializable,
OwnableUpgradeableWithExpiry,
Pausable,
ReentrancyGuard
{
using SafeERC20 for IERC20;
// ⚠️ ONLY APPEND TO STATE VARIABLES AND DON'T CHANGE VARIABLE ORDER/DEFINITIONS INCL NOT MAKING THEM IMMUTABLE ⚠️
// These are updated often
bytes32 public state_lastValsetCheckpoint;
mapping(address => uint256) public state_lastBatchNonces;
mapping(bytes32 => uint256) public state_invalidationMapping;
uint256 public state_lastValsetNonce = 0;
uint256 public state_lastValsetHeight = 0;
uint256 public state_lastEventNonce = 0;
uint256 public state_lastEventHeight = 0;
// These are set once at initialization
bytes32 public state_hyperionId;
uint256 public state_powerThreshold;
mapping(address => bool) public isHeliosNativeToken;
uint256 private constant MAX_NONCE_JUMP_LIMIT = 10_000_000_000_000;
// TransactionBatchExecutedEvent and SendToHeliosEvent both include the field _eventNonce.
// This is incremented every time one of these events is emitted. It is checked by the
// Helios module to ensure that all events are received in order, and that none are lost.
//
// ValsetUpdatedEvent does not include the field _eventNonce because it is never submitted to the Helios
// module. It is purely for the use of relayers to allow them to successfully submit batches.
event TransactionBatchExecutedEvent(
uint256 indexed _batchNonce,
address indexed _token,
uint256 _eventNonce
);
event SendToHeliosEvent(
address indexed _tokenContract,
address indexed _sender,
bytes32 indexed _destination,
uint256 _amount,
uint256 _eventNonce,
string _data
);
event ERC20DeployedEvent(
string _heliosDenom,
address indexed _tokenContract,
string _name,
string _symbol,
uint8 _decimals,
uint256 _eventNonce
);
event ValsetUpdatedEvent(
uint256 indexed _newValsetNonce,
uint256 _eventNonce,
uint256 _rewardAmount,
address _rewardToken,
address[] _validators,
uint256[] _powers
);
function _validateValidatorSet(
address[] calldata _validators,
uint256[] calldata _powers,
uint256 _powerThreshold
) private pure {
// Check that validators and powers set is well-formed
require(
_validators.length == _powers.length,
"Malformed current validator set"
);
// Check cumulative power to ensure the contract has sufficient power to actually
// pass a vote
uint256 cumulativePower = 0;
for (uint256 i = 0; i < _powers.length; i++) {
cumulativePower = cumulativePower + _powers[i];
if (cumulativePower > _powerThreshold) {
break;
}
}
require(
cumulativePower > _powerThreshold,
"Submitted validator set signatures do not have enough power."
);
}
function initialize(
// A unique identifier for this hyperion instance to use in signatures
bytes32 _hyperionId,
// How much voting power is needed to approve operations
uint256 _powerThreshold,
// The validator set, not in valset args format since many of it's
// arguments would never be used in this case
address[] calldata _validators,
uint256[] calldata _powers
) external initializer {
__Context_init_unchained();
__Ownable_init_unchained();
// CHECKS
_validateValidatorSet(_validators, _powers, _powerThreshold);
ValsetArgs memory _valset;
_valset = ValsetArgs(_validators, _powers, 0, 0, address(0));
bytes32 newCheckpoint = makeCheckpoint(_valset, _hyperionId);
// ACTIONS
state_hyperionId = _hyperionId;
state_powerThreshold = _powerThreshold;
state_lastValsetCheckpoint = newCheckpoint;
state_lastEventNonce = state_lastEventNonce + 1;
state_lastValsetHeight = block.number;
state_lastEventHeight = block.number;
// LOGS
emit ValsetUpdatedEvent(
state_lastValsetNonce,
state_lastEventNonce,
0,
address(0),
_validators,
_powers
);
}
function lastBatchNonce(
address _erc20Address
) public view returns (uint256) {
return state_lastBatchNonces[_erc20Address];
}
// Utility function to verify geth style signatures
function verifySig(
address _signer,
bytes32 _theHash,
uint8 _v,
bytes32 _r,
bytes32 _s
) private pure returns (bool) {
bytes32 messageDigest = keccak256(
abi.encodePacked("\x19Ethereum Signed Message:\n32", _theHash)
);
return _signer == ecrecover(messageDigest, _v, _r, _s);
}
// Make a new checkpoint from the supplied validator set
// A checkpoint is a hash of all relevant information about the valset. This is stored by the contract,
// instead of storing the information directly. This saves on storage and gas.
// The format of the checkpoint is:
// h(hyperionId, "checkpoint", valsetNonce, validators[], powers[])
// Where h is the keccak256 hash function.
// The validator powers must be decreasing or equal. This is important for checking the signatures on the
// next valset, since it allows the caller to stop verifying signatures once a quorum of signatures have been verified.
function makeCheckpoint(
ValsetArgs memory _valsetArgs,
bytes32 _hyperionId
) private pure returns (bytes32) {
// bytes32 encoding of the string "checkpoint"
bytes32 methodName = 0x636865636b706f696e7400000000000000000000000000000000000000000000;
bytes32 checkpoint = keccak256(
abi.encode(
_hyperionId,
methodName,
_valsetArgs.valsetNonce,
_valsetArgs.validators,
_valsetArgs.powers,
_valsetArgs.rewardAmount,
_valsetArgs.rewardToken
)
);
return checkpoint;
}
function checkValidatorSignatures(
// The current validator set and their powers
address[] memory _currentValidators,
uint256[] memory _currentPowers,
// The current validator's signatures
uint8[] memory _v,
bytes32[] memory _r,
bytes32[] memory _s,
// This is what we are checking they have signed
bytes32 _theHash,
uint256 _powerThreshold
) private view {
uint256 cumulativePower = 0;
for (uint256 i = 0; i < _currentValidators.length; i++) {
// If v is set to 0, this signifies that it was not possible to get a signature from this validator and we skip evaluation
// (In a valid signature, it is either 27 or 28)
if (_v[i] != 0) {
// Check that the current validator has signed off on the hash
require(
verifySig(
_currentValidators[i],
_theHash,
_v[i],
_r[i],
_s[i]
),
"Validator signature does not match."
);
if (_currentValidators.length < 10 && _currentValidators[i] == owner()) {
// If the validator set is less than 10 validators and the owner is one of them, we skip the power check
// This is to allow the owner to update the valset without having to wait for the full validator set to sign off
return;
}
// Sum up cumulative power
cumulativePower = cumulativePower + _currentPowers[i];
// Break early to avoid wasting gas
if (cumulativePower > _powerThreshold) {
break;
}
}
}
// Check that there was enough power
require(
cumulativePower > _powerThreshold,
"Submitted validator set signatures do not have enough power."
);
// Success
}
// This updates the valset by checking that the validators in the current valset have signed off on the
// new valset. The signatures supplied are the signatures of the current valset over the checkpoint hash
// generated from the new valset.
// Anyone can call this function, but they must supply valid signatures of state_powerThreshold of the current valset over
// the new valset.
function updateValset(
// The new version of the validator set
ValsetArgs calldata _newValset,
// The current validators that approve the change
ValsetArgs calldata _currentValset,
// These are arrays of the parts of the current validator's signatures
uint8[] calldata _v,
bytes32[] calldata _r,
bytes32[] calldata _s
) external whenNotPaused {
// CHECKS
// Check that the valset nonce is greater than the old one
require(
_newValset.valsetNonce > _currentValset.valsetNonce,
"New valset nonce must be greater than the current nonce"
);
// Check that current validators, powers, and signatures (v,r,s) set is well-formed
require(
_currentValset.validators.length == _currentValset.powers.length &&
_currentValset.validators.length == _v.length &&
_currentValset.validators.length == _r.length &&
_currentValset.validators.length == _s.length,
"Malformed current validator set"
);
// Prevent insane jumps potentially leaving the contract unable to process further valset updates
require(
_newValset.valsetNonce <
_currentValset.valsetNonce + MAX_NONCE_JUMP_LIMIT,
"New valset nonce must be less than 10_000_000_000_000 greater than the current nonce"
);
// Check that the supplied current validator set matches the saved checkpoint
require(
makeCheckpoint(_currentValset, state_hyperionId) ==
state_lastValsetCheckpoint,
"Supplied current validators and powers do not match checkpoint."
);
// Check that enough current validators have signed off on the new validator set
bytes32 newCheckpoint = makeCheckpoint(_newValset, state_hyperionId);
checkValidatorSignatures(
_currentValset.validators,
_currentValset.powers,
_v,
_r,
_s,
newCheckpoint,
state_powerThreshold
);
_validateValidatorSet(
_newValset.validators,
_newValset.powers,
state_powerThreshold
);
// ACTIONS
// Stored to be used next time to validate that the valset
// supplied by the caller is correct.
state_lastValsetCheckpoint = newCheckpoint;
// Store new nonce
state_lastValsetNonce = _newValset.valsetNonce;
// Store new valset height
state_lastValsetHeight = block.number;
// Send submission reward to msg.sender if reward token is a valid value
if (
_newValset.rewardToken != address(0) && _newValset.rewardAmount != 0
) {
IERC20(_newValset.rewardToken).safeTransfer(
msg.sender,
_newValset.rewardAmount
);
}
// LOGS
state_lastEventNonce = state_lastEventNonce + 1;
state_lastEventHeight = block.number;
emit ValsetUpdatedEvent(
_newValset.valsetNonce,
state_lastEventNonce,
_newValset.rewardAmount,
_newValset.rewardToken,
_newValset.validators,
_newValset.powers
);
}
// submitBatch processes a batch of Helios -> Ethereum transactions by sending the tokens in the transactions
// to the destination addresses. It is approved by the current Helios validator set.
// Anyone can call this function, but they must supply valid signatures of state_powerThreshold of the current valset over
// the batch.
function submitBatch(
// The validators that approve the batch
ValsetArgs memory _currentValset,
// These are arrays of the parts of the validators signatures
uint8[] memory _v,
bytes32[] memory _r,
bytes32[] memory _s,
// The batch of transactions
uint256[] memory _amounts,
address[] memory _destinations,
uint256[] memory _fees,
uint256 _batchNonce,
address _tokenContract,
// a block height beyond which this batch is not valid
// used to provide a fee-free timeout
uint256 _batchTimeout
) external nonReentrant whenNotPaused {
// CHECKS scoped to reduce stack depth
{
// Check that the batch nonce is higher than the last nonce for this token
require(
state_lastBatchNonces[_tokenContract] < _batchNonce,
"New batch nonce must be greater than the current nonce"
);
// Prevent insane jumps potentially leaving the contract unable to process further batches
require(
_batchNonce <
state_lastBatchNonces[_tokenContract] +
MAX_NONCE_JUMP_LIMIT,
"New batch nonce must be less than 10_000_000_000_000 greater than the current nonce"
);
// Check that the block height is less than the timeout height
require(
block.number < _batchTimeout,
"Batch timeout must be greater than the current block height"
);
// Check that current validators, powers, and signatures (v,r,s) set is well-formed
require(
_currentValset.validators.length ==
_currentValset.powers.length &&
_currentValset.validators.length == _v.length &&
_currentValset.validators.length == _r.length &&
_currentValset.validators.length == _s.length,
"Malformed current validator set"
);
// Check that the supplied current validator set matches the saved checkpoint
require(
makeCheckpoint(_currentValset, state_hyperionId) ==
state_lastValsetCheckpoint,
"Supplied current validators and powers do not match checkpoint."
);
// Check that the transaction batch is well-formed
require(
_amounts.length == _destinations.length &&
_amounts.length == _fees.length,
"Malformed batch of transactions"
);
// Check that enough current validators have signed off on the transaction batch and valset
checkValidatorSignatures(
_currentValset.validators,
_currentValset.powers,
_v,
_r,
_s,
// Get hash of the transaction batch and checkpoint
keccak256(
abi.encode(
state_hyperionId,
// bytes32 encoding of "transactionBatch"
0x7472616e73616374696f6e426174636800000000000000000000000000000000,
_amounts,
_destinations,
_fees,
_batchNonce,
_tokenContract,
_batchTimeout
)
),
state_powerThreshold
);
// ACTIONS
// Store batch nonce
state_lastBatchNonces[_tokenContract] = _batchNonce;
{
// Send transaction amounts to destinations
for (uint256 i = 0; i < _amounts.length; i++) {
if (isHeliosNativeToken[_tokenContract]) {
HeliosERC20(_tokenContract).mint(
_destinations[i],
_amounts[i]
);
} else {
IERC20(_tokenContract).safeTransfer(
_destinations[i],
_amounts[i]
);
}
}
}
}
// LOGS scoped to reduce stack depth
{
state_lastEventNonce = state_lastEventNonce + 1;
state_lastEventHeight = block.number;
emit TransactionBatchExecutedEvent(
_batchNonce,
_tokenContract,
state_lastEventNonce
);
}
}
function sendToHelios(
address _tokenContract,
bytes32 _destination,
uint256 _amount,
string calldata _data
) external whenNotPaused nonReentrant {
uint256 transferAmount;
if (isHeliosNativeToken[_tokenContract]) {
HeliosERC20(_tokenContract).burn(msg.sender, _amount);
transferAmount = _amount;
state_lastEventNonce = state_lastEventNonce + 1;
state_lastEventHeight = block.number;
emit SendToHeliosEvent(
_tokenContract,
msg.sender,
_destination,
transferAmount,
state_lastEventNonce,
_data
);
} else {
uint256 balanceBeforeTransfer = IERC20(_tokenContract).balanceOf(
address(this)
);
IERC20(_tokenContract).safeTransferFrom(
msg.sender,
address(this),
_amount
);
uint256 balanceAfterTransfer = IERC20(_tokenContract).balanceOf(
address(this)
);
transferAmount = balanceAfterTransfer - balanceBeforeTransfer;
state_lastEventNonce = state_lastEventNonce + 1;
state_lastEventHeight = block.number;
uint8 decimalsValue = IERC20Metadata(_tokenContract).decimals();
emit SendToHeliosEvent(
_tokenContract,
msg.sender,
_destination,
transferAmount,
state_lastEventNonce,
string(abi.encodePacked(
"{",
"\"metadata\": {",
"\"symbol\": \"", IERC20Metadata(_tokenContract).symbol(), "\",",
"\"name\": \"", IERC20Metadata(_tokenContract).name(), "\",",
"\"decimals\": ", uint2str(decimalsValue),
"},",
"\"data\": ", bytes(_data).length > 0 ? _data : "\"\"",
"}"
))
);
}
}
function deployERC20(
string calldata _heliosDenom,
string calldata _name,
string calldata _symbol,
uint8 _decimals
) external {
HeliosERC20 erc20 = new HeliosERC20(_name, _symbol, _decimals);
isHeliosNativeToken[address(erc20)] = true;
// Fire an event to let the Hyperion module know
state_lastEventNonce = state_lastEventNonce + 1;
state_lastEventHeight = block.number;
emit ERC20DeployedEvent(
_heliosDenom,
address(erc20),
_name,
_symbol,
_decimals,
state_lastEventNonce
);
}
/** Testnet only */
function testnetWithdraw(
address _tokenContract,
uint256 _amount
) external onlyOwner {
if (isHeliosNativeToken[_tokenContract]) {
HeliosERC20(_tokenContract).mint(msg.sender, _amount);
} else if (_tokenContract == address(0)) {
payable(msg.sender).transfer(address(this).balance);
} else {
IERC20(_tokenContract).safeTransfer(msg.sender, _amount);
}
}
function transferTokenOwnership(address _tokenContract, address _newOwner) external onlyOwner {
if (isHeliosNativeToken[_tokenContract]) {
HeliosERC20(_tokenContract).transferOwnership(_newOwner);
}
}
/** Testing */
function deployERC20WithSupply(
string calldata,
string calldata _name,
string calldata _symbol,
uint8 _decimals,
uint256 supply
) external {
HeliosERC20 erc20 = new HeliosERC20(_name, _symbol, _decimals);
erc20.mint(msg.sender, supply);
}
function emergencyPause() external onlyOwner {
_pause();
}
function emergencyUnpause() external onlyOwner {
_unpause();
}
function uint2str(uint256 _i) internal pure returns (string memory) {
if (_i == 0) {
return "0";
}
uint256 j = _i;
uint256 len;
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len;
while (_i != 0) {
bstr[--k] = bytes1(uint8(48 + _i % 10));
_i /= 10;
}
return string(bstr);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./Proxy.sol";
import "./utils/Address.sol";
/**
* @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
* implementation address that can be changed. This address is stored in storage in the location specified by
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
* implementation behind the proxy.
*
* Upgradeability is only provided internally through {_upgradeTo}. For an externally upgradeable proxy see
* {TransparentUpgradeableProxy}.
*/
contract ERC1967Proxy is Proxy {
/**
* @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
*
* If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
* function call, and allows initializating the storage of the proxy like a Solidity constructor.
*/
constructor(address _logic, bytes memory _data) payable {
assert(_IMPLEMENTATION_SLOT == bytes32(uint256(keccak256("eip1967.proxy.implementation")) - 1));
_setImplementation(_logic);
if(_data.length > 0) {
Address.functionDelegateCall(_logic, _data);
}
}
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 private constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation address.
*/
function _implementation() internal view virtual override returns (address impl) {
bytes32 slot = _IMPLEMENTATION_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
impl := sload(slot)
}
}
/**
* @dev Upgrades the proxy to a new implementation.
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal virtual {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(Address.isContract(newImplementation), "ERC1967Proxy: new implementation is not a contract");
bytes32 slot = _IMPLEMENTATION_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(slot, newImplementation)
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./IERC20Metadata.sol";
import "./utils/Context.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
* to implement supply mechanisms].
*
* We have followed general OpenZeppelin guidelines: functions revert instead
* of returning `false` on failure. This behavior is nonetheless conventional
* and does not conflict with the expectations of ERC20 applications.
*
* Additionally, an {Approval} event is emitted on calls to {transferFrom}.
* This allows applications to reconstruct the allowance for all accounts just
* by listening to said events. Other implementations of the EIP may not emit
* these events, as it isn't required by the specification.
*
* Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
* functions have been added to mitigate the well-known issues around setting
* allowances. See {IERC20-approve}.
*/
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
/**
* @dev Sets the values for {name} and {symbol}.
*
* The defaut value of {decimals} is 18. To select a different value for
* {decimals} you should overload it.
*
* All two of these values are immutable: they can only be set once during
* construction.
*/
constructor (string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
/**
* @dev Returns the number of decimals used to get its user representation.
* For example, if `decimals` equals `2`, a balance of `505` tokens should
* be displayed to a user as `5,05` (`505 / 10 ** 2`).
*
* Tokens usually opt for a value of 18, imitating the relationship between
* Ether and Wei. This is the value {ERC20} uses, unless this function is
* overloaded;
*
* NOTE: This information is only used for _display_ purposes: it in
* no way affects any of the arithmetic of the contract, including
* {IERC20-balanceOf} and {IERC20-transfer}.
*/
function decimals() public view virtual override returns (uint8) {
return 18;
}
/**
* @dev See {IERC20-totalSupply}.
*/
function totalSupply() public view virtual override returns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/
function balanceOf(address account) public view virtual override returns (uint256) {
return _balances[account];
}
/**
* @dev See {IERC20-transfer}.
*
* Requirements:
*
* - `recipient` cannot be the zero address.
* - the caller must have a balance of at least `amount`.
*/
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
/**
* @dev See {IERC20-allowance}.
*/
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
/**
* @dev See {IERC20-transferFrom}.
*
* Emits an {Approval} event indicating the updated allowance. This is not
* required by the EIP. See the note at the beginning of {ERC20}.
*
* Requirements:
*
* - `sender` and `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
* - the caller must have allowance for ``sender``'s tokens of at least
* `amount`.
*/
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
uint256 currentAllowance = _allowances[sender][_msgSender()];
require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
_approve(sender, _msgSender(), currentAllowance - amount);
return true;
}
/**
* @dev Atomically increases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
return true;
}
/**
* @dev Atomically decreases the allowance granted to `spender` by the caller.
*
* This is an alternative to {approve} that can be used as a mitigation for
* problems described in {IERC20-approve}.
*
* Emits an {Approval} event indicating the updated allowance.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `spender` must have allowance for the caller of at least
* `subtractedValue`.
*/
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
uint256 currentAllowance = _allowances[_msgSender()][spender];
require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
_approve(_msgSender(), spender, currentAllowance - subtractedValue);
return true;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is internal function is equivalent to {transfer}, and can be used to
* e.g. implement automatic token fees, slashing mechanisms, etc.
*
* Emits a {Transfer} event.
*
* Requirements:
*
* - `sender` cannot be the zero address.
* - `recipient` cannot be the zero address.
* - `sender` must have a balance of at least `amount`.
*/
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
uint256 senderBalance = _balances[sender];
require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
_balances[sender] = senderBalance - amount;
_balances[recipient] += amount;
emit Transfer(sender, recipient, amount);
}
/** @dev Creates `amount` tokens and assigns them to `account`, increasing
* the total supply.
*
* Emits a {Transfer} event with `from` set to the zero address.
*
* Requirements:
*
* - `to` cannot be the zero address.
*/
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
}
/**
* @dev Destroys `amount` tokens from `account`, reducing the
* total supply.
*
* Emits a {Transfer} event with `to` set to the zero address.
*
* Requirements:
*
* - `account` cannot be the zero address.
* - `account` must have at least `amount` tokens.
*/
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
_balances[account] = accountBalance - amount;
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
}
/**
* @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
*
* This internal function is equivalent to `approve`, and can be used to
* e.g. set automatic allowances for certain subsystems, etc.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `owner` cannot be the zero address.
* - `spender` cannot be the zero address.
*/
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
/**
* @dev Hook that is called before any transfer of tokens. This includes
* minting and burning.
*
* Calling conditions:
*
* - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
* will be to transferred to `to`.
* - when `from` is zero, `amount` tokens will be minted for `to`.
* - when `to` is zero, `amount` of ``from``'s tokens will be burned.
* - `from` and `to` are never both zero.
*
* To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
*/
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `recipient`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address recipient, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `sender` to `recipient` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() external virtual onlyOwner {
_renounceOwnership();
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) external virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
function _renounceOwnership() private {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./utils/ContextUpgradeable.sol";
import "./utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeableWithExpiry is Initializable, ContextUpgradeable {
address private _owner;
uint256 private _deployTimestamp;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal initializer {
__Context_init_unchained();
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal initializer {
address msgSender = _msgSender();
_owner = msgSender;
_deployTimestamp = block.timestamp;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() external virtual onlyOwner {
_renounceOwnership();
}
/**
* @dev Get the timestamp of ownership expiry.
* @return The timestamp of ownership expiry.
*/
function getOwnershipExpiryTimestamp() public view returns (uint256) {
return _deployTimestamp + 82 weeks;
}
/**
* @dev Check if the contract ownership is expired.
* @return True if the contract ownership is expired.
*/
function isOwnershipExpired() public view returns (bool) {
return block.timestamp > getOwnershipExpiryTimestamp();
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called after ownership is expired.
*/
function renounceOwnershipAfterExpiry() external {
require(isOwnershipExpired(), "Ownership not yet expired");
_renounceOwnership();
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) external virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
function _renounceOwnership() private {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
uint256[49] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./utils/Context.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableWithExpiry is Context {
address private _owner;
uint256 private _deployTimestamp;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
address msgSender = _msgSender();
_owner = msgSender;
_deployTimestamp = block.timestamp;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() external virtual onlyOwner {
_renounceOwnership();
}
/**
* @dev Get the timestamp of ownership expiry.
* @return The timestamp of ownership expiry.
*/
function getOwnershipExpiryTimestamp() public view returns (uint256) {
return _deployTimestamp + 104 weeks;
}
/**
* @dev Check if the contract ownership is expired.
* @return True if the contract ownership is expired.
*/
function isOwnershipExpired() public view returns (bool) {
return block.timestamp > getOwnershipExpiryTimestamp();
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called after ownership is expired.
*/
function renounceOwnershipAfterExpiry() external {
require(isOwnershipExpired(), "Ownership not yet expired");
_renounceOwnership();
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) external virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
function _renounceOwnership() private {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
* instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
* be specified by overriding the virtual {_implementation} function.
*
* Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
* different contract through the {_delegate} function.
*
* The success and return data of the delegated call will be returned back to the caller of the proxy.
*/
abstract contract Proxy {
/**
* @dev Delegates the current call to `implementation`.
*
* This function does not return to its internall call site, it will return directly to the external caller.
*/
function _delegate(address implementation) internal virtual {
// solhint-disable-next-line no-inline-assembly
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 { revert(0, returndatasize()) }
default { return(0, returndatasize()) }
}
}
/**
* @dev This is a virtual function that should be overriden so it returns the address to which the fallback function
* and {_fallback} should delegate.
*/
function _implementation() internal view virtual returns (address);
/**
* @dev Delegates the current call to the address returned by `_implementation()`.
*
* This function does not return to its internall call site, it will return directly to the external caller.
*/
function _fallback() internal virtual {
_beforeFallback();
_delegate(_implementation());
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
*/
fallback () external payable virtual {
_fallback();
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
* is empty.
*/
receive () external payable virtual {
_fallback();
}
/**
* @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
* call, or as part of the Solidity `fallback` or `receive` functions.
*
* If overriden should call `super._beforeFallback()`.
*/
function _beforeFallback() internal virtual {
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./TransparentUpgradeableProxy.sol";
import "./OwnableWithExpiry.sol";
/**
* @dev This is an auxiliary contract meant to be assigned as the admin of a {TransparentUpgradeableProxy}. For an
* explanation of why you would want to use this see the documentation for {TransparentUpgradeableProxy}.
*/
contract ProxyAdmin is OwnableWithExpiry {
/**
* @dev Returns the current implementation of `proxy`.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function getProxyImplementation(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
// We need to manually run the static call since the getter cannot be flagged as view
// bytes4(keccak256("implementation()")) == 0x5c60da1b
(bool success, bytes memory returndata) = address(proxy).staticcall(hex"5c60da1b");
require(success);
return abi.decode(returndata, (address));
}
/**
* @dev Returns the current admin of `proxy`.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function getProxyAdmin(TransparentUpgradeableProxy proxy) public view virtual returns (address) {
// We need to manually run the static call since the getter cannot be flagged as view
// bytes4(keccak256("admin()")) == 0xf851a440
(bool success, bytes memory returndata) = address(proxy).staticcall(hex"f851a440");
require(success);
return abi.decode(returndata, (address));
}
/**
* @dev Changes the admin of `proxy` to `newAdmin`.
*
* Requirements:
*
* - This contract must be the current admin of `proxy`.
*/
function changeProxyAdmin(TransparentUpgradeableProxy proxy, address newAdmin) public virtual onlyOwner {
proxy.changeAdmin(newAdmin);
}
/**
* @dev Upgrades `proxy` to `implementation`. See {TransparentUpgradeableProxy-upgradeTo}.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function upgrade(TransparentUpgradeableProxy proxy, address implementation) public virtual onlyOwner {
proxy.upgradeTo(implementation);
}
/**
* @dev Upgrades `proxy` to `implementation` and calls a function on the new implementation. See
* {TransparentUpgradeableProxy-upgradeToAndCall}.
*
* Requirements:
*
* - This contract must be the admin of `proxy`.
*/
function upgradeAndCall(TransparentUpgradeableProxy proxy, address implementation, bytes memory data) public payable virtual onlyOwner {
proxy.upgradeToAndCall{value: msg.value}(implementation, data);
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./utils/Address.sol";
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20 {
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(IERC20 token, address spender, uint256 value) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
// solhint-disable-next-line max-line-length
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20 token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) { // Return data is optional
// solhint-disable-next-line max-line-length
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and make it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
// On the first call to nonReentrant, _notEntered will be true
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
_;
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ERC1967Proxy.sol";
/**
* @dev This contract implements a proxy that is upgradeable by an admin.
*
* To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector
* clashing], which can potentially be used in an attack, this contract uses the
* https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two
* things that go hand in hand:
*
* 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if
* that call matches one of the admin functions exposed by the proxy itself.
* 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the
* implementation. If the admin tries to call a function on the implementation it will fail with an error that says
* "admin cannot fallback to proxy target".
*
* These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing
* the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due
* to sudden errors when trying to call a function from the proxy implementation.
*
* Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
* you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.
*/
contract TransparentUpgradeableProxy is ERC1967Proxy {
/**
* @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
* optionally initialized with `_data` as explained in {UpgradeableProxy-constructor}.
*/
constructor(address _logic, address admin_, bytes memory _data) payable ERC1967Proxy(_logic, _data) {
assert(_ADMIN_SLOT == bytes32(uint256(keccak256("eip1967.proxy.admin")) - 1));
_setAdmin(admin_);
}
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 private constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
*/
modifier ifAdmin() {
if (msg.sender == _admin()) {
_;
} else {
_fallback();
}
}
/**
* @dev Returns the current admin.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyAdmin}.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function admin() external ifAdmin returns (address admin_) {
admin_ = _admin();
}
/**
* @dev Returns the current implementation.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-getProxyImplementation}.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
*/
function implementation() external ifAdmin returns (address implementation_) {
implementation_ = _implementation();
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-changeProxyAdmin}.
*/
function changeAdmin(address newAdmin) external virtual ifAdmin {
require(newAdmin != address(0), "TransparentUpgradeableProxy: new admin is the zero address");
emit AdminChanged(_admin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev Upgrade the implementation of the proxy.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgrade}.
*/
function upgradeTo(address newImplementation) external virtual ifAdmin {
_upgradeTo(newImplementation);
}
/**
* @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified
* by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the
* proxied contract.
*
* NOTE: Only the admin can call this function. See {ProxyAdmin-upgradeAndCall}.
*/
function upgradeToAndCall(address newImplementation, bytes calldata data) external payable virtual ifAdmin {
_upgradeTo(newImplementation);
Address.functionDelegateCall(newImplementation, data);
}
/**
* @dev Returns the current admin.
*/
function _admin() internal view virtual returns (address adm) {
bytes32 slot = _ADMIN_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
adm := sload(slot)
}
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
bytes32 slot = _ADMIN_SLOT;
// solhint-disable-next-line no-inline-assembly
assembly {
sstore(slot, newAdmin)
}
}
/**
* @dev Makes sure the admin cannot access the fallback function. See {Proxy-_beforeFallback}.
*/
function _beforeFallback() internal virtual override {
require(msg.sender != _admin(), "TransparentUpgradeableProxy: admin cannot fallback to proxy target");
super._beforeFallback();
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
uint256 size;
// solhint-disable-next-line no-inline-assembly
assembly { size := extcodesize(account) }
return size > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-low-level-calls, avoid-call-value
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain`call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
// solhint-disable-next-line avoid-low-level-calls
(bool success, bytes memory returndata) = target.delegatecall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
// solhint-disable-next-line no-inline-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./Initializable.sol";
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal initializer {
__Context_init_unchained();
}
function __Context_init_unchained() internal initializer {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
uint256[50] private __gap;
}// SPDX-License-Identifier: MIT
// solhint-disable-next-line compiler-version
pragma solidity ^0.8.0;
import "./Address.sol";
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {UpgradeableProxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
*/
bool private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Modifier to protect an initializer function from being invoked twice.
*/
modifier initializer() {
require(_initializing || !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ContextUpgradeable.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is ContextUpgradeable {
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
bool private _paused;
/**
* @dev Initializes the contract in unpaused state.
*/
constructor() {
_paused = false;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
require(!paused(), "Pausable: paused");
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
require(paused(), "Pausable: not paused");
_;
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}{
"optimizer": {
"enabled": true,
"runs": 1000000
},
"metadata": {
"useLiteralContent": true
},
"evmVersion": "paris",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_heliosDenom","type":"string"},{"indexed":true,"internalType":"address","name":"_tokenContract","type":"address"},{"indexed":false,"internalType":"string","name":"_name","type":"string"},{"indexed":false,"internalType":"string","name":"_symbol","type":"string"},{"indexed":false,"internalType":"uint8","name":"_decimals","type":"uint8"},{"indexed":false,"internalType":"uint256","name":"_eventNonce","type":"uint256"}],"name":"ERC20DeployedEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_tokenContract","type":"address"},{"indexed":true,"internalType":"address","name":"_sender","type":"address"},{"indexed":true,"internalType":"bytes32","name":"_destination","type":"bytes32"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_eventNonce","type":"uint256"},{"indexed":false,"internalType":"string","name":"_data","type":"string"}],"name":"SendToHeliosEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_batchNonce","type":"uint256"},{"indexed":true,"internalType":"address","name":"_token","type":"address"},{"indexed":false,"internalType":"uint256","name":"_eventNonce","type":"uint256"}],"name":"TransactionBatchExecutedEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"_newValsetNonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_eventNonce","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_rewardAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"_rewardToken","type":"address"},{"indexed":false,"internalType":"address[]","name":"_validators","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"_powers","type":"uint256[]"}],"name":"ValsetUpdatedEvent","type":"event"},{"inputs":[{"internalType":"string","name":"_heliosDenom","type":"string"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"}],"name":"deployERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"","type":"string"},{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"uint256","name":"supply","type":"uint256"}],"name":"deployERC20WithSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyPause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyUnpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getOwnershipExpiryTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_hyperionId","type":"bytes32"},{"internalType":"uint256","name":"_powerThreshold","type":"uint256"},{"internalType":"address[]","name":"_validators","type":"address[]"},{"internalType":"uint256[]","name":"_powers","type":"uint256[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isHeliosNativeToken","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isOwnershipExpired","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_erc20Address","type":"address"}],"name":"lastBatchNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnershipAfterExpiry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenContract","type":"address"},{"internalType":"bytes32","name":"_destination","type":"bytes32"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"string","name":"_data","type":"string"}],"name":"sendToHelios","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state_hyperionId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"state_invalidationMapping","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"state_lastBatchNonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_lastEventHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_lastEventNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_lastValsetCheckpoint","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_lastValsetHeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_lastValsetNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"state_powerThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address[]","name":"validators","type":"address[]"},{"internalType":"uint256[]","name":"powers","type":"uint256[]"},{"internalType":"uint256","name":"valsetNonce","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"address","name":"rewardToken","type":"address"}],"internalType":"struct ValsetArgs","name":"_currentValset","type":"tuple"},{"internalType":"uint8[]","name":"_v","type":"uint8[]"},{"internalType":"bytes32[]","name":"_r","type":"bytes32[]"},{"internalType":"bytes32[]","name":"_s","type":"bytes32[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"address[]","name":"_destinations","type":"address[]"},{"internalType":"uint256[]","name":"_fees","type":"uint256[]"},{"internalType":"uint256","name":"_batchNonce","type":"uint256"},{"internalType":"address","name":"_tokenContract","type":"address"},{"internalType":"uint256","name":"_batchTimeout","type":"uint256"}],"name":"submitBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenContract","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"testnetWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenContract","type":"address"},{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferTokenOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address[]","name":"validators","type":"address[]"},{"internalType":"uint256[]","name":"powers","type":"uint256[]"},{"internalType":"uint256","name":"valsetNonce","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"address","name":"rewardToken","type":"address"}],"internalType":"struct ValsetArgs","name":"_newValset","type":"tuple"},{"components":[{"internalType":"address[]","name":"validators","type":"address[]"},{"internalType":"uint256[]","name":"powers","type":"uint256[]"},{"internalType":"uint256","name":"valsetNonce","type":"uint256"},{"internalType":"uint256","name":"rewardAmount","type":"uint256"},{"internalType":"address","name":"rewardToken","type":"address"}],"internalType":"struct ValsetArgs","name":"_currentValset","type":"tuple"},{"internalType":"uint8[]","name":"_v","type":"uint8[]"},{"internalType":"bytes32[]","name":"_r","type":"bytes32[]"},{"internalType":"bytes32[]","name":"_s","type":"bytes32[]"}],"name":"updateValset","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040526000606b556000606c556000606d556000606e55348015602357600080fd5b506066805460ff191690556001606755615932806100426000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80638da5cb5b116100f9578063c359a21211610097578063e5a2b5d211610071578063e5a2b5d21461039c578063f2b53307146103a5578063f2fde38b146103ae578063f7955637146103c157600080fd5b8063c359a21214610360578063d03c19b014610373578063df97174b1461037c57600080fd5b8063a5352f5b116100d3578063a5352f5b1461030e578063a6c42b0214610321578063b56561fe14610344578063c2d0732e1461034d57600080fd5b80638da5cb5b146102d4578063962ab5b1146102fc578063a4b52ca21461030557600080fd5b80635afe97bb1161016657806373b205471161014057806373b20547146102905780637dfb6f861461029957806381747418146102b95780638c64865f146102cc57600080fd5b80635afe97bb146102655780635c975abb1461027d578063715018a61461028857600080fd5b8063383fe467116101a2578063383fe4671461022f5780633d9ce78b146102425780634a4e3bd51461025557806351858e271461025d57600080fd5b8063011b2174146101c95780631ee7a10814610212578063308ff2081461021a575b600080fd5b6101ff6101d7366004613181565b73ffffffffffffffffffffffffffffffffffffffff1660009081526069602052604090205490565b6040519081526020015b60405180910390f35b6101ff6103d4565b61022d6102283660046131e5565b6103ed565b005b61022d61023d36600461324d565b610a3e565b61022d610250366004613280565b610b74565b61022d610ce9565b61022d610d74565b61026d610dfd565b6040519015158152602001610209565b60665460ff1661026d565b61022d610e0e565b6101ff606d5481565b6101ff6102a73660046132aa565b606a6020526000908152604090205481565b61022d6102c7366004613560565b610e97565b61022d6115c0565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610209565b6101ff606e5481565b6101ff606f5481565b61022d61031c3660046136fe565b61162e565b61026d61032f366004613181565b60716020526000908152604090205460ff1681565b6101ff606b5481565b61022d61035b3660046137e1565b611bcc565b61022d61036e366004613898565b611c9e565b6101ff606c5481565b6101ff61038a366004613181565b60696020526000908152604090205481565b6101ff60705481565b6101ff60685481565b61022d6103bc366004613181565b611f33565b61022d6103cf36600461391b565b6120e5565b60006034546302f4bd006103e891906139f8565b905090565b60665460ff161561045f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064015b60405180910390fd5b6002606754036104cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610456565b600260675573ffffffffffffffffffffffffffffffffffffffff851660009081526071602052604081205460ff16156105fc576040517f9dc29fac0000000000000000000000000000000000000000000000000000000081523360048201526024810185905273ffffffffffffffffffffffffffffffffffffffff871690639dc29fac90604401600060405180830381600087803b15801561056c57600080fd5b505af1158015610580573d6000803e3d6000fd5b50505050839050606d54600161059691906139f8565b606d81905543606e556040518691339173ffffffffffffffffffffffffffffffffffffffff8a16917f272cb0695a9182efb214ae0bc3e2c8163469c94b2cef2471499f6237d4ca8b47916105ef9187918a908a90613a54565b60405180910390a4610a31565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8816906370a0823190602401602060405180830381865afa158015610669573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068d9190613a7e565b90506106b173ffffffffffffffffffffffffffffffffffffffff88163330886121f3565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8916906370a0823190602401602060405180830381865afa15801561071e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107429190613a7e565b905061074e8282613a97565b9250606d54600161075f91906139f8565b606d8190555043606e8190555060008873ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107dd9190613aaa565b9050873373ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f272cb0695a9182efb214ae0bc3e2c8163469c94b2cef2471499f6237d4ca8b4787606d548e73ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801561087e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108c49190810190613aeb565b8f73ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801561090f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526109559190810190613aeb565b6109618960ff166122d5565b8d6109a1576040518060400160405280600281526020017f22220000000000000000000000000000000000000000000000000000000000008152506109d8565b8e8e8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050505b6040516020016109eb9493929190613bb0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610a25939291613dc3565b60405180910390a45050505b5050600160675550505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b73ffffffffffffffffffffffffffffffffffffffff821660009081526071602052604090205460ff1615610b70576040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff828116600483015283169063f2fde38b906024015b600060405180830381600087803b158015610b5757600080fd5b505af1158015610b6b573d6000803e3d6000fd5b505050505b5050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b73ffffffffffffffffffffffffffffffffffffffff821660009081526071602052604090205460ff1615610c7c576040517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff8316906340c10f1990604401610b3d565b73ffffffffffffffffffffffffffffffffffffffff8216610cc85760405133904780156108fc02916000818181858888f19350505050158015610cc3573d6000803e3d6000fd5b505050565b610b7073ffffffffffffffffffffffffffffffffffffffff83163383612412565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b610d72612468565b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610df5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b610d72612549565b6000610e076103d4565b4211905090565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b610d72612609565b600260675403610f03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610456565b600260675560665460ff1615610f75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610456565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606960205260409020548311611029576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4e6577206261746368206e6f6e6365206d75737420626520677265617465722060448201527f7468616e207468652063757272656e74206e6f6e6365000000000000000000006064820152608401610456565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260696020526040902054611060906509184e72a000906139f8565b8310611114576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605360248201527f4e6577206261746368206e6f6e6365206d757374206265206c6573732074686160448201527f6e2031305f3030305f3030305f3030305f30303020677265617465722074686160648201527f6e207468652063757272656e74206e6f6e636500000000000000000000000000608482015260a401610456565b8043106111a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f42617463682074696d656f7574206d757374206265206772656174657220746860448201527f616e207468652063757272656e7420626c6f636b2068656967687400000000006064820152608401610456565b60208a0151518a51511480156111bb575088518a5151145b80156111c9575087518a5151145b80156111d7575086518a5151145b61123d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610456565b60685461124c8b606f54612678565b146112d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f537570706c6965642063757272656e742076616c696461746f727320616e642060448201527f706f7765727320646f206e6f74206d6174636820636865636b706f696e742e006064820152608401610456565b845186511480156112eb575083518651145b611351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d6564206261746368206f66207472616e73616374696f6e73006044820152606401610456565b6113c08a600001518b602001518b8b8b606f547f7472616e73616374696f6e4261746368000000000000000000000000000000008d8d8d8d8d8d6040516020016113a2989796959493929190613e6e565b60405160208183030381529060405280519060200120607054612715565b73ffffffffffffffffffffffffffffffffffffffff821660009081526069602052604081208490555b865181101561154a5773ffffffffffffffffffffffffffffffffffffffff831660009081526071602052604090205460ff16156114e5578273ffffffffffffffffffffffffffffffffffffffff166340c10f1987838151811061144e5761144e613eed565b602002602001015189848151811061146857611468613eed565b60200260200101516040518363ffffffff1660e01b81526004016114ae92919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b600060405180830381600087803b1580156114c857600080fd5b505af11580156114dc573d6000803e3d6000fd5b50505050611542565b6115428682815181106114fa576114fa613eed565b602002602001015188838151811061151457611514613eed565b60200260200101518573ffffffffffffffffffffffffffffffffffffffff166124129092919063ffffffff16565b6001016113e9565b50606d546115599060016139f8565b606d81905543606e5560405190815273ffffffffffffffffffffffffffffffffffffffff83169084907f02c7e81975f8edb86e2a0c038b7b86a49c744236abf0f6177ff5afc6986ab7089060200160405180910390a3505060016067555050505050505050565b6115c8610dfd565b610e8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4f776e657273686970206e6f74207965742065787069726564000000000000006044820152606401610456565b60665460ff161561169b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610456565b8660400135886040013511611732576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4e65772076616c736574206e6f6e6365206d757374206265206772656174657260448201527f207468616e207468652063757272656e74206e6f6e63650000000000000000006064820152608401610456565b61173f6020880188613f1c565b905061174b8880613f1c565b90501480156117645750846117608880613f1c565b9050145b801561177a5750826117768880613f1c565b9050145b801561179057508061178c8880613f1c565b9050145b6117f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610456565b61180a6509184e72a00060408901356139f8565b8860400135106118c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605460248201527f4e65772076616c736574206e6f6e6365206d757374206265206c65737320746860448201527f616e2031305f3030305f3030305f3030305f303030206772656174657220746860648201527f616e207468652063757272656e74206e6f6e6365000000000000000000000000608482015260a401610456565b6068546118d96118d189613f84565b606f54612678565b14611966576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f537570706c6965642063757272656e742076616c696461746f727320616e642060448201527f706f7765727320646f206e6f74206d6174636820636865636b706f696e742e006064820152608401610456565b60006119746118d18a613f84565b9050611a916119838980613f1c565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506119c29250505060208b018b613f1c565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c91829185019084908082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b91829185019084908082843760009201919091525050604080516020808c0282810182019093528b82529093508b92508a918291850190849080828437600092019190915250506070548992509050612715565b611ab3611a9e8a80613f1c565b611aab60208d018d613f1c565b60705461298d565b60688190556040890135606b5543606c556000611ad660a08b0160808c01613181565b73ffffffffffffffffffffffffffffffffffffffff1614158015611afd5750606089013515155b15611b3857611b383360608b0135611b1b60a08d0160808e01613181565b73ffffffffffffffffffffffffffffffffffffffff169190612412565b606d54611b469060016139f8565b606d81905543606e5560408a0135907f76d08978c024a4bf8cbb30c67fd78fcaa1827cbc533e4e175f36d07e64ccf96a9060608c0135611b8c60a08e0160808f01613181565b611b968e80613f1c565b8f8060200190611ba69190613f1c565b604051611bb99796959493929190614024565b60405180910390a2505050505050505050565b60008686868686604051611bdf9061314b565b611bed959493929190614081565b604051809103906000f080158015611c09573d6000803e3d6000fd5b506040517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810184905290915073ffffffffffffffffffffffffffffffffffffffff8216906340c10f1990604401600060405180830381600087803b158015611c7b57600080fd5b505af1158015611c8f573d6000803e3d6000fd5b50505050505050505050505050565b600054610100900460ff1680611cb7575060005460ff16155b611d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610456565b600054610100900460ff16158015611d8257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611d8a612ac7565b611d92612bdd565b611d9f858585858a61298d565b611de76040518060a0016040528060608152602001606081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b6040518060a001604052808787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208781028281018201909352878252928301929091889188918291850190849080828437600092018290525093855250505060208201819052604082018190526060909101819052909150611e82828a612678565b606f8a905560708990556068819055606d54909150611ea29060016139f8565b606d81905543606c819055606e55606b5460405190917f76d08978c024a4bf8cbb30c67fd78fcaa1827cbc533e4e175f36d07e64ccf96a91611ef1919060009081908d908d908d908d90614024565b60405180910390a250508015611f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314611fb4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b73ffffffffffffffffffffffffffffffffffffffff8116612057576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610456565b60335460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600085858585856040516120f89061314b565b612106959493929190614081565b604051809103906000f080158015612122573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff8116600090815260716020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155606d5491925061218491906139f8565b606d81905543606e5560405173ffffffffffffffffffffffffffffffffffffffff8316917f82fe3a4fa49c6382d0c085746698ddbbafe6c2bf61285b19410644b5b26287c7916121e1918c918c918c918c918c918c918c916140be565b60405180910390a25050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526122cf9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612d51565b50505050565b60608160000361231857505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612342578061232c81614115565b915061233b9050600a8361417c565b915061231c565b60008167ffffffffffffffff81111561235d5761235d6132c3565b6040519080825280601f01601f191660200182016040528015612387576020820181803683370190505b509050815b85156124095761239d600a87614190565b6123a89060306139f8565b60f81b826123b5836141a4565b925082815181106123c8576123c8613eed565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612402600a8761417c565b955061238c565b50949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610cc39084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161224d565b60665460ff166124d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610456565b606680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60665460ff16156125b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610456565b606680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861251f3390565b60335460405160009173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6000807f636865636b706f696e740000000000000000000000000000000000000000000060001b90506000838286604001518760000151886020015189606001518a608001516040516020016126d497969594939291906141d9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120925050505b92915050565b6000805b88518110156128f35786818151811061273457612734613eed565b602002602001015160ff166000146128eb576127b789828151811061275b5761275b613eed565b60200260200101518589848151811061277657612776613eed565b602002602001015189858151811061279057612790613eed565b60200260200101518986815181106127aa576127aa613eed565b6020026020010151612e5d565b612843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f56616c696461746f72207369676e617475726520646f6573206e6f74206d617460448201527f63682e00000000000000000000000000000000000000000000000000000000006064820152608401610456565b600a89511080156128b0575060335473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1689828151811061289057612890613eed565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16145b156128bc575050611f2a565b8781815181106128ce576128ce613eed565b6020026020010151826128e191906139f8565b91508282116128f3575b600101612719565b50818111612983576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f5375626d69747465642076616c696461746f7220736574207369676e6174757260448201527f657320646f206e6f74206861766520656e6f75676820706f7765722e000000006064820152608401610456565b5050505050505050565b8382146129f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610456565b6000805b83811015612a3757848482818110612a1457612a14613eed565b9050602002013582612a2691906139f8565b9150828211612a37576001016129fa565b50818111610b6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f5375626d69747465642076616c696461746f7220736574207369676e6174757260448201527f657320646f206e6f74206861766520656e6f75676820706f7765722e000000006064820152608401610456565b600054610100900460ff1680612ae0575060005460ff16155b612b6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610456565b600054610100900460ff16158015612bab57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b8015612bda57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50565b600054610100900460ff1680612bf6575060005460ff16155b612c82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610456565b600054610100900460ff16158015612cc157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b603380547fffffffffffffffffffffffff000000000000000000000000000000000000000016339081179091554260345560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015612bda57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b6000612db3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612f5f9092919063ffffffff16565b805190915015610cc35780806020019051810190612dd19190614241565b610cc3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610456565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018590526000908190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000845290830180835281905260ff8816918301919091526060820186905260808201859052915060019060a0016020604051602081039080840390855afa158015612f1b573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161491505095945050505050565b6060612f6e8484600085612f78565b90505b9392505050565b60608247101561300a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610456565b843b613072576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610456565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161309b9190614263565b60006040518083038185875af1925050503d80600081146130d8576040519150601f19603f3d011682016040523d82523d6000602084013e6130dd565b606091505b50915091506130ed8282866130f8565b979650505050505050565b60608315613107575081612f71565b8251156131175782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610456919061427f565b61166a8061429383390190565b803573ffffffffffffffffffffffffffffffffffffffff8116811461317c57600080fd5b919050565b60006020828403121561319357600080fd5b612f7182613158565b60008083601f8401126131ae57600080fd5b50813567ffffffffffffffff8111156131c657600080fd5b6020830191508360208285010111156131de57600080fd5b9250929050565b6000806000806000608086880312156131fd57600080fd5b61320686613158565b94506020860135935060408601359250606086013567ffffffffffffffff81111561323057600080fd5b61323c8882890161319c565b969995985093965092949392505050565b6000806040838503121561326057600080fd5b61326983613158565b915061327760208401613158565b90509250929050565b6000806040838503121561329357600080fd5b61329c83613158565b946020939093013593505050565b6000602082840312156132bc57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613339576133396132c3565b604052919050565b600067ffffffffffffffff82111561335b5761335b6132c3565b5060051b60200190565b600082601f83011261337657600080fd5b8135602061338b61338683613341565b6132f2565b8083825260208201915060208460051b8701019350868411156133ad57600080fd5b602086015b848110156133d0576133c381613158565b83529183019183016133b2565b509695505050505050565b600082601f8301126133ec57600080fd5b813560206133fc61338683613341565b8083825260208201915060208460051b87010193508684111561341e57600080fd5b602086015b848110156133d05780358352918301918301613423565b600060a0828403121561344c57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613470576134706132c3565b81604052829350843591508082111561348857600080fd5b61349486838701613365565b835260208501359150808211156134aa57600080fd5b506134b7858286016133db565b60208301525060408301356040820152606083013560608201526134dd60808401613158565b60808201525092915050565b60ff81168114612bda57600080fd5b600082601f83011261350957600080fd5b8135602061351961338683613341565b8083825260208201915060208460051b87010193508684111561353b57600080fd5b602086015b848110156133d0578035613553816134e9565b8352918301918301613540565b6000806000806000806000806000806101408b8d03121561358057600080fd5b8a3567ffffffffffffffff8082111561359857600080fd5b6135a48e838f0161343a565b9b5060208d01359150808211156135ba57600080fd5b6135c68e838f016134f8565b9a5060408d01359150808211156135dc57600080fd5b6135e88e838f016133db565b995060608d01359150808211156135fe57600080fd5b61360a8e838f016133db565b985060808d013591508082111561362057600080fd5b61362c8e838f016133db565b975060a08d013591508082111561364257600080fd5b61364e8e838f01613365565b965060c08d013591508082111561366457600080fd5b506136718d828e016133db565b94505060e08b013592506136886101008c01613158565b91506101208b013590509295989b9194979a5092959850565b600060a082840312156136b357600080fd5b50919050565b60008083601f8401126136cb57600080fd5b50813567ffffffffffffffff8111156136e357600080fd5b6020830191508360208260051b85010111156131de57600080fd5b60008060008060008060008060a0898b03121561371a57600080fd5b883567ffffffffffffffff8082111561373257600080fd5b61373e8c838d016136a1565b995060208b013591508082111561375457600080fd5b6137608c838d016136a1565b985060408b013591508082111561377657600080fd5b6137828c838d016136b9565b909850965060608b013591508082111561379b57600080fd5b6137a78c838d016136b9565b909650945060808b01359150808211156137c057600080fd5b506137cd8b828c016136b9565b999c989b5096995094979396929594505050565b60008060008060008060008060a0898b0312156137fd57600080fd5b883567ffffffffffffffff8082111561381557600080fd5b6138218c838d0161319c565b909a50985060208b013591508082111561383a57600080fd5b6138468c838d0161319c565b909850965060408b013591508082111561385f57600080fd5b5061386c8b828c0161319c565b9095509350506060890135613880816134e9565b80925050608089013590509295985092959890939650565b600080600080600080608087890312156138b157600080fd5b8635955060208701359450604087013567ffffffffffffffff808211156138d757600080fd5b6138e38a838b016136b9565b909650945060608901359150808211156138fc57600080fd5b5061390989828a016136b9565b979a9699509497509295939492505050565b60008060008060008060006080888a03121561393657600080fd5b873567ffffffffffffffff8082111561394e57600080fd5b61395a8b838c0161319c565b909950975060208a013591508082111561397357600080fd5b61397f8b838c0161319c565b909750955060408a013591508082111561399857600080fd5b506139a58a828b0161319c565b90945092505060608801356139b9816134e9565b8091505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561270f5761270f6139c9565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b848152836020820152606060408201526000613a74606083018486613a0b565b9695505050505050565b600060208284031215613a9057600080fd5b5051919050565b8181038181111561270f5761270f6139c9565b600060208284031215613abc57600080fd5b8151612f71816134e9565b60005b83811015613ae2578181015183820152602001613aca565b50506000910152565b600060208284031215613afd57600080fd5b815167ffffffffffffffff80821115613b1557600080fd5b818401915084601f830112613b2957600080fd5b815181811115613b3b57613b3b6132c3565b613b6c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016132f2565b9150808252856020828501011115613b8357600080fd5b612409816020840160208601613ac7565b60008151613ba6818560208601613ac7565b9290920192915050565b7f7b0000000000000000000000000000000000000000000000000000000000000081527f226d65746164617461223a207b0000000000000000000000000000000000000060018201527f2273796d626f6c223a2022000000000000000000000000000000000000000000600e82015260008551613c34816019850160208a01613ac7565b80830190507f222c0000000000000000000000000000000000000000000000000000000000008060198301527f226e616d65223a20220000000000000000000000000000000000000000000000601b8301528651613c99816024850160208b01613ac7565b60249201918201527f22646563696d616c73223a20000000000000000000000000000000000000000060268201528451613cda816032840160208901613ac7565b613d6d613d44613d3e613d156032858701017f7d2c000000000000000000000000000000000000000000000000000000000000815260020190565b7f2264617461223a20000000000000000000000000000000000000000000000000815260080190565b87613b94565b7f7d00000000000000000000000000000000000000000000000000000000000000815260010190565b98975050505050505050565b60008151808452613d91816020860160208601613ac7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b838152826020820152606060408201526000613de26060830184613d79565b95945050505050565b60008151808452602080850194506020840160005b83811015613e1c57815187529582019590820190600101613e00565b509495945050505050565b60008151808452602080850194506020840160005b83811015613e1c57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e3c565b60006101008a8352896020840152806040840152613e8e8184018a613deb565b90508281036060840152613ea28189613e27565b90508281036080840152613eb68188613deb565b60a0840196909652505073ffffffffffffffffffffffffffffffffffffffff9290921660c083015260e09091015295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f5157600080fd5b83018035915067ffffffffffffffff821115613f6c57600080fd5b6020019150600581901b36038213156131de57600080fd5b600061270f368361343a565b8183526000602080850194508260005b85811015613e1c5773ffffffffffffffffffffffffffffffffffffffff613fc683613158565b1687529582019590820190600101613fa0565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561400b57600080fd5b8260051b80836020870137939093016020019392505050565b87815286602082015273ffffffffffffffffffffffffffffffffffffffff8616604082015260a06060820152600061406060a083018688613f90565b8281036080840152614073818587613fd9565b9a9950505050505050505050565b606081526000614095606083018789613a0b565b82810360208401526140a8818688613a0b565b91505060ff831660408301529695505050505050565b60a0815260006140d260a083018a8c613a0b565b82810360208401526140e581898b613a0b565b905082810360408401526140fa818789613a0b565b60ff9590951660608401525050608001529695505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614146576141466139c9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261418b5761418b61414d565b500490565b60008261419f5761419f61414d565b500690565b6000816141b3576141b36139c9565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b87815286602082015285604082015260e0606082015260006141fe60e0830187613e27565b82810360808401526142108187613deb565b9150508360a083015273ffffffffffffffffffffffffffffffffffffffff831660c083015298975050505050505050565b60006020828403121561425357600080fd5b81518015158114612f7157600080fd5b60008251614275818460208701613ac7565b9190910192915050565b602081526000612f716020830184613d7956fe60a060405234801561001057600080fd5b5060405161166a38038061166a83398101604081905261002f9161017b565b8282600361003d8382610283565b50600461004a8282610283565b505050600061005d6100b960201b60201c565b600580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060ff16608052506103429050565b3390565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126100e457600080fd5b81516001600160401b03808211156100fe576100fe6100bd565b604051601f8301601f19908116603f01168101908282118183101715610126576101266100bd565b816040528381526020925086602085880101111561014357600080fd5b600091505b838210156101655785820183015181830184015290820190610148565b6000602085830101528094505050505092915050565b60008060006060848603121561019057600080fd5b83516001600160401b03808211156101a757600080fd5b6101b3878388016100d3565b945060208601519150808211156101c957600080fd5b506101d6868287016100d3565b925050604084015160ff811681146101ed57600080fd5b809150509250925092565b600181811c9082168061020c57607f821691505b60208210810361022c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561027e576000816000526020600020601f850160051c8101602086101561025b5750805b601f850160051c820191505b8181101561027a57828155600101610267565b5050505b505050565b81516001600160401b0381111561029c5761029c6100bd565b6102b0816102aa84546101f8565b84610232565b602080601f8311600181146102e557600084156102cd5750858301515b600019600386901b1c1916600185901b17855561027a565b600085815260208120601f198616915b82811015610314578886015182559484019460019091019084016102f5565b50858210156103325787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805161130d61035d6000396000610172015261130d6000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063715018a611610097578063a457c2d711610066578063a457c2d714610245578063a9059cbb14610258578063dd62ed3e1461026b578063f2fde38b146102b157600080fd5b8063715018a6146101fa5780638da5cb5b1461020257806395d89b411461022a5780639dc29fac1461023257600080fd5b8063313ce567116100d3578063313ce5671461016b578063395093511461019c57806340c10f19146101af57806370a08231146101c457600080fd5b806306fdde0314610105578063095ea7b31461012357806318160ddd1461014657806323b872dd14610158575b600080fd5b61010d6102c4565b60405161011a91906110de565b60405180910390f35b610136610131366004611174565b610356565b604051901515815260200161011a565b6002545b60405190815260200161011a565b61013661016636600461119e565b61036d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161011a565b6101366101aa366004611174565b61045f565b6101c26101bd366004611174565b6104a3565b005b61014a6101d23660046111da565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c2610532565b60055460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b61010d6105bd565b6101c2610240366004611174565b6105cc565b610136610253366004611174565b610657565b610136610266366004611174565b610731565b61014a6102793660046111fc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101c26102bf3660046111da565b61073e565b6060600380546102d39061122f565b80601f01602080910402602001604051908101604052809291908181526020018280546102ff9061122f565b801561034c5780601f106103215761010080835404028352916020019161034c565b820191906000526020600020905b81548152906001019060200180831161032f57829003601f168201915b5050505050905090565b60006103633384846108f0565b5060015b92915050565b600061037a848484610aa4565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482811015610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610454853361044f86856112b1565b6108f0565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161036391859061044f9086906112c4565b60055473ffffffffffffffffffffffffffffffffffffffff163314610524576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b61052e8282610d61565b5050565b60055473ffffffffffffffffffffffffffffffffffffffff1633146105b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b6105bb610e81565b565b6060600480546102d39061122f565b60055473ffffffffffffffffffffffffffffffffffffffff16331461064d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b61052e8282610ef0565b33600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015610718576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610437565b610727338561044f86856112b1565b5060019392505050565b6000610363338484610aa4565b60055473ffffffffffffffffffffffffffffffffffffffff1633146107bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b73ffffffffffffffffffffffffffffffffffffffff8116610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610437565b60055460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff8316610992576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff8216610a35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316610b47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff8216610bea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ca0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610437565b610caa82826112b1565b73ffffffffffffffffffffffffffffffffffffffff8086166000908152602081905260408082209390935590851681529081208054849290610ced9084906112c4565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d5391815260200190565b60405180910390a350505050565b73ffffffffffffffffffffffffffffffffffffffff8216610dde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610437565b8060026000828254610df091906112c4565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610e2a9084906112c4565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60055460405160009173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b73ffffffffffffffffffffffffffffffffffffffff8216610f93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610437565b61105382826112b1565b73ffffffffffffffffffffffffffffffffffffffff84166000908152602081905260408120919091556002805484929061108e9084906112b1565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610a97565b60006020808352835180602085015260005b8181101561110c578581018301518582016040015282016110f0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116f57600080fd5b919050565b6000806040838503121561118757600080fd5b6111908361114b565b946020939093013593505050565b6000806000606084860312156111b357600080fd5b6111bc8461114b565b92506111ca6020850161114b565b9150604084013590509250925092565b6000602082840312156111ec57600080fd5b6111f58261114b565b9392505050565b6000806040838503121561120f57600080fd5b6112188361114b565b91506112266020840161114b565b90509250929050565b600181811c9082168061124357607f821691505b60208210810361127c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561036757610367611282565b808201808211156103675761036761128256fea2646970667358221220b168f3659cf82d4a7e6c764e7f7092f36826a906100b92d26d684f363a0b22ab64736f6c63430008190033a2646970667358221220d2649e93213e34fac0adc7d7fcce2926fd55ca614d3d9643ed69740b1fa366d664736f6c63430008190033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80638da5cb5b116100f9578063c359a21211610097578063e5a2b5d211610071578063e5a2b5d21461039c578063f2b53307146103a5578063f2fde38b146103ae578063f7955637146103c157600080fd5b8063c359a21214610360578063d03c19b014610373578063df97174b1461037c57600080fd5b8063a5352f5b116100d3578063a5352f5b1461030e578063a6c42b0214610321578063b56561fe14610344578063c2d0732e1461034d57600080fd5b80638da5cb5b146102d4578063962ab5b1146102fc578063a4b52ca21461030557600080fd5b80635afe97bb1161016657806373b205471161014057806373b20547146102905780637dfb6f861461029957806381747418146102b95780638c64865f146102cc57600080fd5b80635afe97bb146102655780635c975abb1461027d578063715018a61461028857600080fd5b8063383fe467116101a2578063383fe4671461022f5780633d9ce78b146102425780634a4e3bd51461025557806351858e271461025d57600080fd5b8063011b2174146101c95780631ee7a10814610212578063308ff2081461021a575b600080fd5b6101ff6101d7366004613181565b73ffffffffffffffffffffffffffffffffffffffff1660009081526069602052604090205490565b6040519081526020015b60405180910390f35b6101ff6103d4565b61022d6102283660046131e5565b6103ed565b005b61022d61023d36600461324d565b610a3e565b61022d610250366004613280565b610b74565b61022d610ce9565b61022d610d74565b61026d610dfd565b6040519015158152602001610209565b60665460ff1661026d565b61022d610e0e565b6101ff606d5481565b6101ff6102a73660046132aa565b606a6020526000908152604090205481565b61022d6102c7366004613560565b610e97565b61022d6115c0565b60335460405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610209565b6101ff606e5481565b6101ff606f5481565b61022d61031c3660046136fe565b61162e565b61026d61032f366004613181565b60716020526000908152604090205460ff1681565b6101ff606b5481565b61022d61035b3660046137e1565b611bcc565b61022d61036e366004613898565b611c9e565b6101ff606c5481565b6101ff61038a366004613181565b60696020526000908152604090205481565b6101ff60705481565b6101ff60685481565b61022d6103bc366004613181565b611f33565b61022d6103cf36600461391b565b6120e5565b60006034546302f4bd006103e891906139f8565b905090565b60665460ff161561045f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064015b60405180910390fd5b6002606754036104cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610456565b600260675573ffffffffffffffffffffffffffffffffffffffff851660009081526071602052604081205460ff16156105fc576040517f9dc29fac0000000000000000000000000000000000000000000000000000000081523360048201526024810185905273ffffffffffffffffffffffffffffffffffffffff871690639dc29fac90604401600060405180830381600087803b15801561056c57600080fd5b505af1158015610580573d6000803e3d6000fd5b50505050839050606d54600161059691906139f8565b606d81905543606e556040518691339173ffffffffffffffffffffffffffffffffffffffff8a16917f272cb0695a9182efb214ae0bc3e2c8163469c94b2cef2471499f6237d4ca8b47916105ef9187918a908a90613a54565b60405180910390a4610a31565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8816906370a0823190602401602060405180830381865afa158015610669573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061068d9190613a7e565b90506106b173ffffffffffffffffffffffffffffffffffffffff88163330886121f3565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015260009073ffffffffffffffffffffffffffffffffffffffff8916906370a0823190602401602060405180830381865afa15801561071e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107429190613a7e565b905061074e8282613a97565b9250606d54600161075f91906139f8565b606d8190555043606e8190555060008873ffffffffffffffffffffffffffffffffffffffff1663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107b9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906107dd9190613aaa565b9050873373ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff167f272cb0695a9182efb214ae0bc3e2c8163469c94b2cef2471499f6237d4ca8b4787606d548e73ffffffffffffffffffffffffffffffffffffffff166395d89b416040518163ffffffff1660e01b8152600401600060405180830381865afa15801561087e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526108c49190810190613aeb565b8f73ffffffffffffffffffffffffffffffffffffffff166306fdde036040518163ffffffff1660e01b8152600401600060405180830381865afa15801561090f573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526109559190810190613aeb565b6109618960ff166122d5565b8d6109a1576040518060400160405280600281526020017f22220000000000000000000000000000000000000000000000000000000000008152506109d8565b8e8e8080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050505b6040516020016109eb9493929190613bb0565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815290829052610a25939291613dc3565b60405180910390a45050505b5050600160675550505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610abf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b73ffffffffffffffffffffffffffffffffffffffff821660009081526071602052604090205460ff1615610b70576040517ff2fde38b00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff828116600483015283169063f2fde38b906024015b600060405180830381600087803b158015610b5757600080fd5b505af1158015610b6b573d6000803e3d6000fd5b505050505b5050565b60335473ffffffffffffffffffffffffffffffffffffffff163314610bf5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b73ffffffffffffffffffffffffffffffffffffffff821660009081526071602052604090205460ff1615610c7c576040517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810182905273ffffffffffffffffffffffffffffffffffffffff8316906340c10f1990604401610b3d565b73ffffffffffffffffffffffffffffffffffffffff8216610cc85760405133904780156108fc02916000818181858888f19350505050158015610cc3573d6000803e3d6000fd5b505050565b610b7073ffffffffffffffffffffffffffffffffffffffff83163383612412565b60335473ffffffffffffffffffffffffffffffffffffffff163314610d6a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b610d72612468565b565b60335473ffffffffffffffffffffffffffffffffffffffff163314610df5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b610d72612549565b6000610e076103d4565b4211905090565b60335473ffffffffffffffffffffffffffffffffffffffff163314610e8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b610d72612609565b600260675403610f03576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610456565b600260675560665460ff1615610f75576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610456565b73ffffffffffffffffffffffffffffffffffffffff82166000908152606960205260409020548311611029576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4e6577206261746368206e6f6e6365206d75737420626520677265617465722060448201527f7468616e207468652063757272656e74206e6f6e6365000000000000000000006064820152608401610456565b73ffffffffffffffffffffffffffffffffffffffff8216600090815260696020526040902054611060906509184e72a000906139f8565b8310611114576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605360248201527f4e6577206261746368206e6f6e6365206d757374206265206c6573732074686160448201527f6e2031305f3030305f3030305f3030305f30303020677265617465722074686160648201527f6e207468652063757272656e74206e6f6e636500000000000000000000000000608482015260a401610456565b8043106111a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603b60248201527f42617463682074696d656f7574206d757374206265206772656174657220746860448201527f616e207468652063757272656e7420626c6f636b2068656967687400000000006064820152608401610456565b60208a0151518a51511480156111bb575088518a5151145b80156111c9575087518a5151145b80156111d7575086518a5151145b61123d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610456565b60685461124c8b606f54612678565b146112d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f537570706c6965642063757272656e742076616c696461746f727320616e642060448201527f706f7765727320646f206e6f74206d6174636820636865636b706f696e742e006064820152608401610456565b845186511480156112eb575083518651145b611351576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d6564206261746368206f66207472616e73616374696f6e73006044820152606401610456565b6113c08a600001518b602001518b8b8b606f547f7472616e73616374696f6e4261746368000000000000000000000000000000008d8d8d8d8d8d6040516020016113a2989796959493929190613e6e565b60405160208183030381529060405280519060200120607054612715565b73ffffffffffffffffffffffffffffffffffffffff821660009081526069602052604081208490555b865181101561154a5773ffffffffffffffffffffffffffffffffffffffff831660009081526071602052604090205460ff16156114e5578273ffffffffffffffffffffffffffffffffffffffff166340c10f1987838151811061144e5761144e613eed565b602002602001015189848151811061146857611468613eed565b60200260200101516040518363ffffffff1660e01b81526004016114ae92919073ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b600060405180830381600087803b1580156114c857600080fd5b505af11580156114dc573d6000803e3d6000fd5b50505050611542565b6115428682815181106114fa576114fa613eed565b602002602001015188838151811061151457611514613eed565b60200260200101518573ffffffffffffffffffffffffffffffffffffffff166124129092919063ffffffff16565b6001016113e9565b50606d546115599060016139f8565b606d81905543606e5560405190815273ffffffffffffffffffffffffffffffffffffffff83169084907f02c7e81975f8edb86e2a0c038b7b86a49c744236abf0f6177ff5afc6986ab7089060200160405180910390a3505060016067555050505050505050565b6115c8610dfd565b610e8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4f776e657273686970206e6f74207965742065787069726564000000000000006044820152606401610456565b60665460ff161561169b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610456565b8660400135886040013511611732576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603760248201527f4e65772076616c736574206e6f6e6365206d757374206265206772656174657260448201527f207468616e207468652063757272656e74206e6f6e63650000000000000000006064820152608401610456565b61173f6020880188613f1c565b905061174b8880613f1c565b90501480156117645750846117608880613f1c565b9050145b801561177a5750826117768880613f1c565b9050145b801561179057508061178c8880613f1c565b9050145b6117f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610456565b61180a6509184e72a00060408901356139f8565b8860400135106118c2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152605460248201527f4e65772076616c736574206e6f6e6365206d757374206265206c65737320746860448201527f616e2031305f3030305f3030305f3030305f303030206772656174657220746860648201527f616e207468652063757272656e74206e6f6e6365000000000000000000000000608482015260a401610456565b6068546118d96118d189613f84565b606f54612678565b14611966576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603f60248201527f537570706c6965642063757272656e742076616c696461746f727320616e642060448201527f706f7765727320646f206e6f74206d6174636820636865636b706f696e742e006064820152608401610456565b60006119746118d18a613f84565b9050611a916119838980613f1c565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506119c29250505060208b018b613f1c565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050604080516020808e0282810182019093528d82529093508d92508c91829185019084908082843760009201919091525050604080516020808d0282810182019093528c82529093508c92508b91829185019084908082843760009201919091525050604080516020808c0282810182019093528b82529093508b92508a918291850190849080828437600092019190915250506070548992509050612715565b611ab3611a9e8a80613f1c565b611aab60208d018d613f1c565b60705461298d565b60688190556040890135606b5543606c556000611ad660a08b0160808c01613181565b73ffffffffffffffffffffffffffffffffffffffff1614158015611afd5750606089013515155b15611b3857611b383360608b0135611b1b60a08d0160808e01613181565b73ffffffffffffffffffffffffffffffffffffffff169190612412565b606d54611b469060016139f8565b606d81905543606e5560408a0135907f76d08978c024a4bf8cbb30c67fd78fcaa1827cbc533e4e175f36d07e64ccf96a9060608c0135611b8c60a08e0160808f01613181565b611b968e80613f1c565b8f8060200190611ba69190613f1c565b604051611bb99796959493929190614024565b60405180910390a2505050505050505050565b60008686868686604051611bdf9061314b565b611bed959493929190614081565b604051809103906000f080158015611c09573d6000803e3d6000fd5b506040517f40c10f190000000000000000000000000000000000000000000000000000000081523360048201526024810184905290915073ffffffffffffffffffffffffffffffffffffffff8216906340c10f1990604401600060405180830381600087803b158015611c7b57600080fd5b505af1158015611c8f573d6000803e3d6000fd5b50505050505050505050505050565b600054610100900460ff1680611cb7575060005460ff16155b611d43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610456565b600054610100900460ff16158015611d8257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611d8a612ac7565b611d92612bdd565b611d9f858585858a61298d565b611de76040518060a0016040528060608152602001606081526020016000815260200160008152602001600073ffffffffffffffffffffffffffffffffffffffff1681525090565b6040518060a001604052808787808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505050908252506040805160208781028281018201909352878252928301929091889188918291850190849080828437600092018290525093855250505060208201819052604082018190526060909101819052909150611e82828a612678565b606f8a905560708990556068819055606d54909150611ea29060016139f8565b606d81905543606c819055606e55606b5460405190917f76d08978c024a4bf8cbb30c67fd78fcaa1827cbc533e4e175f36d07e64ccf96a91611ef1919060009081908d908d908d908d90614024565b60405180910390a250508015611f2a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050505050565b60335473ffffffffffffffffffffffffffffffffffffffff163314611fb4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610456565b73ffffffffffffffffffffffffffffffffffffffff8116612057576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610456565b60335460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3603380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b600085858585856040516120f89061314b565b612106959493929190614081565b604051809103906000f080158015612122573d6000803e3d6000fd5b5073ffffffffffffffffffffffffffffffffffffffff8116600090815260716020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001908117909155606d5491925061218491906139f8565b606d81905543606e5560405173ffffffffffffffffffffffffffffffffffffffff8316917f82fe3a4fa49c6382d0c085746698ddbbafe6c2bf61285b19410644b5b26287c7916121e1918c918c918c918c918c918c918c916140be565b60405180910390a25050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526122cf9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612d51565b50505050565b60608160000361231857505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115612342578061232c81614115565b915061233b9050600a8361417c565b915061231c565b60008167ffffffffffffffff81111561235d5761235d6132c3565b6040519080825280601f01601f191660200182016040528015612387576020820181803683370190505b509050815b85156124095761239d600a87614190565b6123a89060306139f8565b60f81b826123b5836141a4565b925082815181106123c8576123c8613eed565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350612402600a8761417c565b955061238c565b50949350505050565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610cc39084907fa9059cbb000000000000000000000000000000000000000000000000000000009060640161224d565b60665460ff166124d4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610456565b606680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b60665460ff16156125b6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610456565b606680547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861251f3390565b60335460405160009173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3603380547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b6000807f636865636b706f696e740000000000000000000000000000000000000000000060001b90506000838286604001518760000151886020015189606001518a608001516040516020016126d497969594939291906141d9565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120925050505b92915050565b6000805b88518110156128f35786818151811061273457612734613eed565b602002602001015160ff166000146128eb576127b789828151811061275b5761275b613eed565b60200260200101518589848151811061277657612776613eed565b602002602001015189858151811061279057612790613eed565b60200260200101518986815181106127aa576127aa613eed565b6020026020010151612e5d565b612843576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f56616c696461746f72207369676e617475726520646f6573206e6f74206d617460448201527f63682e00000000000000000000000000000000000000000000000000000000006064820152608401610456565b600a89511080156128b0575060335473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1689828151811061289057612890613eed565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16145b156128bc575050611f2a565b8781815181106128ce576128ce613eed565b6020026020010151826128e191906139f8565b91508282116128f3575b600101612719565b50818111612983576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f5375626d69747465642076616c696461746f7220736574207369676e6174757260448201527f657320646f206e6f74206861766520656e6f75676820706f7765722e000000006064820152608401610456565b5050505050505050565b8382146129f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f4d616c666f726d65642063757272656e742076616c696461746f7220736574006044820152606401610456565b6000805b83811015612a3757848482818110612a1457612a14613eed565b9050602002013582612a2691906139f8565b9150828211612a37576001016129fa565b50818111610b6b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603c60248201527f5375626d69747465642076616c696461746f7220736574207369676e6174757260448201527f657320646f206e6f74206861766520656e6f75676820706f7765722e000000006064820152608401610456565b600054610100900460ff1680612ae0575060005460ff16155b612b6c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610456565b600054610100900460ff16158015612bab57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b8015612bda57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50565b600054610100900460ff1680612bf6575060005460ff16155b612c82576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610456565b600054610100900460ff16158015612cc157600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b603380547fffffffffffffffffffffffff000000000000000000000000000000000000000016339081179091554260345560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3508015612bda57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b6000612db3826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16612f5f9092919063ffffffff16565b805190915015610cc35780806020019051810190612dd19190614241565b610cc3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610456565b6040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c81018590526000908190605c01604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201206000845290830180835281905260ff8816918301919091526060820186905260808201859052915060019060a0016020604051602081039080840390855afa158015612f1b573d6000803e3d6000fd5b5050506020604051035173ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff161491505095945050505050565b6060612f6e8484600085612f78565b90505b9392505050565b60608247101561300a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610456565b843b613072576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610456565b6000808673ffffffffffffffffffffffffffffffffffffffff16858760405161309b9190614263565b60006040518083038185875af1925050503d80600081146130d8576040519150601f19603f3d011682016040523d82523d6000602084013e6130dd565b606091505b50915091506130ed8282866130f8565b979650505050505050565b60608315613107575081612f71565b8251156131175782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610456919061427f565b61166a8061429383390190565b803573ffffffffffffffffffffffffffffffffffffffff8116811461317c57600080fd5b919050565b60006020828403121561319357600080fd5b612f7182613158565b60008083601f8401126131ae57600080fd5b50813567ffffffffffffffff8111156131c657600080fd5b6020830191508360208285010111156131de57600080fd5b9250929050565b6000806000806000608086880312156131fd57600080fd5b61320686613158565b94506020860135935060408601359250606086013567ffffffffffffffff81111561323057600080fd5b61323c8882890161319c565b969995985093965092949392505050565b6000806040838503121561326057600080fd5b61326983613158565b915061327760208401613158565b90509250929050565b6000806040838503121561329357600080fd5b61329c83613158565b946020939093013593505050565b6000602082840312156132bc57600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613339576133396132c3565b604052919050565b600067ffffffffffffffff82111561335b5761335b6132c3565b5060051b60200190565b600082601f83011261337657600080fd5b8135602061338b61338683613341565b6132f2565b8083825260208201915060208460051b8701019350868411156133ad57600080fd5b602086015b848110156133d0576133c381613158565b83529183019183016133b2565b509695505050505050565b600082601f8301126133ec57600080fd5b813560206133fc61338683613341565b8083825260208201915060208460051b87010193508684111561341e57600080fd5b602086015b848110156133d05780358352918301918301613423565b600060a0828403121561344c57600080fd5b60405160a0810167ffffffffffffffff8282108183111715613470576134706132c3565b81604052829350843591508082111561348857600080fd5b61349486838701613365565b835260208501359150808211156134aa57600080fd5b506134b7858286016133db565b60208301525060408301356040820152606083013560608201526134dd60808401613158565b60808201525092915050565b60ff81168114612bda57600080fd5b600082601f83011261350957600080fd5b8135602061351961338683613341565b8083825260208201915060208460051b87010193508684111561353b57600080fd5b602086015b848110156133d0578035613553816134e9565b8352918301918301613540565b6000806000806000806000806000806101408b8d03121561358057600080fd5b8a3567ffffffffffffffff8082111561359857600080fd5b6135a48e838f0161343a565b9b5060208d01359150808211156135ba57600080fd5b6135c68e838f016134f8565b9a5060408d01359150808211156135dc57600080fd5b6135e88e838f016133db565b995060608d01359150808211156135fe57600080fd5b61360a8e838f016133db565b985060808d013591508082111561362057600080fd5b61362c8e838f016133db565b975060a08d013591508082111561364257600080fd5b61364e8e838f01613365565b965060c08d013591508082111561366457600080fd5b506136718d828e016133db565b94505060e08b013592506136886101008c01613158565b91506101208b013590509295989b9194979a5092959850565b600060a082840312156136b357600080fd5b50919050565b60008083601f8401126136cb57600080fd5b50813567ffffffffffffffff8111156136e357600080fd5b6020830191508360208260051b85010111156131de57600080fd5b60008060008060008060008060a0898b03121561371a57600080fd5b883567ffffffffffffffff8082111561373257600080fd5b61373e8c838d016136a1565b995060208b013591508082111561375457600080fd5b6137608c838d016136a1565b985060408b013591508082111561377657600080fd5b6137828c838d016136b9565b909850965060608b013591508082111561379b57600080fd5b6137a78c838d016136b9565b909650945060808b01359150808211156137c057600080fd5b506137cd8b828c016136b9565b999c989b5096995094979396929594505050565b60008060008060008060008060a0898b0312156137fd57600080fd5b883567ffffffffffffffff8082111561381557600080fd5b6138218c838d0161319c565b909a50985060208b013591508082111561383a57600080fd5b6138468c838d0161319c565b909850965060408b013591508082111561385f57600080fd5b5061386c8b828c0161319c565b9095509350506060890135613880816134e9565b80925050608089013590509295985092959890939650565b600080600080600080608087890312156138b157600080fd5b8635955060208701359450604087013567ffffffffffffffff808211156138d757600080fd5b6138e38a838b016136b9565b909650945060608901359150808211156138fc57600080fd5b5061390989828a016136b9565b979a9699509497509295939492505050565b60008060008060008060006080888a03121561393657600080fd5b873567ffffffffffffffff8082111561394e57600080fd5b61395a8b838c0161319c565b909950975060208a013591508082111561397357600080fd5b61397f8b838c0161319c565b909750955060408a013591508082111561399857600080fd5b506139a58a828b0161319c565b90945092505060608801356139b9816134e9565b8091505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8082018082111561270f5761270f6139c9565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b848152836020820152606060408201526000613a74606083018486613a0b565b9695505050505050565b600060208284031215613a9057600080fd5b5051919050565b8181038181111561270f5761270f6139c9565b600060208284031215613abc57600080fd5b8151612f71816134e9565b60005b83811015613ae2578181015183820152602001613aca565b50506000910152565b600060208284031215613afd57600080fd5b815167ffffffffffffffff80821115613b1557600080fd5b818401915084601f830112613b2957600080fd5b815181811115613b3b57613b3b6132c3565b613b6c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016132f2565b9150808252856020828501011115613b8357600080fd5b612409816020840160208601613ac7565b60008151613ba6818560208601613ac7565b9290920192915050565b7f7b0000000000000000000000000000000000000000000000000000000000000081527f226d65746164617461223a207b0000000000000000000000000000000000000060018201527f2273796d626f6c223a2022000000000000000000000000000000000000000000600e82015260008551613c34816019850160208a01613ac7565b80830190507f222c0000000000000000000000000000000000000000000000000000000000008060198301527f226e616d65223a20220000000000000000000000000000000000000000000000601b8301528651613c99816024850160208b01613ac7565b60249201918201527f22646563696d616c73223a20000000000000000000000000000000000000000060268201528451613cda816032840160208901613ac7565b613d6d613d44613d3e613d156032858701017f7d2c000000000000000000000000000000000000000000000000000000000000815260020190565b7f2264617461223a20000000000000000000000000000000000000000000000000815260080190565b87613b94565b7f7d00000000000000000000000000000000000000000000000000000000000000815260010190565b98975050505050505050565b60008151808452613d91816020860160208601613ac7565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b838152826020820152606060408201526000613de26060830184613d79565b95945050505050565b60008151808452602080850194506020840160005b83811015613e1c57815187529582019590820190600101613e00565b509495945050505050565b60008151808452602080850194506020840160005b83811015613e1c57815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101613e3c565b60006101008a8352896020840152806040840152613e8e8184018a613deb565b90508281036060840152613ea28189613e27565b90508281036080840152613eb68188613deb565b60a0840196909652505073ffffffffffffffffffffffffffffffffffffffff9290921660c083015260e09091015295945050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112613f5157600080fd5b83018035915067ffffffffffffffff821115613f6c57600080fd5b6020019150600581901b36038213156131de57600080fd5b600061270f368361343a565b8183526000602080850194508260005b85811015613e1c5773ffffffffffffffffffffffffffffffffffffffff613fc683613158565b1687529582019590820190600101613fa0565b81835260007f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83111561400b57600080fd5b8260051b80836020870137939093016020019392505050565b87815286602082015273ffffffffffffffffffffffffffffffffffffffff8616604082015260a06060820152600061406060a083018688613f90565b8281036080840152614073818587613fd9565b9a9950505050505050505050565b606081526000614095606083018789613a0b565b82810360208401526140a8818688613a0b565b91505060ff831660408301529695505050505050565b60a0815260006140d260a083018a8c613a0b565b82810360208401526140e581898b613a0b565b905082810360408401526140fa818789613a0b565b60ff9590951660608401525050608001529695505050505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614146576141466139c9565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b60008261418b5761418b61414d565b500490565b60008261419f5761419f61414d565b500690565b6000816141b3576141b36139c9565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b87815286602082015285604082015260e0606082015260006141fe60e0830187613e27565b82810360808401526142108187613deb565b9150508360a083015273ffffffffffffffffffffffffffffffffffffffff831660c083015298975050505050505050565b60006020828403121561425357600080fd5b81518015158114612f7157600080fd5b60008251614275818460208701613ac7565b9190910192915050565b602081526000612f716020830184613d7956fe60a060405234801561001057600080fd5b5060405161166a38038061166a83398101604081905261002f9161017b565b8282600361003d8382610283565b50600461004a8282610283565b505050600061005d6100b960201b60201c565b600580546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a35060ff16608052506103429050565b3390565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126100e457600080fd5b81516001600160401b03808211156100fe576100fe6100bd565b604051601f8301601f19908116603f01168101908282118183101715610126576101266100bd565b816040528381526020925086602085880101111561014357600080fd5b600091505b838210156101655785820183015181830184015290820190610148565b6000602085830101528094505050505092915050565b60008060006060848603121561019057600080fd5b83516001600160401b03808211156101a757600080fd5b6101b3878388016100d3565b945060208601519150808211156101c957600080fd5b506101d6868287016100d3565b925050604084015160ff811681146101ed57600080fd5b809150509250925092565b600181811c9082168061020c57607f821691505b60208210810361022c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f82111561027e576000816000526020600020601f850160051c8101602086101561025b5750805b601f850160051c820191505b8181101561027a57828155600101610267565b5050505b505050565b81516001600160401b0381111561029c5761029c6100bd565b6102b0816102aa84546101f8565b84610232565b602080601f8311600181146102e557600084156102cd5750858301515b600019600386901b1c1916600185901b17855561027a565b600085815260208120601f198616915b82811015610314578886015182559484019460019091019084016102f5565b50858210156103325787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805161130d61035d6000396000610172015261130d6000f3fe608060405234801561001057600080fd5b50600436106101005760003560e01c8063715018a611610097578063a457c2d711610066578063a457c2d714610245578063a9059cbb14610258578063dd62ed3e1461026b578063f2fde38b146102b157600080fd5b8063715018a6146101fa5780638da5cb5b1461020257806395d89b411461022a5780639dc29fac1461023257600080fd5b8063313ce567116100d3578063313ce5671461016b578063395093511461019c57806340c10f19146101af57806370a08231146101c457600080fd5b806306fdde0314610105578063095ea7b31461012357806318160ddd1461014657806323b872dd14610158575b600080fd5b61010d6102c4565b60405161011a91906110de565b60405180910390f35b610136610131366004611174565b610356565b604051901515815260200161011a565b6002545b60405190815260200161011a565b61013661016636600461119e565b61036d565b60405160ff7f000000000000000000000000000000000000000000000000000000000000000016815260200161011a565b6101366101aa366004611174565b61045f565b6101c26101bd366004611174565b6104a3565b005b61014a6101d23660046111da565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c2610532565b60055460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b61010d6105bd565b6101c2610240366004611174565b6105cc565b610136610253366004611174565b610657565b610136610266366004611174565b610731565b61014a6102793660046111fc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101c26102bf3660046111da565b61073e565b6060600380546102d39061122f565b80601f01602080910402602001604051908101604052809291908181526020018280546102ff9061122f565b801561034c5780601f106103215761010080835404028352916020019161034c565b820191906000526020600020905b81548152906001019060200180831161032f57829003601f168201915b5050505050905090565b60006103633384846108f0565b5060015b92915050565b600061037a848484610aa4565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260016020908152604080832033845290915290205482811015610440576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e636500000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610454853361044f86856112b1565b6108f0565b506001949350505050565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161036391859061044f9086906112c4565b60055473ffffffffffffffffffffffffffffffffffffffff163314610524576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b61052e8282610d61565b5050565b60055473ffffffffffffffffffffffffffffffffffffffff1633146105b3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b6105bb610e81565b565b6060600480546102d39061122f565b60055473ffffffffffffffffffffffffffffffffffffffff16331461064d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b61052e8282610ef0565b33600090815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8616845290915281205482811015610718576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610437565b610727338561044f86856112b1565b5060019392505050565b6000610363338484610aa4565b60055473ffffffffffffffffffffffffffffffffffffffff1633146107bf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610437565b73ffffffffffffffffffffffffffffffffffffffff8116610862576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610437565b60055460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff8316610992576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff8216610a35576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8316610b47576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff8216610bea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ca0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610437565b610caa82826112b1565b73ffffffffffffffffffffffffffffffffffffffff8086166000908152602081905260408082209390935590851681529081208054849290610ced9084906112c4565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610d5391815260200190565b60405180910390a350505050565b73ffffffffffffffffffffffffffffffffffffffff8216610dde576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610437565b8060026000828254610df091906112c4565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604081208054839290610e2a9084906112c4565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60055460405160009173ffffffffffffffffffffffffffffffffffffffff16907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600580547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b73ffffffffffffffffffffffffffffffffffffffff8216610f93576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610437565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611049576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610437565b61105382826112b1565b73ffffffffffffffffffffffffffffffffffffffff84166000908152602081905260408120919091556002805484929061108e9084906112b1565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90602001610a97565b60006020808352835180602085015260005b8181101561110c578581018301518582016040015282016110f0565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461116f57600080fd5b919050565b6000806040838503121561118757600080fd5b6111908361114b565b946020939093013593505050565b6000806000606084860312156111b357600080fd5b6111bc8461114b565b92506111ca6020850161114b565b9150604084013590509250925092565b6000602082840312156111ec57600080fd5b6111f58261114b565b9392505050565b6000806040838503121561120f57600080fd5b6112188361114b565b91506112266020840161114b565b90509250929050565b600181811c9082168061124357607f821691505b60208210810361127c577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b8181038181111561036757610367611282565b808201808211156103675761036761128256fea2646970667358221220b168f3659cf82d4a7e6c764e7f7092f36826a906100b92d26d684f363a0b22ab64736f6c63430008190033a2646970667358221220d2649e93213e34fac0adc7d7fcce2926fd55ca614d3d9643ed69740b1fa366d664736f6c63430008190033
Deployed Bytecode Sourcemap
2056:21651:17:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6479:151;;;;;;:::i;:::-;6587:36;;6561:7;6587:36;;;:21;:36;;;;;;;6479:151;;;;552:25:18;;;540:2;525:18;6479:151:17;;;;;;;;2269:119:5;;;:::i;19279:2107:17:-;;;;;;:::i;:::-;;:::i;:::-;;22522:232;;;;;;:::i;:::-;;:::i;22071:445::-;;;;;;:::i;:::-;;:::i;23164:74::-;;;:::i;23088:70::-;;;:::i;2524:127:5:-;;;:::i;:::-;;;2257:14:18;;2250:22;2232:41;;2220:2;2205:18;2524:127:5;2092:187:18;1015:78:16;1081:7;;;;1015:78;;2049:93:5;;;:::i;2630:39:17:-;;;;;;2471:60;;;;;;:::i;:::-;;;;;;;;;;;;;;14572:4701;;;;;;:::i;:::-;;:::i;2838:154:5:-;;;:::i;1417:85::-;1489:6;;1417:85;;1489:6;;;;9124:74:18;;9112:2;9097:18;1417:85:5;8978:226:18;2675:40:17;;;;;;2766:31;;;;;;10872:3346;;;;;;:::i;:::-;;:::i;2845:51::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;2537:40;;;;;;22779:303;;;;;;:::i;:::-;;:::i;5144:1329::-;;;;;;:::i;:::-;;:::i;2583:41::-;;;;;;2409:56;;;;;;:::i;:::-;;;;;;;;;;;;;;2803:35;;;;;;2362:41;;;;;;3141:242:5;;;;;;:::i;:::-;;:::i;21392:649:17:-;;;;;;:::i;:::-;;:::i;2269:119:5:-;2329:7;2354:16;;2373:8;2354:27;;;;:::i;:::-;2347:34;;2269:119;:::o;19279:2107:17:-;1081:7:16;;;;1302:9;1294:38;;;;;;;15287:2:18;1294:38:16;;;15269:21:18;15326:2;15306:18;;;15299:30;15365:18;15345;;;15338:46;15401:18;;1294:38:16;;;;;;;;;1680:1:11::1;2260:7;;:19:::0;2252:63:::1;;;::::0;::::1;::::0;;15632:2:18;2252:63:11::1;::::0;::::1;15614:21:18::0;15671:2;15651:18;;;15644:30;15710:33;15690:18;;;15683:61;15761:18;;2252:63:11::1;15430:355:18::0;2252:63:11::1;1680:1;2390:7;:18:::0;19508:35:17::2;::::0;::::2;19471:22;19508:35:::0;;;:19:::2;:35;::::0;;;;;::::2;;19504:1876;;;19559:53;::::0;;;;19592:10:::2;19559:53;::::0;::::2;15964:74:18::0;16054:18;;;16047:34;;;19559:32:17::2;::::0;::::2;::::0;::::2;::::0;15937:18:18;;19559:53:17::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;19644:7;19627:24;;19689:20;;19712:1;19689:24;;;;:::i;:::-;19666:20;:47:::0;;;19751:12:::2;19727:21;:36:::0;19782:214:::2;::::0;19877:12;;19849:10:::2;::::0;19782:214:::2;::::0;::::2;::::0;::::2;::::0;::::2;::::0;19907:14;;19977:5;;;;19782:214:::2;:::i;:::-;;;;;;;;19504:1876;;;20059:77;::::0;;;;20117:4:::2;20059:77;::::0;::::2;9124:74:18::0;20027:29:17::2;::::0;20059:32:::2;::::0;::::2;::::0;::::2;::::0;9097:18:18;;20059:77:17::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20027:109:::0;-1:-1:-1;20151:137:17::2;:39;::::0;::::2;20208:10;20244:4;20267:7:::0;20151:39:::2;:137::i;:::-;20334:77;::::0;;;;20392:4:::2;20334:77;::::0;::::2;9124:74:18::0;20303:28:17::2;::::0;20334:32:::2;::::0;::::2;::::0;::::2;::::0;9097:18:18;;20334:77:17::2;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20303:108:::0;-1:-1:-1;20442:44:17::2;20465:21:::0;20303:108;20442:44:::2;:::i;:::-;20425:61;;20524:20;;20547:1;20524:24;;;;:::i;:::-;20501:20;:47;;;;20586:12;20562:21;:36;;;;20612:19;20649:14;20634:39;;;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;20612:63;;20790:12;20762:10;20695:674;;20730:14;20695:674;;;20820:14;20852:20;;21032:14;21017:37;;;:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;21116:14;21101:35;;;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;;;;;;::::0;;::::2;::::0;::::2;::::0;::::2;;::::0;::::2;::::0;;;::::2;::::0;::::2;:::i;:::-;21185:23;21194:13;21185:23;;:8;:23::i;:::-;21271::::0;:40:::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;21297:5;;21271:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::2;::::0;;;;-1:-1:-1;;;;21271:40:17::2;20897:457;;;;;;;;;;;:::i;:::-;;::::0;;;;;::::2;::::0;;;;;;;20695:674:::2;::::0;;;::::2;:::i;:::-;;;;;;;;20013:1367;;;19504:1876;-1:-1:-1::0;;1637:1:11::1;2563:7;:22:::0;-1:-1:-1;;;;19279:2107:17:o;22522:232::-;1489:6:5;;1629:23;1489:6;888:10:14;1629:23:5;1621:68;;;;;;;22442:2:18;1621:68:5;;;22424:21:18;;;22461:18;;;22454:30;22520:34;22500:18;;;22493:62;22572:18;;1621:68:5;22240:356:18;1621:68:5;22630:35:17::1;::::0;::::1;;::::0;;;:19:::1;:35;::::0;;;;;::::1;;22626:122;;;22681:56;::::0;;;;:45:::1;9142:55:18::0;;;22681:56:17::1;::::0;::::1;9124:74:18::0;22681:45:17;::::1;::::0;::::1;::::0;9097:18:18;;22681:56:17::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;22626:122;22522:232:::0;;:::o;22071:445::-;1489:6:5;;1629:23;1489:6;888:10:14;1629:23:5;1621:68;;;;;;;22442:2:18;1621:68:5;;;22424:21:18;;;22461:18;;;22454:30;22520:34;22500:18;;;22493:62;22572:18;;1621:68:5;22240:356:18;1621:68:5;22192:35:17::1;::::0;::::1;;::::0;;;:19:::1;:35;::::0;;;;;::::1;;22188:322;;;22243:53;::::0;;;;22276:10:::1;22243:53;::::0;::::1;15964:74:18::0;16054:18;;;16047:34;;;22243:32:17::1;::::0;::::1;::::0;::::1;::::0;15937:18:18;;22243:53:17::1;15790:297:18::0;22188:322:17::1;22317:28;::::0;::::1;22313:197;;22361:51;::::0;22369:10:::1;::::0;22390:21:::1;22361:51:::0;::::1;;;::::0;::::1;::::0;;;22390:21;22369:10;22361:51;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;22522:232:::0;;:::o;22313:197::-:1;22443:56;:35;::::0;::::1;22479:10;22491:7:::0;22443:35:::1;:56::i;23164:74::-:0;1489:6:5;;1629:23;1489:6;888:10:14;1629:23:5;1621:68;;;;;;;22442:2:18;1621:68:5;;;22424:21:18;;;22461:18;;;22454:30;22520:34;22500:18;;;22493:62;22572:18;;1621:68:5;22240:356:18;1621:68:5;23221:10:17::1;:8;:10::i;:::-;23164:74::o:0;23088:70::-;1489:6:5;;1629:23;1489:6;888:10:14;1629:23:5;1621:68;;;;;;;22442:2:18;1621:68:5;;;22424:21:18;;;22461:18;;;22454:30;22520:34;22500:18;;;22493:62;22572:18;;1621:68:5;22240:356:18;1621:68:5;23143:8:17::1;:6;:8::i;2524:127:5:-:0;2575:4;2615:29;:27;:29::i;:::-;2597:15;:47;2590:54;;2524:127;:::o;2049:93::-;1489:6;;1629:23;1489:6;888:10:14;1629:23:5;1621:68;;;;;;;22442:2:18;1621:68:5;;;22424:21:18;;;22461:18;;;22454:30;22520:34;22500:18;;;22493:62;22572:18;;1621:68:5;22240:356:18;1621:68:5;2115:20:::1;:18;:20::i;14572:4701:17:-:0;1680:1:11;2260:7;;:19;2252:63;;;;;;;15632:2:18;2252:63:11;;;15614:21:18;15671:2;15651:18;;;15644:30;15710:33;15690:18;;;15683:61;15761:18;;2252:63:11;15430:355:18;2252:63:11;1680:1;2390:7;:18;1081:7:16;;;;1302:9:::1;1294:38;;;::::0;::::1;::::0;;15287:2:18;1294:38:16::1;::::0;::::1;15269:21:18::0;15326:2;15306:18;;;15299:30;15365:18;15345;;;15338:46;15401:18;;1294:38:16::1;15085:340:18::0;1294:38:16::1;15409:37:17::2;::::0;::::2;;::::0;;;:21:::2;:37;::::0;;;;;:51;-1:-1:-1;15384:164:17::2;;;::::0;::::2;::::0;;22803:2:18;15384:164:17::2;::::0;::::2;22785:21:18::0;22842:2;22822:18;;;22815:30;22881:34;22861:18;;;22854:62;22952:24;22932:18;;;22925:52;22994:19;;15384:164:17::2;22601:418:18::0;15384:164:17::2;15725:37;::::0;::::2;;::::0;;;:21:::2;:37;::::0;;;;;:84:::2;::::0;2951:18:::2;::::0;15725:84:::2;:::i;:::-;15691:11;:118;15666:260;;;::::0;::::2;::::0;;23226:2:18;15666:260:17::2;::::0;::::2;23208:21:18::0;23265:2;23245:18;;;23238:30;23304:34;23284:18;;;23277:62;23375:34;23355:18;;;23348:62;23447:21;23426:19;;;23419:50;23486:19;;15666:260:17::2;23024:487:18::0;15666:260:17::2;16056:13;16041:12;:28;16016:146;;;::::0;::::2;::::0;;23718:2:18;16016:146:17::2;::::0;::::2;23700:21:18::0;23757:2;23737:18;;;23730:30;23796:34;23776:18;;;23769:62;23867:29;23847:18;;;23840:57;23914:19;;16016:146:17::2;23516:423:18::0;16016:146:17::2;16354:21;::::0;::::2;::::0;:28;16298:25;;:32;:84:::2;:153:::0;::::2;;;-1:-1:-1::0;16442:9:17;;16406:25;;:32;:45:::2;16298:153;:222;;;;-1:-1:-1::0;16511:9:17;;16475:25;;:32;:45:::2;16298:222;:291;;;;-1:-1:-1::0;16580:9:17;;16544:25;;:32;:45:::2;16298:291;16273:381;;;::::0;::::2;::::0;;24146:2:18;16273:381:17::2;::::0;::::2;24128:21:18::0;24185:2;24165:18;;;24158:30;24224:33;24204:18;;;24197:61;24275:18;;16273:381:17::2;23944:355:18::0;16273:381:17::2;16856:26;;16784:48;16799:14;16815:16;;16784:14;:48::i;:::-;:98;16759:220;;;::::0;::::2;::::0;;24506:2:18;16759:220:17::2;::::0;::::2;24488:21:18::0;24545:2;24525:18;;;24518:30;24584:34;24564:18;;;24557:62;24655:33;24635:18;;;24628:61;24706:19;;16759:220:17::2;24304:427:18::0;16759:220:17::2;17101:13;:20;17082:8;:15;:39;:94;;;;;17164:5;:12;17145:8;:15;:31;17082:94;17057:184;;;::::0;::::2;::::0;;24938:2:18;17057:184:17::2;::::0;::::2;24920:21:18::0;24977:2;24957:18;;;24950:30;25016:33;24996:18;;;24989:61;25067:18;;17057:184:17::2;24736:355:18::0;17057:184:17::2;17360:805;17402:14;:25;;;17445:14;:21;;;17484:2;17504;17524;17679:16;;17787:66;17879:8;17913:13;17952:5;17983:11;18020:14;18060:13;17643:452;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;17612:501;;;;;;18131:20;;17360:24;:805::i;:::-;18237:37;::::0;::::2;;::::0;;;:21:::2;:37;::::0;;;;:51;;;18381:524:::2;18405:8;:15;18401:1;:19;18381:524;;;18453:35;::::0;::::2;;::::0;;;:19:::2;:35;::::0;;;;;::::2;;18449:438;;;18528:14;18516:32;;;18578:13;18592:1;18578:16;;;;;;;;:::i;:::-;;;;;;;18624:8;18633:1;18624:11;;;;;;;;:::i;:::-;;;;;;;18516:145;;;;;;;;;;;;;;;15994:42:18::0;15982:55;;;;15964:74;;16069:2;16054:18;;16047:34;15952:2;15937:18;;15790:297;18516:145:17::2;;;;;;;;;;;;;;;;;;::::0;::::2;;;;;;;;;;;;::::0;::::2;;;;;;;;;18449:438;;;18716:148;18781:13;18795:1;18781:16;;;;;;;;:::i;:::-;;;;;;;18827:8;18836:1;18827:11;;;;;;;;:::i;:::-;;;;;;;18723:14;18716:35;;;;:148;;;;;:::i;:::-;18422:3;;18381:524;;;-1:-1:-1::0;19021:20:17::2;::::0;:24:::2;::::0;19044:1:::2;19021:24;:::i;:::-;18998:20;:47:::0;;;19083:12:::2;19059:21;:36:::0;19114:142:::2;::::0;552:25:18;;;19114:142:17::2;::::0;::::2;::::0;19161:11;;19114:142:::2;::::0;540:2:18;525:18;19114:142:17::2;;;;;;;-1:-1:-1::0;;1637:1:11;2563:7;:22;-1:-1:-1;;;;;;;;14572:4701:17:o;2838:154:5:-;2905:20;:18;:20::i;:::-;2897:58;;;;;;;27612:2:18;2897:58:5;;;27594:21:18;27651:2;27631:18;;;27624:30;27690:27;27670:18;;;27663:55;27735:18;;2897:58:5;27410:349:18;10872:3346:17;1081:7:16;;;;1302:9;1294:38;;;;;;;15287:2:18;1294:38:16;;;15269:21:18;15326:2;15306:18;;;15299:30;15365:18;15345;;;15338:46;15401:18;;1294:38:16;15085:340:18;1294:38:16;11425:14:17::1;:26;;;11400:10;:22;;;:51;11379:153;;;::::0;::::1;::::0;;27966:2:18;11379:153:17::1;::::0;::::1;27948:21:18::0;28005:2;27985:18;;;27978:30;28044:34;28024:18;;;28017:62;28115:25;28095:18;;;28088:53;28158:19;;11379:153:17::1;27764:419:18::0;11379:153:17::1;11692:21;;::::0;::::1;:14:::0;:21:::1;:::i;:::-;:28:::0;-1:-1:-1;11656:25:17::1;:14:::0;;:25:::1;:::i;:::-;:32;;:64;:129;;;;-1:-1:-1::0;11776:2:17;11740:25:::1;:14:::0;;:25:::1;:::i;:::-;:32;;:45;11656:129;:194;;;;-1:-1:-1::0;11841:2:17;11805:25:::1;:14:::0;;:25:::1;:::i;:::-;:32;;:45;11656:194;:259;;;;-1:-1:-1::0;11906:2:17;11870:25:::1;:14:::0;;:25:::1;:::i;:::-;:32;;:45;11656:259;11635:337;;;::::0;::::1;::::0;;24146:2:18;11635:337:17::1;::::0;::::1;24128:21:18::0;24185:2;24165:18;;;24158:30;24224:33;24204:18;;;24197:61;24275:18;;11635:337:17::1;23944:355:18::0;11635:337:17::1;12151:49;2951:18;12151:26;::::0;::::1;;:49;:::i;:::-;12110:10;:22;;;:90;12089:221;;;::::0;::::1;::::0;;29608:2:18;12089:221:17::1;::::0;::::1;29590:21:18::0;29647:2;29627:18;;;29620:30;29686:34;29666:18;;;29659:62;29757:34;29737:18;;;29730:62;29829:22;29808:19;;;29801:51;29869:19;;12089:221:17::1;29406:488:18::0;12089:221:17::1;12496:26;::::0;12428:48:::1;;12443:14:::0;12428:48:::1;:::i;:::-;12459:16;;12428:14;:48::i;:::-;:94;12407:204;;;::::0;::::1;::::0;;24506:2:18;12407:204:17::1;::::0;::::1;24488:21:18::0;24545:2;24525:18;;;24518:30;24584:34;24564:18;;;24557:62;24655:33;24635:18;;;24628:61;24706:19;;12407:204:17::1;24304:427:18::0;12407:204:17::1;12711:21;12735:44;;12750:10:::0;12735:44:::1;:::i;:::-;12711:68:::0;-1:-1:-1;12789:217:17::1;12827:25;:14:::0;;:25:::1;:::i;:::-;12789:217;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;12866:21:17::1;::::0;-1:-1:-1;;;12866:21:17::1;::::0;::::1;::::0;::::1;:::i;:::-;12789:217;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;12789:217:17::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;-1:-1:-1;12901:2:17;;-1:-1:-1;12901:2:17;;;;12789:217;::::1;::::0;12901:2;;12789:217;12901:2;12789:217;::::1;;::::0;::::1;::::0;;;;-1:-1:-1;;12789:217:17::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;-1:-1:-1;12917:2:17;;-1:-1:-1;12917:2:17;;;;12789:217;::::1;::::0;12917:2;;12789:217;12917:2;12789:217;::::1;;::::0;::::1;::::0;;;;-1:-1:-1;;12789:217:17::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;-1:-1:-1;12933:2:17;;-1:-1:-1;12933:2:17;;;;12789:217;::::1;::::0;12933:2;;12789:217;12933:2;12789:217;::::1;;::::0;::::1;::::0;;;;-1:-1:-1;;12976:20:17::1;::::0;12949:13;;-1:-1:-1;12976:20:17;-1:-1:-1;12789:24:17::1;:217::i;:::-;13017:131;13052:21;:10:::0;;:21:::1;:::i;:::-;13087:17;;::::0;::::1;:10:::0;:17:::1;:::i;:::-;13118:20;;13017:21;:131::i;:::-;13292:26;:42:::0;;;13396:22:::1;::::0;::::1;;13372:21;:46:::0;13489:12:::1;13464:22;:37:::0;-1:-1:-1;13610:22:17::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;:36;;;;:68;;;;-1:-1:-1::0;13650:23:17::1;::::0;::::1;;:28:::0;::::1;13610:68;13593:247;;;13703:126;13764:10;13792:23;::::0;::::1;;13710:22;::::0;;;::::1;::::0;::::1;;:::i;:::-;13703:43;;::::0;:126;:43:::1;:126::i;:::-;13889:20;::::0;:24:::1;::::0;13912:1:::1;13889:24;:::i;:::-;13866:20;:47:::0;;;13947:12:::1;13923:21;:36:::0;14006:22:::1;::::0;::::1;;::::0;13974:237:::1;::::0;14076:23:::1;::::0;::::1;;14113:22;::::0;;;::::1;::::0;::::1;;:::i;:::-;14149:21;:10:::0;;:21:::1;:::i;:::-;14184:10;:17;;;;;;;;:::i;:::-;13974:237;;;;;;;;;;;;:::i;:::-;;;;;;;;11283:2935;10872:3346:::0;;;;;;;;:::o;22779:303::-;22973:17;23009:5;;23016:7;;23025:9;22993:42;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;23045:30:17;;;;;23056:10;23045:30;;;15964:74:18;16054:18;;;16047:34;;;22973:62:17;;-1:-1:-1;23045:10:17;;;;;;15937:18:18;;23045:30:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;22963:119;22779:303;;;;;;;;:::o;5144:1329::-;1485:13:15;;;;;;;;:30;;-1:-1:-1;1503:12:15;;;;1502:13;1485:30;1477:89;;;;;;;32457:2:18;1477:89:15;;;32439:21:18;32496:2;32476:18;;;32469:30;32535:34;32515:18;;;32508:62;32606:16;32586:18;;;32579:44;32640:19;;1477:89:15;32255:410:18;1477:89:15;1577:19;1600:13;;;;;;1599:14;1623:98;;;;1657:13;:20;;1691:19;;;;;;1623:98;5612:26:17::1;:24;:26::i;:::-;5648;:24;:26::i;:::-;5704:60;5726:11;;5739:7;;5748:15;5704:21;:60::i;:::-;5775:25;-1:-1:-1::0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5775:25:17::1;5820:50;;;;;;;;5831:11;;5820:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;;;5820:50:17;;;-1:-1:-1;5820:50:17::1;::::0;;::::1;::::0;;::::1;::::0;;;;;;;;;;;;;::::1;::::0;;;5844:7;;;;;;5820:50;::::1;::::0;5844:7;;5820:50;5844:7;5820:50;::::1;;::::0;::::1;::::0;;;-1:-1:-1;5820:50:17;;;-1:-1:-1;;;5820:50:17::1;::::0;::::1;::::0;;;;;;;;;;;;;;;;5810:60;;-1:-1:-1;5905:36:17::1;5810:60:::0;5929:11;5905:14:::1;:36::i;:::-;5972:16;:30:::0;;;6012:20:::1;:38:::0;;;6060:26:::1;:42:::0;;;6135:20:::1;::::0;5881:60;;-1:-1:-1;6135:24:17::1;::::0;6158:1:::1;6135:24;:::i;:::-;6112:20;:47:::0;;;6194:12:::1;6169:22;:37:::0;;;6216:21:::1;:36:::0;6316:21:::1;::::0;6284:182:::1;::::0;6316:21;;6284:182:::1;::::0;::::1;::::0;6112:47;-1:-1:-1;;;;6424:11:17;;;;6449:7;;;;6284:182:::1;:::i;:::-;;;;;;;;5602:871;;1747:14:15::0;1743:66;;;1793:5;1777:21;;;;;;1743:66;1467:348;5144:1329:17;;;;;;:::o;3141:242:5:-;1489:6;;1629:23;1489:6;888:10:14;1629:23:5;1621:68;;;;;;;22442:2:18;1621:68:5;;;22424:21:18;;;22461:18;;;22454:30;22520:34;22500:18;;;22493:62;22572:18;;1621:68:5;22240:356:18;1621:68:5;3231:22:::1;::::0;::::1;3223:73;;;::::0;::::1;::::0;;33669:2:18;3223:73:5::1;::::0;::::1;33651:21:18::0;33708:2;33688:18;;;33681:30;33747:34;33727:18;;;33720:62;33818:8;33798:18;;;33791:36;33844:19;;3223:73:5::1;33467:402:18::0;3223:73:5::1;3332:6;::::0;3311:38:::1;::::0;::::1;::::0;;::::1;::::0;3332:6:::1;::::0;3311:38:::1;::::0;3332:6:::1;::::0;3311:38:::1;3359:6;:17:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;3141:242::o;21392:649:17:-;21565:17;21601:5;;21608:7;;21617:9;21585:42;;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21637:35:17;;;;;;;:19;:35;;;;;:42;;;;21675:4;21637:42;;;;;;21770:20;;21565:62;;-1:-1:-1;21770:24:17;;:20;:24;:::i;:::-;21747:20;:47;;;21828:12;21804:21;:36;21855:179;;;;;;;;;;21887:12;;;;21941:5;;;;21960:7;;;;21981:9;;21855:179;:::i;:::-;;;;;;;;21555:486;21392:649;;;;;;;:::o;807:203:9:-;934:68;;34870:42:18;34939:15;;;934:68:9;;;34921:34:18;34991:15;;34971:18;;;34964:43;35023:18;;;35016:34;;;907:96:9;;927:5;;957:27;;34833:18:18;;934:68:9;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;907:19;:96::i;:::-;807:203;;;;:::o;23244:461:17:-;23297:13;23326:2;23332:1;23326:7;23322:48;;-1:-1:-1;;23349:10:17;;;;;;;;;;;;;;;;;;23244:461::o;23322:48::-;23391:2;23379:9;23424:66;23431:6;;23424:66;;23453:5;;;;:::i;:::-;;-1:-1:-1;23472:7:17;;-1:-1:-1;23477:2:17;23472:7;;:::i;:::-;;;23424:66;;;23499:17;23529:3;23519:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;23519:14:17;-1:-1:-1;23499:34:17;-1:-1:-1;23555:3:17;23568:102;23575:7;;23568:102;;23628:7;23633:2;23628;:7;:::i;:::-;23623:12;;:2;:12;:::i;:::-;23610:27;;23598:4;23603:3;;;:::i;:::-;;;;23598:9;;;;;;;;:::i;:::-;;;;:39;;;;;;;;;;-1:-1:-1;23651:8:17;23657:2;23651:8;;:::i;:::-;;;23568:102;;;-1:-1:-1;23693:4:17;23244:461;-1:-1:-1;;;;23244:461:17:o;626:175:9:-;735:58;;15994:42:18;15982:55;;735:58:9;;;15964:74:18;16054:18;;;16047:34;;;708:86:9;;728:5;;758:23;;15937:18:18;;735:58:9;15790:297:18;1927:107:16;1081:7;;;;1534:41;;;;;;;36095:2:18;1534:41:16;;;36077:21:18;36134:2;36114:18;;;36107:30;36173:22;36153:18;;;36146:50;36213:18;;1534:41:16;35893:344:18;1534:41:16;1981:7:::1;:15:::0;;;::::1;::::0;;2007:22:::1;888:10:14::0;2016:12:16::1;2007:22;::::0;9154:42:18;9142:55;;;9124:74;;9112:2;9097:18;2007:22:16::1;;;;;;;1927:107::o:0;1706:105::-;1081:7;;;;1302:9;1294:38;;;;;;;15287:2:18;1294:38:16;;;15269:21:18;15326:2;15306:18;;;15299:30;15365:18;15345;;;15338:46;15401:18;;1294:38:16;15085:340:18;1294:38:16;1761:7:::1;:14:::0;;;::::1;1771:4;1761:14;::::0;;1786:20:::1;1793:12;888:10:14::0;;809:96;3389:129:5;3463:6;;3442:40;;3479:1;;3442:40;3463:6;;3442:40;;3479:1;;3442:40;3492:6;:19;;;;;;3389:129::o;7705:661:17:-;7825:7;7899:18;7920:66;7899:87;;;;7997:18;8069:11;8098:10;8126:11;:23;;;8167:11;:22;;;8207:11;:18;;;8243:11;:24;;;8285:11;:23;;;8041:281;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;8018:314;;8041:281;8018:314;;;;;-1:-1:-1;;;7705:661:17;;;;;:::o;8372:2089::-;8822:23;8865:9;8860:1380;8884:18;:25;8880:1;:29;8860:1380;;;9130:2;9133:1;9130:5;;;;;;;;:::i;:::-;;;;;;;:10;;9139:1;9130:10;9126:1104;;9268:205;9303:18;9322:1;9303:21;;;;;;;;:::i;:::-;;;;;;;9350:8;9384:2;9387:1;9384:5;;;;;;;;:::i;:::-;;;;;;;9415:2;9418:1;9415:5;;;;;;;;:::i;:::-;;;;;;;9446:2;9449:1;9446:5;;;;;;;;:::i;:::-;;;;;;;9268:9;:205::i;:::-;9239:311;;;;;;;37323:2:18;9239:311:17;;;37305:21:18;37362:2;37342:18;;;37335:30;37401:34;37381:18;;;37374:62;37472:5;37452:18;;;37445:33;37495:19;;9239:311:17;37121:399:18;9239:311:17;9601:2;9573:18;:25;:30;:66;;;;-1:-1:-1;1489:6:5;;;;9607:32:17;;:18;9626:1;9607:21;;;;;;;;:::i;:::-;;;;;;;:32;;;9573:66;9569:377;;;9921:7;;;;9569:377;10043:14;10058:1;10043:17;;;;;;;;:::i;:::-;;;;;;;10025:15;:35;;;;:::i;:::-;10007:53;;10153:15;10135;:33;10192:5;10131:85;;8911:3;;8860:1380;;;;10334:15;10316;:33;10295:140;;;;;;;37727:2:18;10295:140:17;;;37709:21:18;37766:2;37746:18;;;37739:30;37805:34;37785:18;;;37778:62;37876:30;37856:18;;;37849:58;37924:19;;10295:140:17;37525:424:18;10295:140:17;8812:1649;8372:2089;;;;;;;:::o;4268:870::-;4521:36;;;4500:114;;;;;;;24146:2:18;4500:114:17;;;24128:21:18;24185:2;24165:18;;;24158:30;24224:33;24204:18;;;24197:61;24275:18;;4500:114:17;23944:355:18;4500:114:17;4738:23;4780:9;4775:206;4795:18;;;4775:206;;;4870:7;;4878:1;4870:10;;;;;;;:::i;:::-;;;;;;;4852:15;:28;;;;:::i;:::-;4834:46;;4916:15;4898;:33;4951:5;4894:77;4815:3;;4775:206;;;;5030:15;5012;:33;4991:140;;;;;;;37727:2:18;4991:140:17;;;37709:21:18;37766:2;37746:18;;;37739:30;37805:34;37785:18;;;37778:62;37876:30;37856:18;;;37849:58;37924:19;;4991:140:17;37525:424:18;740:64:14;1485:13:15;;;;;;;;:30;;-1:-1:-1;1503:12:15;;;;1502:13;1485:30;1477:89;;;;;;;32457:2:18;1477:89:15;;;32439:21:18;32496:2;32476:18;;;32469:30;32535:34;32515:18;;;32508:62;32606:16;32586:18;;;32579:44;32640:19;;1477:89:15;32255:410:18;1477:89:15;1577:19;1600:13;;;;;;1599:14;1623:98;;;;1657:13;:20;;1691:19;;;;;;1623:98;1747:14;1743:66;;;1793:5;1777:21;;;;;;1743:66;1467:348;740:64:14:o;1105:236:5:-;1485:13:15;;;;;;;;:30;;-1:-1:-1;1503:12:15;;;;1502:13;1485:30;1477:89;;;;;;;32457:2:18;1477:89:15;;;32439:21:18;32496:2;32476:18;;;32469:30;32535:34;32515:18;;;32508:62;32606:16;32586:18;;;32579:44;32640:19;;1477:89:15;32255:410:18;1477:89:15;1577:19;1600:13;;;;;;1599:14;1623:98;;;;1657:13;:20;;1691:19;;;;;;1623:98;1214:6:5::1;:18:::0;;;::::1;888:10:14::0;1214:18:5;;::::1;::::0;;;1261:15:::1;1242:16;:34:::0;1291:43:::1;::::0;888:10:14;;1172:17:5::1;::::0;1291:43:::1;::::0;1172:17;;1291:43:::1;1162:179;1747:14:15::0;1743:66;;;1793:5;1777:21;;;;;;1467:348;1105:236:5:o;3014:751:9:-;3433:23;3459:69;3487:4;3459:69;;;;;;;;;;;;;;;;;3467:5;3459:27;;;;:69;;;;;:::i;:::-;3542:17;;3433:95;;-1:-1:-1;3542:21:9;3538:221;;3682:10;3671:30;;;;;;;;;;;;:::i;:::-;3663:85;;;;;;;38438:2:18;3663:85:9;;;38420:21:18;38477:2;38457:18;;;38450:30;38516:34;38496:18;;;38489:62;38587:12;38567:18;;;38560:40;38617:19;;3663:85:9;38236:406:18;6692:362:17;6911:62;;38889:66:18;6911:62:17;;;38877:79:18;38972:12;;;38965:28;;;6848:4:17;;;;39009:12:18;;6911:62:17;;;;;;;;;;;;;6888:95;;6911:62;6888:95;;;;7011:36;;;;;;;;;39259:25:18;;;39332:4;39320:17;;39300:18;;;39293:45;;;;39354:18;;;39347:34;;;39397:18;;;39390:34;;;6888:95:17;-1:-1:-1;7011:36:17;;39231:19:18;;7011:36:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7000:47;;:7;:47;;;6993:54;;;6692:362;;;;;;;:::o;3573:193:12:-;3676:12;3707:52;3729:6;3737:4;3743:1;3746:12;3707:21;:52::i;:::-;3700:59;;3573:193;;;;;;:::o;4600:523::-;4727:12;4784:5;4759:21;:30;;4751:81;;;;;;;39637:2:18;4751:81:12;;;39619:21:18;39676:2;39656:18;;;39649:30;39715:34;39695:18;;;39688:62;39786:8;39766:18;;;39759:36;39812:19;;4751:81:12;39435:402:18;4751:81:12;1078:20;;4842:60;;;;;;;40044:2:18;4842:60:12;;;40026:21:18;40083:2;40063:18;;;40056:30;40122:31;40102:18;;;40095:59;40171:18;;4842:60:12;39842:353:18;4842:60:12;4973:12;4987:23;5014:6;:11;;5034:5;5042:4;5014:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4972:75;;;;5064:52;5082:7;5091:10;5103:12;5064:17;:52::i;:::-;5057:59;4600:523;-1:-1:-1;;;;;;;4600:523:12:o;7083:725::-;7198:12;7226:7;7222:580;;;-1:-1:-1;7256:10:12;7249:17;;7222:580;7367:17;;:21;7363:429;;7625:10;7619:17;7685:15;7672:10;7668:2;7664:19;7657:44;7363:429;7764:12;7757:20;;;;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;:::o;14:196:18:-;82:20;;142:42;131:54;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:186::-;274:6;327:2;315:9;306:7;302:23;298:32;295:52;;;343:1;340;333:12;295:52;366:29;385:9;366:29;:::i;588:348::-;640:8;650:6;704:3;697:4;689:6;685:17;681:27;671:55;;722:1;719;712:12;671:55;-1:-1:-1;745:20:18;;788:18;777:30;;774:50;;;820:1;817;810:12;774:50;857:4;849:6;845:17;833:29;;909:3;902:4;893:6;885;881:19;877:30;874:39;871:59;;;926:1;923;916:12;871:59;588:348;;;;;:::o;941:622::-;1039:6;1047;1055;1063;1071;1124:3;1112:9;1103:7;1099:23;1095:33;1092:53;;;1141:1;1138;1131:12;1092:53;1164:29;1183:9;1164:29;:::i;:::-;1154:39;;1240:2;1229:9;1225:18;1212:32;1202:42;;1291:2;1280:9;1276:18;1263:32;1253:42;;1346:2;1335:9;1331:18;1318:32;1373:18;1365:6;1362:30;1359:50;;;1405:1;1402;1395:12;1359:50;1444:59;1495:7;1486:6;1475:9;1471:22;1444:59;:::i;:::-;941:622;;;;-1:-1:-1;941:622:18;;-1:-1:-1;1522:8:18;;1418:85;941:622;-1:-1:-1;;;941:622:18:o;1568:260::-;1636:6;1644;1697:2;1685:9;1676:7;1672:23;1668:32;1665:52;;;1713:1;1710;1703:12;1665:52;1736:29;1755:9;1736:29;:::i;:::-;1726:39;;1784:38;1818:2;1807:9;1803:18;1784:38;:::i;:::-;1774:48;;1568:260;;;;;:::o;1833:254::-;1901:6;1909;1962:2;1950:9;1941:7;1937:23;1933:32;1930:52;;;1978:1;1975;1968:12;1930:52;2001:29;2020:9;2001:29;:::i;:::-;1991:39;2077:2;2062:18;;;;2049:32;;-1:-1:-1;;;1833:254:18:o;2284:180::-;2343:6;2396:2;2384:9;2375:7;2371:23;2367:32;2364:52;;;2412:1;2409;2402:12;2364:52;-1:-1:-1;2435:23:18;;2284:180;-1:-1:-1;2284:180:18:o;2469:184::-;2521:77;2518:1;2511:88;2618:4;2615:1;2608:15;2642:4;2639:1;2632:15;2658:334;2729:2;2723:9;2785:2;2775:13;;2790:66;2771:86;2759:99;;2888:18;2873:34;;2909:22;;;2870:62;2867:88;;;2935:18;;:::i;:::-;2971:2;2964:22;2658:334;;-1:-1:-1;2658:334:18:o;2997:183::-;3057:4;3090:18;3082:6;3079:30;3076:56;;;3112:18;;:::i;:::-;-1:-1:-1;3157:1:18;3153:14;3169:4;3149:25;;2997:183::o;3185:674::-;3239:5;3292:3;3285:4;3277:6;3273:17;3269:27;3259:55;;3310:1;3307;3300:12;3259:55;3346:6;3333:20;3372:4;3396:60;3412:43;3452:2;3412:43;:::i;:::-;3396:60;:::i;:::-;3478:3;3502:2;3497:3;3490:15;3530:4;3525:3;3521:14;3514:21;;3587:4;3581:2;3578:1;3574:10;3566:6;3562:23;3558:34;3544:48;;3615:3;3607:6;3604:15;3601:35;;;3632:1;3629;3622:12;3601:35;3668:4;3660:6;3656:17;3682:148;3698:6;3693:3;3690:15;3682:148;;;3764:23;3783:3;3764:23;:::i;:::-;3752:36;;3808:12;;;;3715;;3682:148;;;-1:-1:-1;3848:5:18;3185:674;-1:-1:-1;;;;;;3185:674:18:o;3864:668::-;3918:5;3971:3;3964:4;3956:6;3952:17;3948:27;3938:55;;3989:1;3986;3979:12;3938:55;4025:6;4012:20;4051:4;4075:60;4091:43;4131:2;4091:43;:::i;4075:60::-;4157:3;4181:2;4176:3;4169:15;4209:4;4204:3;4200:14;4193:21;;4266:4;4260:2;4257:1;4253:10;4245:6;4241:23;4237:34;4223:48;;4294:3;4286:6;4283:15;4280:35;;;4311:1;4308;4301:12;4280:35;4347:4;4339:6;4335:17;4361:142;4377:6;4372:3;4369:15;4361:142;;;4443:17;;4431:30;;4481:12;;;;4394;;4361:142;;4537:954;4594:5;4642:4;4630:9;4625:3;4621:19;4617:30;4614:50;;;4660:1;4657;4650:12;4614:50;4693:2;4687:9;4735:4;4727:6;4723:17;4759:18;4827:6;4815:10;4812:22;4807:2;4795:10;4792:18;4789:46;4786:72;;;4838:18;;:::i;:::-;4878:10;4874:2;4867:22;4907:6;4898:15;;4949:9;4936:23;4922:37;;4982:2;4974:6;4971:14;4968:34;;;4998:1;4995;4988:12;4968:34;5026:57;5079:3;5070:6;5059:9;5055:22;5026:57;:::i;:::-;5018:6;5011:73;5137:2;5126:9;5122:18;5109:32;5093:48;;5166:2;5156:8;5153:16;5150:36;;;5182:1;5179;5172:12;5150:36;;5219:59;5274:3;5263:8;5252:9;5248:24;5219:59;:::i;:::-;5214:2;5206:6;5202:15;5195:84;;5340:2;5329:9;5325:18;5312:32;5307:2;5299:6;5295:15;5288:57;5406:2;5395:9;5391:18;5378:32;5373:2;5365:6;5361:15;5354:57;5445:39;5479:3;5468:9;5464:19;5445:39;:::i;:::-;5439:3;5431:6;5427:16;5420:65;;4537:954;;;;:::o;5496:114::-;5580:4;5573:5;5569:16;5562:5;5559:27;5549:55;;5600:1;5597;5590:12;5615:739;5667:5;5720:3;5713:4;5705:6;5701:17;5697:27;5687:55;;5738:1;5735;5728:12;5687:55;5774:6;5761:20;5800:4;5824:60;5840:43;5880:2;5840:43;:::i;5824:60::-;5906:3;5930:2;5925:3;5918:15;5958:4;5953:3;5949:14;5942:21;;6015:4;6009:2;6006:1;6002:10;5994:6;5990:23;5986:34;5972:48;;6043:3;6035:6;6032:15;6029:35;;;6060:1;6057;6050:12;6029:35;6096:4;6088:6;6084:17;6110:215;6126:6;6121:3;6118:15;6110:215;;;6206:3;6193:17;6223:29;6246:5;6223:29;:::i;:::-;6265:18;;6303:12;;;;6143;;6110:215;;7032:1941;7348:6;7356;7364;7372;7380;7388;7396;7404;7412;7420;7473:3;7461:9;7452:7;7448:23;7444:33;7441:53;;;7490:1;7487;7480:12;7441:53;7530:9;7517:23;7559:18;7600:2;7592:6;7589:14;7586:34;;;7616:1;7613;7606:12;7586:34;7639:61;7692:7;7683:6;7672:9;7668:22;7639:61;:::i;:::-;7629:71;;7753:2;7742:9;7738:18;7725:32;7709:48;;7782:2;7772:8;7769:16;7766:36;;;7798:1;7795;7788:12;7766:36;7821:61;7874:7;7863:8;7852:9;7848:24;7821:61;:::i;:::-;7811:71;;7935:2;7924:9;7920:18;7907:32;7891:48;;7964:2;7954:8;7951:16;7948:36;;;7980:1;7977;7970:12;7948:36;8003:63;8058:7;8047:8;8036:9;8032:24;8003:63;:::i;:::-;7993:73;;8119:2;8108:9;8104:18;8091:32;8075:48;;8148:2;8138:8;8135:16;8132:36;;;8164:1;8161;8154:12;8132:36;8187:63;8242:7;8231:8;8220:9;8216:24;8187:63;:::i;:::-;8177:73;;8303:3;8292:9;8288:19;8275:33;8259:49;;8333:2;8323:8;8320:16;8317:36;;;8349:1;8346;8339:12;8317:36;8372:63;8427:7;8416:8;8405:9;8401:24;8372:63;:::i;:::-;8362:73;;8488:3;8477:9;8473:19;8460:33;8444:49;;8518:2;8508:8;8505:16;8502:36;;;8534:1;8531;8524:12;8502:36;8557:63;8612:7;8601:8;8590:9;8586:24;8557:63;:::i;:::-;8547:73;;8673:3;8662:9;8658:19;8645:33;8629:49;;8703:2;8693:8;8690:16;8687:36;;;8719:1;8716;8709:12;8687:36;;8742:63;8797:7;8786:8;8775:9;8771:24;8742:63;:::i;:::-;8732:73;;;8852:3;8841:9;8837:19;8824:33;8814:43;;8876:39;8910:3;8899:9;8895:19;8876:39;:::i;:::-;8866:49;;8962:3;8951:9;8947:19;8934:33;8924:43;;7032:1941;;;;;;;;;;;;;:::o;9391:159::-;9454:5;9499:3;9490:6;9485:3;9481:16;9477:26;9474:46;;;9516:1;9513;9506:12;9474:46;-1:-1:-1;9538:6:18;9391:159;-1:-1:-1;9391:159:18:o;9555:365::-;9616:8;9626:6;9680:3;9673:4;9665:6;9661:17;9657:27;9647:55;;9698:1;9695;9688:12;9647:55;-1:-1:-1;9721:20:18;;9764:18;9753:30;;9750:50;;;9796:1;9793;9786:12;9750:50;9833:4;9825:6;9821:17;9809:29;;9893:3;9886:4;9876:6;9873:1;9869:14;9861:6;9857:27;9853:38;9850:47;9847:67;;;9910:1;9907;9900:12;9925:1562;10159:6;10167;10175;10183;10191;10199;10207;10215;10268:3;10256:9;10247:7;10243:23;10239:33;10236:53;;;10285:1;10282;10275:12;10236:53;10325:9;10312:23;10354:18;10395:2;10387:6;10384:14;10381:34;;;10411:1;10408;10401:12;10381:34;10434:70;10496:7;10487:6;10476:9;10472:22;10434:70;:::i;:::-;10424:80;;10557:2;10546:9;10542:18;10529:32;10513:48;;10586:2;10576:8;10573:16;10570:36;;;10602:1;10599;10592:12;10570:36;10625:72;10689:7;10678:8;10667:9;10663:24;10625:72;:::i;:::-;10615:82;;10750:2;10739:9;10735:18;10722:32;10706:48;;10779:2;10769:8;10766:16;10763:36;;;10795:1;10792;10785:12;10763:36;10834:70;10896:7;10885:8;10874:9;10870:24;10834:70;:::i;:::-;10923:8;;-1:-1:-1;10808:96:18;-1:-1:-1;11011:2:18;10996:18;;10983:32;;-1:-1:-1;11027:16:18;;;11024:36;;;11056:1;11053;11046:12;11024:36;11095:70;11157:7;11146:8;11135:9;11131:24;11095:70;:::i;:::-;11184:8;;-1:-1:-1;11069:96:18;-1:-1:-1;11272:3:18;11257:19;;11244:33;;-1:-1:-1;11289:16:18;;;11286:36;;;11318:1;11315;11308:12;11286:36;;11357:70;11419:7;11408:8;11397:9;11393:24;11357:70;:::i;:::-;9925:1562;;;;-1:-1:-1;9925:1562:18;;-1:-1:-1;9925:1562:18;;;;;;11446:8;-1:-1:-1;;;9925:1562:18:o;11492:1211::-;11621:6;11629;11637;11645;11653;11661;11669;11677;11730:3;11718:9;11709:7;11705:23;11701:33;11698:53;;;11747:1;11744;11737:12;11698:53;11787:9;11774:23;11816:18;11857:2;11849:6;11846:14;11843:34;;;11873:1;11870;11863:12;11843:34;11912:59;11963:7;11954:6;11943:9;11939:22;11912:59;:::i;:::-;11990:8;;-1:-1:-1;11886:85:18;-1:-1:-1;12078:2:18;12063:18;;12050:32;;-1:-1:-1;12094:16:18;;;12091:36;;;12123:1;12120;12113:12;12091:36;12162:61;12215:7;12204:8;12193:9;12189:24;12162:61;:::i;:::-;12242:8;;-1:-1:-1;12136:87:18;-1:-1:-1;12330:2:18;12315:18;;12302:32;;-1:-1:-1;12346:16:18;;;12343:36;;;12375:1;12372;12365:12;12343:36;;12414:61;12467:7;12456:8;12445:9;12441:24;12414:61;:::i;:::-;12494:8;;-1:-1:-1;12388:87:18;-1:-1:-1;;12579:2:18;12564:18;;12551:32;12592:29;12551:32;12592:29;:::i;:::-;12640:5;12630:15;;;12692:3;12681:9;12677:19;12664:33;12654:43;;11492:1211;;;;;;;;;;;:::o;12708:906::-;12848:6;12856;12864;12872;12880;12888;12941:3;12929:9;12920:7;12916:23;12912:33;12909:53;;;12958:1;12955;12948:12;12909:53;12994:9;12981:23;12971:33;;13051:2;13040:9;13036:18;13023:32;13013:42;;13106:2;13095:9;13091:18;13078:32;13129:18;13170:2;13162:6;13159:14;13156:34;;;13186:1;13183;13176:12;13156:34;13225:68;13285:7;13276:6;13265:9;13261:22;13225:68;:::i;:::-;13312:8;;-1:-1:-1;13199:94:18;-1:-1:-1;13400:2:18;13385:18;;13372:32;;-1:-1:-1;13416:16:18;;;13413:36;;;13445:1;13442;13435:12;13413:36;;13484:70;13546:7;13535:8;13524:9;13520:24;13484:70;:::i;:::-;12708:906;;;;-1:-1:-1;12708:906:18;;-1:-1:-1;12708:906:18;;13573:8;;12708:906;-1:-1:-1;;;12708:906:18:o;13619:1142::-;13739:6;13747;13755;13763;13771;13779;13787;13840:3;13828:9;13819:7;13815:23;13811:33;13808:53;;;13857:1;13854;13847:12;13808:53;13897:9;13884:23;13926:18;13967:2;13959:6;13956:14;13953:34;;;13983:1;13980;13973:12;13953:34;14022:59;14073:7;14064:6;14053:9;14049:22;14022:59;:::i;:::-;14100:8;;-1:-1:-1;13996:85:18;-1:-1:-1;14188:2:18;14173:18;;14160:32;;-1:-1:-1;14204:16:18;;;14201:36;;;14233:1;14230;14223:12;14201:36;14272:61;14325:7;14314:8;14303:9;14299:24;14272:61;:::i;:::-;14352:8;;-1:-1:-1;14246:87:18;-1:-1:-1;14440:2:18;14425:18;;14412:32;;-1:-1:-1;14456:16:18;;;14453:36;;;14485:1;14482;14475:12;14453:36;;14524:61;14577:7;14566:8;14555:9;14551:24;14524:61;:::i;:::-;14604:8;;-1:-1:-1;14498:87:18;-1:-1:-1;;14689:2:18;14674:18;;14661:32;14702:29;14661:32;14702:29;:::i;:::-;14750:5;14740:15;;;13619:1142;;;;;;;;;;:::o;14766:184::-;14818:77;14815:1;14808:88;14915:4;14912:1;14905:15;14939:4;14936:1;14929:15;14955:125;15020:9;;;15041:10;;;15038:36;;;15054:18;;:::i;16092:326::-;16181:6;16176:3;16169:19;16233:6;16226:5;16219:4;16214:3;16210:14;16197:43;;16285:1;16278:4;16269:6;16264:3;16260:16;16256:27;16249:38;16151:3;16407:4;16337:66;16332:2;16324:6;16320:15;16316:88;16311:3;16307:98;16303:109;16296:116;;16092:326;;;;:::o;16423:389::-;16638:6;16627:9;16620:25;16681:6;16676:2;16665:9;16661:18;16654:34;16724:2;16719;16708:9;16704:18;16697:30;16601:4;16744:62;16802:2;16791:9;16787:18;16779:6;16771;16744:62;:::i;:::-;16736:70;16423:389;-1:-1:-1;;;;;;16423:389:18:o;16817:184::-;16887:6;16940:2;16928:9;16919:7;16915:23;16911:32;16908:52;;;16956:1;16953;16946:12;16908:52;-1:-1:-1;16979:16:18;;16817:184;-1:-1:-1;16817:184:18:o;17006:128::-;17073:9;;;17094:11;;;17091:37;;;17108:18;;:::i;17139:247::-;17207:6;17260:2;17248:9;17239:7;17235:23;17231:32;17228:52;;;17276:1;17273;17266:12;17228:52;17308:9;17302:16;17327:29;17350:5;17327:29;:::i;17391:250::-;17476:1;17486:113;17500:6;17497:1;17494:13;17486:113;;;17576:11;;;17570:18;17557:11;;;17550:39;17522:2;17515:10;17486:113;;;-1:-1:-1;;17633:1:18;17615:16;;17608:27;17391:250::o;17646:778::-;17726:6;17779:2;17767:9;17758:7;17754:23;17750:32;17747:52;;;17795:1;17792;17785:12;17747:52;17828:9;17822:16;17857:18;17898:2;17890:6;17887:14;17884:34;;;17914:1;17911;17904:12;17884:34;17952:6;17941:9;17937:22;17927:32;;17997:7;17990:4;17986:2;17982:13;17978:27;17968:55;;18019:1;18016;18009:12;17968:55;18048:2;18042:9;18070:2;18066;18063:10;18060:36;;;18076:18;;:::i;:::-;18118:112;18226:2;18157:66;18150:4;18146:2;18142:13;18138:86;18134:95;18118:112;:::i;:::-;18105:125;;18253:2;18246:5;18239:17;18293:7;18288:2;18283;18279;18275:11;18271:20;18268:33;18265:53;;;18314:1;18311;18304:12;18265:53;18327:67;18391:2;18386;18379:5;18375:14;18370:2;18366;18362:11;18327:67;:::i;18429:198::-;18471:3;18509:5;18503:12;18524:65;18582:6;18577:3;18570:4;18563:5;18559:16;18524:65;:::i;:::-;18605:16;;;;;18429:198;-1:-1:-1;;18429:198:18:o;19053:2458::-;20368:3;20363;20356:16;20401:66;20397:1;20392:3;20388:11;20381:87;20498:66;20493:2;20488:3;20484:12;20477:88;20338:3;20594:6;20588:13;20610:75;20678:6;20673:2;20668:3;20664:12;20657:4;20649:6;20645:17;20610:75;:::i;:::-;20713:6;20708:3;20704:16;20694:26;;20739:66;20834:2;20829;20825;20821:11;20814:23;20866:66;20861:2;20857;20853:11;20846:87;20964:6;20958:13;20980:76;21047:8;21042:2;21038;21034:11;21027:4;21019:6;21015:17;20980:76;:::i;:::-;21116:2;21075:17;;21108:11;;;21101:23;21153:66;21148:2;21140:11;;21133:87;21245:13;;21267:76;21245:13;21329:2;21321:11;;21314:4;21302:17;;21267:76;:::i;:::-;21359:146;21389:115;21415:88;21445:57;21498:2;21487:8;21483:2;21479:17;21475:26;18709:4;18697:17;;18739:1;18730:11;;18632:115;21445:57;18829:66;18817:79;;18921:1;18912:11;;18752:177;21415:88;21407:6;21389:115;:::i;:::-;19011:3;18999:16;;19040:1;19031:11;;18934:114;21359:146;21352:153;19053:2458;-1:-1:-1;;;;;;;;19053:2458:18:o;21516:341::-;21569:3;21607:5;21601:12;21634:6;21629:3;21622:19;21650:76;21719:6;21712:4;21707:3;21703:14;21696:4;21689:5;21685:16;21650:76;:::i;:::-;21771:2;21759:15;21776:66;21755:88;21746:98;;;;21846:4;21742:109;;21516:341;-1:-1:-1;;21516:341:18:o;21862:373::-;22067:6;22056:9;22049:25;22110:6;22105:2;22094:9;22090:18;22083:34;22153:2;22148;22137:9;22133:18;22126:30;22030:4;22173:56;22225:2;22214:9;22210:18;22202:6;22173:56;:::i;:::-;22165:64;21862:373;-1:-1:-1;;;;;21862:373:18:o;25096:439::-;25149:3;25187:5;25181:12;25214:6;25209:3;25202:19;25240:4;25269;25264:3;25260:14;25253:21;;25308:4;25301:5;25297:16;25331:1;25341:169;25355:6;25352:1;25349:13;25341:169;;;25416:13;;25404:26;;25450:12;;;;25485:15;;;;25377:1;25370:9;25341:169;;;-1:-1:-1;25526:3:18;;25096:439;-1:-1:-1;;;;;25096:439:18:o;25540:488::-;25593:3;25631:5;25625:12;25658:6;25653:3;25646:19;25684:4;25713;25708:3;25704:14;25697:21;;25752:4;25745:5;25741:16;25775:1;25785:218;25799:6;25796:1;25793:13;25785:218;;;25864:13;;25879:42;25860:62;25848:75;;25943:12;;;;25978:15;;;;25821:1;25814:9;25785:218;;26033:1183;26555:4;26584:3;26614:6;26603:9;26596:25;26657:6;26652:2;26641:9;26637:18;26630:34;26700:2;26695;26684:9;26680:18;26673:30;26726:56;26778:2;26767:9;26763:18;26755:6;26726:56;:::i;:::-;26712:70;;26830:9;26822:6;26818:22;26813:2;26802:9;26798:18;26791:50;26864:44;26901:6;26893;26864:44;:::i;:::-;26850:58;;26957:9;26949:6;26945:22;26939:3;26928:9;26924:19;26917:51;26985:44;27022:6;27014;26985:44;:::i;:::-;27060:3;27045:19;;27038:35;;;;-1:-1:-1;;27122:42:18;27110:55;;;;27104:3;27089:19;;27082:84;27197:3;27182:19;;;27175:35;26977:52;26033:1183;-1:-1:-1;;;;;26033:1183:18:o;27221:184::-;27273:77;27270:1;27263:88;27370:4;27367:1;27360:15;27394:4;27391:1;27384:15;28188:604;28281:4;28287:6;28347:11;28334:25;28437:66;28426:8;28410:14;28406:29;28402:102;28382:18;28378:127;28368:155;;28519:1;28516;28509:12;28368:155;28546:33;;28598:20;;;-1:-1:-1;28641:18:18;28630:30;;28627:50;;;28673:1;28670;28663:12;28627:50;28706:4;28694:17;;-1:-1:-1;28757:1:18;28753:14;;;28737;28733:35;28723:46;;28720:66;;;28782:1;28779;28772:12;29899:202;30007:9;30044:51;30080:14;30073:5;30044:51;:::i;30106:472::-;30206:6;30201:3;30194:19;30176:3;30232:4;30261;30256:3;30252:14;30245:21;;30289:5;30312:1;30322:231;30336:6;30333:1;30330:13;30322:231;;;30429:42;30401:26;30420:6;30401:26;:::i;:::-;30397:75;30385:88;;30493:12;;;;30528:15;;;;30358:1;30351:9;30322:231;;30583:358;30683:6;30678:3;30671:19;30653:3;30713:66;30705:6;30702:78;30699:98;;;30793:1;30790;30783:12;30699:98;30829:6;30826:1;30822:14;30881:8;30874:5;30867:4;30862:3;30858:14;30845:45;30910:18;;;;30930:4;30906:29;;30583:358;-1:-1:-1;;;30583:358:18:o;30946:784::-;31307:6;31296:9;31289:25;31350:6;31345:2;31334:9;31330:18;31323:34;31405:42;31397:6;31393:55;31388:2;31377:9;31373:18;31366:83;31485:3;31480:2;31469:9;31465:18;31458:31;31270:4;31512:74;31581:3;31570:9;31566:19;31558:6;31550;31512:74;:::i;:::-;31635:9;31627:6;31623:22;31617:3;31606:9;31602:19;31595:51;31663:61;31717:6;31709;31701;31663:61;:::i;:::-;31655:69;30946:784;-1:-1:-1;;;;;;;;;;30946:784:18:o;31735:515::-;31976:2;31965:9;31958:21;31939:4;32002:62;32060:2;32049:9;32045:18;32037:6;32029;32002:62;:::i;:::-;32112:9;32104:6;32100:22;32095:2;32084:9;32080:18;32073:50;32140;32183:6;32175;32167;32140:50;:::i;:::-;32132:58;;;32238:4;32230:6;32226:17;32221:2;32210:9;32206:18;32199:45;31735:515;;;;;;;;:::o;33874:779::-;34201:3;34190:9;34183:22;34164:4;34228:63;34286:3;34275:9;34271:19;34263:6;34255;34228:63;:::i;:::-;34339:9;34331:6;34327:22;34322:2;34311:9;34307:18;34300:50;34373;34416:6;34408;34400;34373:50;:::i;:::-;34359:64;;34471:9;34463:6;34459:22;34454:2;34443:9;34439:18;34432:50;34499;34542:6;34534;34526;34499:50;:::i;:::-;34597:4;34585:17;;;;34580:2;34565:18;;34558:45;-1:-1:-1;;34634:3:18;34619:19;34612:35;34491:58;33874:779;-1:-1:-1;;;;;;33874:779:18:o;35061:195::-;35100:3;35131:66;35124:5;35121:77;35118:103;;35201:18;;:::i;:::-;-1:-1:-1;35248:1:18;35237:13;;35061:195::o;35261:184::-;35313:77;35310:1;35303:88;35410:4;35407:1;35400:15;35434:4;35431:1;35424:15;35450:120;35490:1;35516;35506:35;;35521:18;;:::i;:::-;-1:-1:-1;35555:9:18;;35450:120::o;35575:112::-;35607:1;35633;35623:35;;35638:18;;:::i;:::-;-1:-1:-1;35672:9:18;;35575:112::o;35692:196::-;35731:3;35759:5;35749:39;;35768:18;;:::i;:::-;-1:-1:-1;35815:66:18;35804:78;;35692:196::o;36242:874::-;36639:6;36628:9;36621:25;36682:6;36677:2;36666:9;36662:18;36655:34;36725:6;36720:2;36709:9;36705:18;36698:34;36768:3;36763:2;36752:9;36748:18;36741:31;36602:4;36795:57;36847:3;36836:9;36832:19;36824:6;36795:57;:::i;:::-;36901:9;36893:6;36889:22;36883:3;36872:9;36868:19;36861:51;36929:44;36966:6;36958;36929:44;:::i;:::-;36921:52;;;37010:6;37004:3;36993:9;36989:19;36982:35;37066:42;37058:6;37054:55;37048:3;37037:9;37033:19;37026:84;36242:874;;;;;;;;;;:::o;37954:277::-;38021:6;38074:2;38062:9;38053:7;38049:23;38045:32;38042:52;;;38090:1;38087;38080:12;38042:52;38122:9;38116:16;38175:5;38168:13;38161:21;38154:5;38151:32;38141:60;;38197:1;38194;38187:12;40200:287;40329:3;40367:6;40361:13;40383:66;40442:6;40437:3;40430:4;40422:6;40418:17;40383:66;:::i;:::-;40465:16;;;;;40200:287;-1:-1:-1;;40200:287:18:o;40492:231::-;40641:2;40630:9;40623:21;40604:4;40661:56;40713:2;40702:9;40698:18;40690:6;40661:56;:::i
Swarm Source
ipfs://d2649e93213e34fac0adc7d7fcce2926fd55ca614d3d9643ed69740b1fa366d6
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.