Polygon Sponsored slots available. Book your slot here!
More Info
Private Name Tags
ContractCreator
TokenTracker
Latest 25 from a total of 30,853 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Set Approval For... | 78959565 | 1 hr ago | IN | 0 POL | 0.01540285 | ||||
| Set Approval For... | 78950502 | 6 hrs ago | IN | 0 POL | 0.03102594 | ||||
| Set Approval For... | 78890106 | 40 hrs ago | IN | 0 POL | 0.00522538 | ||||
| Safe Transfer Fr... | 78889851 | 40 hrs ago | IN | 0 POL | 0.00499409 | ||||
| Set Approval For... | 78814189 | 3 days ago | IN | 0 POL | 0.00517717 | ||||
| Set Approval For... | 78810274 | 3 days ago | IN | 0 POL | 0.00235178 | ||||
| Safe Transfer Fr... | 78660157 | 7 days ago | IN | 0 POL | 0.00434221 | ||||
| Set Approval For... | 78635902 | 7 days ago | IN | 0 POL | 0.00216001 | ||||
| Set Approval For... | 78629597 | 7 days ago | IN | 0 POL | 0.00511268 | ||||
| Set Approval For... | 78605542 | 8 days ago | IN | 0 POL | 0.00487283 | ||||
| Set Approval For... | 78583786 | 8 days ago | IN | 0 POL | 0.01204693 | ||||
| Set Approval For... | 78503837 | 10 days ago | IN | 0 POL | 0.00143263 | ||||
| Set Approval For... | 78485857 | 11 days ago | IN | 0 POL | 0.00393371 | ||||
| Set Approval For... | 78365397 | 13 days ago | IN | 0 POL | 0.01633056 | ||||
| Set Approval For... | 78339004 | 14 days ago | IN | 0 POL | 0.00215564 | ||||
| Set Approval For... | 78314128 | 15 days ago | IN | 0 POL | 0.00169783 | ||||
| Set Approval For... | 78309742 | 15 days ago | IN | 0 POL | 0.00436563 | ||||
| Set Approval For... | 78303460 | 15 days ago | IN | 0 POL | 0.00074325 | ||||
| Set Approval For... | 78302947 | 15 days ago | IN | 0 POL | 0.00074326 | ||||
| Set Approval For... | 78302825 | 15 days ago | IN | 0 POL | 0.00072502 | ||||
| Set Approval For... | 78284048 | 15 days ago | IN | 0 POL | 0.00086567 | ||||
| Set Approval For... | 78195756 | 17 days ago | IN | 0 POL | 0.00182384 | ||||
| Set Approval For... | 78192955 | 17 days ago | IN | 0 POL | 0.00138387 | ||||
| Safe Transfer Fr... | 78064196 | 20 days ago | IN | 0 POL | 0.00364608 | ||||
| Set Approval For... | 78047969 | 21 days ago | IN | 0 POL | 0.00166156 |
Latest 1 internal transaction
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 21750460 | 1449 days ago | Contract Creation | 0 POL |
Cross-Chain Transactions
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x27A11C15...BaD9C0cf6 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
SkyweaverAssets
Compiler Version
v0.7.4+commit.3f05b770
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;
import "../utils/Ownable.sol";
import "@0xsequence/erc-1155/contracts/tokens/ERC1155PackedBalance/ERC1155MintBurnPackedBalance.sol";
import "@0xsequence/erc-1155/contracts/tokens/ERC1155/ERC1155Metadata.sol";
import "@0xsequence/erc-1155/contracts/tokens/ERC2981/ERC2981Global.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";
/**
* ERC-1155 token contract for skyweaver assets.
* This contract manages the various SW asset factories
* and ensures that each factory has constraint access in
* terms of the id space they are allowed to mint.
* @dev Mint permissions use range because factory contracts
* could be minting large numbers of NFTs or be built
* with granular, but efficient permission checks.
*/
contract SkyweaverAssets is ERC1155MintBurnPackedBalance, ERC1155Metadata, ERC2981Global, Ownable {
using SafeMath for uint256;
/***********************************|
| Variables |
|__________________________________*/
// Factory mapping variables
mapping(address => bool) internal isFactoryActive; // Whether an address can print tokens or not
mapping(address => AssetRange[]) internal mintAccessRanges; // Contains the ID ranges factories are allowed to mint
AssetRange[] internal lockedRanges; // Ranges of IDs that can't be granted permission to mint
// Issuance mapping variables
mapping (uint256 => uint256) internal currentIssuance; // Current Issuance of token for tokens that have max issuance ONLY
mapping (uint256 => uint256) internal maxIssuance; // Issuance is counted and capped to associated maxIssuance if it's non-zero
// Struct for mint ID ranges permissions
struct AssetRange {
uint64 minID; // Minimum value the ID need to be to fall in the range
uint64 maxID; // Maximum value the ID need to be to fall in the range
uint64 startTime; // Timestamp when the range becomes valid
uint64 endTime; // Timestamp after which the range is no longer valid
}
/***********************************|
| Events |
|__________________________________*/
event FactoryActivation(address indexed factory);
event FactoryShutdown(address indexed factory);
event MaxIssuancesChanged(uint256[] ids, uint256[] newMaxIssuances);
event MintPermissionAdded(address indexed factory, AssetRange new_range);
event MintPermissionRemoved(address indexed factory, AssetRange deleted_range);
event RangeLocked(AssetRange locked_range);
/***********************************|
| Constuctor |
|__________________________________*/
constructor (address _firstOwner) ERC1155Metadata("Skyweaver", "") Ownable(_firstOwner) public {}
/***********************************|
| Factory Management Methods |
|__________________________________*/
/**
* @notice Will ALLOW factory to print some assets specified in `canPrint` mapping
* @param _factory Address of the factory to activate
*/
function activateFactory(address _factory) external onlyOwner() {
isFactoryActive[_factory] = true;
emit FactoryActivation(_factory);
}
/**
* @notice Will DISALLOW factory to print any asset
* @param _factory Address of the factory to shutdown
*/
function shutdownFactory(address _factory) external onlyOwner() {
isFactoryActive[_factory] = false;
emit FactoryShutdown(_factory);
}
/**
* @notice Will allow a factory to mint some token ids
* @param _factory Address of the factory to update permission
* @param _minRange Minimum ID (inclusive) in id range that factory will be able to mint
* @param _maxRange Maximum ID (inclusive) in id range that factory will be able to mint
* @param _startTime Timestamp when the range becomes valid
* @param _endTime Timestamp after which the range is no longer valid
*/
function addMintPermission(address _factory, uint64 _minRange, uint64 _maxRange, uint64 _startTime, uint64 _endTime) external onlyOwner() {
require(_maxRange > 0, "SkyweaverAssets#addMintPermission: NULL_RANGE");
require(_minRange <= _maxRange, "SkyweaverAssets#addMintPermission: INVALID_RANGE");
require(_startTime < _endTime, "SkyweaverAssets#addMintPermission: START_TIME_IS_NOT_LESSER_THEN_END_TIME");
// Check if new range has an overlap with locked ranges.
// lockedRanges is expected to be a small array
for (uint256 i = 0; i < lockedRanges.length; i++) {
AssetRange memory locked_range = lockedRanges[i];
require(
(_maxRange < locked_range.minID) || (locked_range.maxID < _minRange),
"SkyweaverAssets#addMintPermission: OVERLAP_WITH_LOCKED_RANGE"
);
}
// Create and store range struct for _factory
AssetRange memory range = AssetRange(_minRange, _maxRange, _startTime, _endTime);
mintAccessRanges[_factory].push(range);
emit MintPermissionAdded(_factory, range);
}
/**
* @notice Will remove the permission a factory has to mint some token ids
* @param _factory Address of the factory to update permission
* @param _rangeIndex Array's index where the range to delete is located for _factory
*/
function removeMintPermission(address _factory, uint256 _rangeIndex) external onlyOwner() {
// Will take the last range and put it where the "hole" will be after
// the AssetRange struct at _rangeIndex is deleted
uint256 last_index = mintAccessRanges[_factory].length - 1; // won't underflow because of require() statement above
AssetRange memory range_to_delete = mintAccessRanges[_factory][_rangeIndex]; // Stored for log
if (_rangeIndex != last_index) {
AssetRange memory last_range = mintAccessRanges[_factory][last_index]; // Retrieve the range that will be moved
mintAccessRanges[_factory][_rangeIndex] = last_range; // Overwrite the "to-be-deleted" range
}
// Delete last element of the array
mintAccessRanges[_factory].pop();
emit MintPermissionRemoved(_factory, range_to_delete);
}
/**
* @notice Will forever prevent new mint permissions for provided ids
* @dev THIS ACTION IS IRREVERSIBLE, USE WITH CAUTION
* @dev In order to forever restrict minting of certain ids to a set of factories,
* one first needs to call `addMintPermission()` for the corresponding factory
* and the corresponding ids, then call this method to prevent further mint
* permissions to be granted. One can also remove mint permissions after ids
* mint permissions where locked down.
* @param _range AssetRange struct for range of asset that can't be granted
* new mint permission to
*/
function lockRangeMintPermissions(AssetRange memory _range) public onlyOwner() {
lockedRanges.push(_range);
emit RangeLocked(_range);
}
/***********************************|
| Supplies Management Methods |
|__________________________________*/
/**
* @notice Set max issuance for some token IDs that can't ever be increased
* @dev Can only decrease the max issuance if already set, but can't set it *back* to 0.
* @param _ids Array of token IDs to set the max issuance
* @param _newMaxIssuances Array of max issuances for each corresponding ID
*/
function setMaxIssuances(uint256[] calldata _ids, uint256[] calldata _newMaxIssuances) external onlyOwner() {
require(_ids.length == _newMaxIssuances.length, "SkyweaverAssets#setMaxIssuances: INVALID_ARRAYS_LENGTH");
// Can only *decrease* a max issuance
// Can't set max issuance back to 0
for (uint256 i = 0; i < _ids.length; i++ ) {
if (maxIssuance[_ids[i]] > 0) {
require(
0 < _newMaxIssuances[i] && _newMaxIssuances[i] < maxIssuance[_ids[i]],
"SkyweaverAssets#setMaxIssuances: INVALID_NEW_MAX_ISSUANCE"
);
}
maxIssuance[_ids[i]] = _newMaxIssuances[i];
}
emit MaxIssuancesChanged(_ids, _newMaxIssuances);
}
/***********************************|
| Royalty Management Methods |
|__________________________________*/
/**
* @notice Will set the basis point and royalty recipient that is applied to all Skyweaver assets
* @param _receiver Fee recipient that will receive the royalty payments
* @param _royaltyBasisPoints Basis points with 3 decimals representing the fee %
* e.g. a fee of 2% would be 20 (i.e. 20 / 1000 == 0.02, or 2%)
*/
function setGlobalRoyaltyInfo(address _receiver, uint256 _royaltyBasisPoints) external onlyOwner() {
_setGlobalRoyaltyInfo(_receiver, _royaltyBasisPoints);
}
/***********************************|
| Receiver Method Handler |
|__________________________________*/
/**
* @notice Prevents receiving Ether or calls to unsuported methods
*/
fallback () external {
revert("UNSUPPORTED_METHOD");
}
/***********************************|
| Minting Function |
|__________________________________*/
/**
* @notice Mint tokens for each ids in _ids
* @dev This methods assumes ids are sorted by how the ranges are sorted in
* the corresponding mintAccessRanges[msg.sender] array. Call might throw
* if they are not.
* @param _to The address to mint tokens to.
* @param _ids Array of ids to mint
* @param _amounts Array of amount of tokens to mint per id
* @param _data Byte array of data to pass to recipient if it's a contract
*/
function batchMint(
address _to,
uint256[] memory _ids,
uint256[] memory _amounts,
bytes memory _data) public
{
// Validate assets to be minted
_validateMints(_ids, _amounts);
// If hasn't reverted yet, all IDs are allowed for factory
_batchMint(_to, _ids, _amounts, _data);
}
/**
* @notice Mint _amount of tokens of a given id, if allowed.
* @param _to The address to mint tokens to
* @param _id Token id to mint
* @param _amount The amount to be minted
* @param _data Data to pass if receiver is contract
*/
function mint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) external
{
// Put into array for validation
uint256[] memory ids = new uint256[](1);
uint256[] memory amounts = new uint256[](1);
ids[0] = _id;
amounts[0] = _amount;
// Validate and mint
_validateMints(ids, amounts);
_mint(_to, _id, _amount, _data);
}
/**
* @notice Will validate the ids and amounts to mint
* @dev This methods assumes ids are sorted by how the ranges are sorted in
* the corresponding mintAccessRanges[msg.sender] array. Call will revert
* if they are not.
* @dev When the maxIssuance of an asset is set to a non-zero value, the
* supply manager contract will start keeping track of how many of that
* token are minted, until the maxIssuance hit.
* @param _ids Array of ids to mint
* @param _amounts Array of amount of tokens to mint per id
*/
function _validateMints(uint256[] memory _ids, uint256[] memory _amounts) internal {
require(isFactoryActive[msg.sender], "SkyweaverAssets#_validateMints: FACTORY_NOT_ACTIVE");
// Number of mint ranges
uint256 n_ranges = mintAccessRanges[msg.sender].length;
// Load factory's default range
AssetRange memory range = mintAccessRanges[msg.sender][0];
uint256 range_index = 0;
// Will make sure that factory is allowed to print all ids
// and that no max issuance is exceeded
for (uint256 i = 0; i < _ids.length; i++) {
uint256 id = _ids[i];
uint256 amount = _amounts[i];
uint256 max_issuance = maxIssuance[id];
// If ID is out of current range, move to next range, else skip.
// This function only moves forwards in the AssetRange array,
// hence if _ids are not sorted correctly, the call will fail.
while (block.timestamp < range.startTime || block.timestamp > range.endTime || id < range.minID || range.maxID < id) {
range_index += 1;
// Load next range. If none left, ID is assumed to be out of all ranges
require(range_index < n_ranges, "SkyweaverAssets#_validateMints: ID_OUT_OF_RANGE");
range = mintAccessRanges[msg.sender][range_index];
}
// If max supply is specified for id
if (max_issuance > 0) {
uint256 new_current_issuance = currentIssuance[id].add(amount);
require(new_current_issuance <= max_issuance, "SkyweaverAssets#_validateMints: MAX_ISSUANCE_EXCEEDED");
currentIssuance[id] = new_current_issuance;
}
}
}
/***********************************|
| Getter Functions |
|__________________________________*/
/**
* @notice Get the max issuance of multiple asset IDs
* @dev The max issuance of a token does not reflect the maximum supply, only
* how many tokens can be minted once the maxIssuance for a token is set.
* @param _ids Array containing the assets IDs
* @return The current max issuance of each asset ID in _ids
*/
function getMaxIssuances(uint256[] calldata _ids) external view returns (uint256[] memory) {
uint256 nIds = _ids.length;
uint256[] memory max_issuances = new uint256[](nIds);
// Iterate over each owner and token ID
for (uint256 i = 0; i < nIds; i++) {
max_issuances[i] = maxIssuance[_ids[i]];
}
return max_issuances;
}
/**
* @notice Get the current issuanc of multiple asset ID
* @dev The current issuance of a token does not reflect the current supply, only
* how many tokens since a max issuance was set for a given token id.
* @param _ids Array containing the assets IDs
* @return The current issuance of each asset ID in _ids
*/
function getCurrentIssuances(uint256[] calldata _ids) external view returns (uint256[] memory) {
uint256 nIds = _ids.length;
uint256[] memory current_issuances = new uint256[](nIds);
// Iterate over each owner and token ID
for (uint256 i = 0; i < nIds; i++) {
current_issuances[i] = currentIssuance[_ids[i]];
}
return current_issuances;
}
/**
* @return Returns whether a factory is active or not
*/
function getFactoryStatus(address _factory) external view returns (bool) {
return isFactoryActive[_factory];
}
/**
* @return Returns whether the sale has ended or not
*/
function getFactoryAccessRanges(address _factory) external view returns (AssetRange[] memory) {
return mintAccessRanges[_factory];
}
/**
* @return Returns all the ranges that are locked
*/
function getLockedRanges() external view returns (AssetRange[] memory) {
return lockedRanges;
}
/***********************************|
| Burning Functions |
|__________________________________*/
/**
* @notice Burn _amount of tokens of a given id from msg.sender
* @dev This will not change the current issuance tracked in _supplyManagerAddr.
* @param _id Asset id to burn
* @param _amount The amount to be burn
*/
function burn(
uint256 _id,
uint256 _amount)
external
{
_burn(msg.sender, _id, _amount);
}
/**
* @notice Burn _amounts of tokens of given ids from msg.sender
* @dev This will not change the current issuance tracked in _supplyManagerAddr.
* @param _ids Asset id to burn
* @param _amounts The amount to be burn
*/
function batchBurn(
uint256[] calldata _ids,
uint256[] calldata _amounts)
external
{
_batchBurn(msg.sender, _ids, _amounts);
}
/***********************************|
| URI Functions |
|__________________________________*/
/**
* @dev Will update the base URL of token's URI
* @param _newBaseMetadataURI New base URL of token's URI
*/
function setBaseMetadataURI(string calldata _newBaseMetadataURI) external onlyOwner() {
_setBaseMetadataURI(_newBaseMetadataURI);
}
/**
* @dev Will emit default URI log event for corresponding token _id
* @param _tokenIDs Array of IDs of tokens to log default URI
*/
function logURIs(uint256[] calldata _tokenIDs) external onlyOwner() {
_logURIs(_tokenIDs);
}
/***********************************|
| ERC165 Functions |
|__________________________________*/
/**
* @notice Query if a contract implements an interface
* @param _interfaceID The interface identifier, as specified in ERC-165
* @return `true` if the contract implements `_interfaceID`
*/
function supportsInterface(bytes4 _interfaceID) public override(ERC1155PackedBalance, ERC1155Metadata, ERC2981Global) virtual pure returns (bool) {
return super.supportsInterface(_interfaceID);
}
}pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;
interface ISkyweaverAssets {
/***********************************|
| Events |
|__________________________________*/
event FactoryActivation(address indexed factory);
event FactoryShutdown(address indexed factory);
event MintPermissionAdded(address indexed factory, AssetRange new_range);
event MintPermissionRemoved(address indexed factory, AssetRange deleted_range);
// Struct for mint ID ranges permissions
struct AssetRange {
uint256 minID;
uint256 maxID;
}
/***********************************|
| Supplies Management Methods |
|__________________________________*/
/**
* @notice Set max issuance for some token IDs that can't ever be increased
* @dev Can only decrease the max issuance if already set, but can't set it *back* to 0.
* @param _ids Array of token IDs to set the max issuance
* @param _newMaxIssuances Array of max issuances for each corresponding ID
*/
function setMaxIssuances(uint256[] calldata _ids, uint256[] calldata _newMaxIssuances) external;
/***********************************|
| Factory Management Methods |
|__________________________________*/
/**
* @notice Will allow a factory to mint some token ids
* @param _factory Address of the factory to update permission
* @param _minRange Minimum ID (inclusive) in id range that factory will be able to mint
* @param _maxRange Maximum ID (inclusive) in id range that factory will be able to mint
* @param _startTime Timestamp when the range becomes valid
* @param _endTime Timestamp after which the range is no longer valid
*/
function addMintPermission(address _factory, uint64 _minRange, uint64 _maxRange, uint64 _startTime, uint64 _endTime) external;
/**
* @notice Will remove the permission a factory has to mint some token ids
* @param _factory Address of the factory to update permission
* @param _rangeIndex Array's index where the range to delete is located for _factory
*/
function removeMintPermission(address _factory, uint256 _rangeIndex) external;
/**
* @notice Will ALLOW factory to print some assets specified in `canPrint` mapping
* @param _factory Address of the factory to activate
*/
function activateFactory(address _factory) external;
/**
* @notice Will DISALLOW factory to print any asset
* @param _factory Address of the factory to shutdown
*/
function shutdownFactory(address _factory) external;
/**
* @notice Will forever prevent new mint permissions for provided ids
* @param _range AssetRange struct for range of asset that can't be granted
* new mint permission to
*/
function lockRangeMintPermissions(AssetRange calldata _range) external;
/***********************************|
| Getter Functions |
|__________________________________*/
/**
* @return Returns whether a factory is active or not
*/
function getFactoryStatus(address _factory) external view returns (bool);
/**
* @return Returns whether the sale has ended or not
*/
function getFactoryAccessRanges(address _factory) external view returns ( AssetRange[] memory);
/**
* @notice Get the max issuance of multiple asset IDs
* @dev The max issuance of a token does not reflect the maximum supply, only
* how many tokens can be minted once the maxIssuance for a token is set.
* @param _ids Array containing the assets IDs
* @return The current max issuance of each asset ID in _ids
*/
function getMaxIssuances(uint256[] calldata _ids) external view returns (uint256[] memory);
/**
* @notice Get the current issuanc of multiple asset ID
* @dev The current issuance of a token does not reflect the current supply, only
* how many tokens since a max issuance was set for a given token id.
* @param _ids Array containing the assets IDs
* @return The current issuance of each asset ID in _ids
*/
function getCurrentIssuances(uint256[] calldata _ids)external view returns (uint256[] memory);
/***************************************|
| Minting Functions |
|______________________________________*/
/**
* @dev Mint _amount of tokens of a given id if not frozen and if max supply not exceeded
* @param _to The address to mint tokens to.
* @param _id Token id to mint
* @param _amount The amount to be minted
* @param _data Byte array of data to pass to recipient if it's a contract
*/
function mint(address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;
/**
* @dev Mint tokens for each ids in _ids
* @param _to The address to mint tokens to.
* @param _ids Array of ids to mint
* @param _amounts Array of amount of tokens to mint per id
* @param _data Byte array of data to pass to recipient if it's a contract
*/
function batchMint(address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external;
/***************************************|
| Burning Functions |
|______________________________________*/
/**
* @notice Burn sender's_amount of tokens of a given token id
* @param _id Token id to burn
* @param _amount The amount to be burned
*/
function burn(uint256 _id, uint256 _amount) external;
/**
* @notice Burn sender's tokens of given token id for each (_ids[i], _amounts[i]) pair
* @param _ids Array of token ids to burn
* @param _amounts Array of the amount to be burned
*/
function batchBurn(uint256[] calldata _ids, uint256[] calldata _amounts) external;
}pragma solidity 0.7.4;
import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "../interfaces/IRewardFactory.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155TokenReceiver.sol";
/**
* @notice Keep track of players participation in Conquest and used to issue rewards.
* @dev This contract must be at least a TIER 1 owner of the silverCardFactory and
* goldCardFactory.
*/
contract Conquest is IERC1155TokenReceiver, TieredOwnable {
using SafeMath for uint256;
/***********************************|
| Variables |
|__________________________________*/
// Parameters
uint256 constant internal TIME_BETWEEN_CONQUESTS = 1 seconds; // Seconds that must elapse between two conquest
uint256 constant internal ENTRIES_DECIMALS = 2; // Amount of decimals conquest entries have
uint256 constant internal CARDS_DECIMALS = 2; // Number of decimals cards have
// Contracts
IRewardFactory immutable public silverCardFactory; // Factory that mints Silver cards
IRewardFactory immutable public goldCardFactory; // Factory that mints Gold cards
ISkyweaverAssets immutable public skyweaverAssets; // ERC-1155 Skyweaver assets contract
uint256 immutable public conquestEntryID; // Conquest entry token id
// Mappings
mapping(address => bool) public isActiveConquest; // Whether a given player is currently in a conquest
mapping(address => uint256) public conquestsEntered; // Number of conquest a given player has entered so far
mapping(address => uint256) public nextConquestTime; // Time when the next conquest can be started for players
// Event
event ConquestEntered(address user, uint256 nConquests);
/***********************************|
| Constructor |
|__________________________________*/
/**
* @notice Link factories and skyweaver assets, store initial parameters
* @param _firstOwner Address of the first owner
* @param _skyweaverAssetsAddress The address of the ERC-1155 Assets Token contract
* @param _silverCardFactoryAddress The address of the Silver Card Factory
* @param _goldCardFactoryAddress The address of the Gold Card Factory
* @param _conquestEntryTokenId Conquest entry token id
*/
constructor(
address _firstOwner,
address _skyweaverAssetsAddress,
address _silverCardFactoryAddress,
address _goldCardFactoryAddress,
uint256 _conquestEntryTokenId
) TieredOwnable(_firstOwner) public
{
require(
_skyweaverAssetsAddress != address(0) &&
_silverCardFactoryAddress != address(0) &&
_goldCardFactoryAddress != address(0),
"Conquest#constructor: INVALID_INPUT"
);
// Store parameters
skyweaverAssets = ISkyweaverAssets(_skyweaverAssetsAddress);
silverCardFactory = IRewardFactory(_silverCardFactoryAddress);
goldCardFactory = IRewardFactory(_goldCardFactoryAddress);
conquestEntryID = _conquestEntryTokenId;
}
/***********************************|
| Receiver Method Handler |
|__________________________________*/
/**
* @notice Prevents receiving Ether or calls to unsupported methods
*/
fallback () external {
revert("Conquest#_: UNSUPPORTED_METHOD");
}
/**
* @notice Players entering conquest with conquest entry token
* @dev Payload is passed to and verified by onERC1155BatchReceived()
*/
function onERC1155Received(
address _operator,
address _from,
uint256 _id,
uint256 _amount,
bytes calldata _data
)
external override returns(bytes4)
{
// Convert payload to arrays to pass to onERC1155BatchReceived()
uint256[] memory ids = new uint256[](1);
uint256[] memory amounts = new uint256[](1);
ids[0] = _id;
amounts[0] = _amount;
// Will revert call if doesn't pass
onERC1155BatchReceived(_operator, _from, ids, amounts, _data);
// Return success
return IERC1155TokenReceiver.onERC1155Received.selector;
}
/**
* @notice Conquest entry point. Will mark user as having entered conquest if valid entry.
* @param _from Address who sent the token
* @param _ids An array containing ids of each Token being transferred
* @param _amounts An array containing amounts of each Token being transferred
*/
function onERC1155BatchReceived(
address, // _operator
address _from,
uint256[] memory _ids,
uint256[] memory _amounts,
bytes memory // _data
)
public override returns(bytes4)
{
require(msg.sender == address(skyweaverAssets), "Conquest#entry: INVALID_ENTRY_TOKEN_ADDRESS");
require(_ids.length == 1, "Conquest#entry: INVALID_IDS_ARRAY_LENGTH");
require(_amounts.length == 1, "Conquest#entry: INVALID_AMOUNTS_ARRAY_LENGTH");
require(_ids[0] == conquestEntryID, "Conquest#entry: INVALID_ENTRY_TOKEN_ID");
require(_amounts[0] == 10**ENTRIES_DECIMALS, "Conquest#entry: INVALID_ENTRY_TOKEN_AMOUNT");
require(!isActiveConquest[_from], "Conquest#entry: PLAYER_ALREADY_IN_CONQUEST");
require(nextConquestTime[_from] <= block.timestamp, "Conquest#entry: NEW_CONQUEST_TOO_EARLY");
// Mark player as playing
isActiveConquest[_from] = true;
conquestsEntered[_from] = conquestsEntered[_from].add(1);
nextConquestTime[_from] = block.timestamp.add(TIME_BETWEEN_CONQUESTS);
// Burn tickets
skyweaverAssets.burn(conquestEntryID, 10**ENTRIES_DECIMALS);
// Emit event
emit ConquestEntered(_from, conquestsEntered[_from]);
// Return success
return IERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
/***********************************|
| Minting Functions |
|__________________________________*/
/**
* @notice Will exit user from conquest and mint tokens to user
* @param _user The address that exits conquest and receive the rewards
* @param _silverIds Ids of silver cards to mint (duplicate ids if amount > 1)
* @param _goldIds Ids of gold cards to mint (duplicate ids if amount > 1)
*/
function exitConquest(address _user, uint256[] calldata _silverIds, uint256[] calldata _goldIds)
external onlyOwnerTier(1)
{
require(isActiveConquest[_user], "Conquest#exitConquest: USER_IS_NOT_IN_CONQUEST");
// Mark player as not playing anymore
isActiveConquest[_user] = false;
// 0 win - 1 loss ===> 0 rewards
if (_silverIds.length == 0 && _goldIds.length == 0) {
/* Do nothing if user didn't win any matches */
// 1 win - 1 loss ===> 1 Silver card
} else if (_silverIds.length == 1 && _goldIds.length == 0) {
silverCardFactory.batchMint(_user, _silverIds, array(1, 10**CARDS_DECIMALS), "");
// 2 wins - 1 loss ===> 2 silver cards
} else if (_silverIds.length == 2 && _goldIds.length == 0) {
silverCardFactory.batchMint(_user, _silverIds, array(2, 10**CARDS_DECIMALS), "");
// 3 wins - 0 loss ===> 1 Silver card and 1 Gold card
} else if (_silverIds.length == 1 && _goldIds.length == 1) {
silverCardFactory.batchMint(_user, _silverIds, array(1, 10**CARDS_DECIMALS), "");
goldCardFactory.batchMint(_user, _goldIds, array(1, 10**CARDS_DECIMALS), "");
// Revert for any other combination
} else {
revert("Conquest#exitConquest: INVALID_REWARDS");
}
}
/***********************************|
| Utility Functions |
|__________________________________*/
/**
* @notice Will create an array of uint _value of length _length
* @param _length Number of elements in array
* @param _value Value to put in array at each element
*/
function array(uint256 _length, uint256 _value) internal pure returns (uint256[] memory) {
uint256[] memory a = new uint256[](_length);
for (uint256 i = 0; i < _length; i++) {
a[i] = _value;
}
return a;
}
/**
* @notice Indicates whether a contract implements a given interface.
* @param interfaceID The ERC-165 interface ID that is queried for support.
* @return True if contract interface is supported.
*/
function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
return interfaceID == type(IERC165).interfaceId ||
interfaceID == type(IERC1155TokenReceiver).interfaceId;
}
}pragma solidity 0.7.4;
/**
* @notice The TieredOwnable can assign ownership tiers to addresses,
* allowing inheriting contracts to choose which tier can call which function.
*/
contract TieredOwnable {
uint256 constant internal HIGHEST_OWNER_TIER = 2**256-1; //Highest possible tier
mapping(address => uint256) internal ownerTier;
event OwnershipGranted(address indexed owner, uint256 indexed previousTier, uint256 indexed newTier);
/**
* @dev Sets the _firstOwner provided to highest owner tier
* @dev _firstOwner First address to be a owner of this contract
*/
constructor (address _firstOwner) {
require(_firstOwner != address(0), "TieredOwnable#constructor: INVALID_FIRST_OWNER");
ownerTier[_firstOwner] = HIGHEST_OWNER_TIER;
emit OwnershipGranted(_firstOwner, 0, HIGHEST_OWNER_TIER);
}
/**
* @dev Throws if called by an account that's in lower ownership tier than expected
*/
modifier onlyOwnerTier(uint256 _minTier) {
require(ownerTier[msg.sender] >= _minTier, "TieredOwnable#onlyOwnerTier: OWNER_TIER_IS_TOO_LOW");
_;
}
/**
* @notice Highest owners can change ownership tier of other owners
* @dev Prevents changing sender's tier to ensure there is always at least one HIGHEST_OWNER_TIER owner.
* @param _address Address of the owner
* @param _tier Ownership tier assigned to owner
*/
function assignOwnership(address _address, uint256 _tier) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
require(_address != address(0), "TieredOwnable#assignOwnership: INVALID_ADDRESS");
require(msg.sender != _address, "TieredOwnable#assignOwnership: UPDATING_SELF_TIER");
emit OwnershipGranted(_address, ownerTier[_address], _tier);
ownerTier[_address] = _tier;
}
/**
* @notice Returns the ownership tier of provided owner
* @param _owner Owner's address to query ownership tier
*/
function getOwnerTier(address _owner) external view returns (uint256) {
return ownerTier[_owner];
}
}pragma solidity 0.7.4;
/**
* @notice This is a contract allowing contract owner to mint up to N
* assets per period of 6 hours.
* @dev This contract should only be able to mint some assets types
*/
interface IRewardFactory {
// Event
event PeriodMintLimitChanged(uint256 oldMintingLimit, uint256 newMintingLimit);
/***********************************|
| Management Methods |
|__________________________________*/
/**
* @notice Will update the daily mint limit
* @dev This change will take effect immediatly once executed
* @param _newPeriodMintLimit Amount of assets that can be minted within a period
*/
function updatePeriodMintLimit(uint256 _newPeriodMintLimit) external;
/***********************************|
| Minting Functions |
|__________________________________*/
/**
* @notice Will mint tokens to user
* @dev Can only mint up to the periodMintLimit in a given 6hour period
* @param _to The address that receives the assets
* @param _ids Array of Tokens ID that are minted
* @param _amounts Amount of Tokens id minted for each corresponding Token id in _tokenIds
* @param _data Byte array passed to recipient if recipient is a contract
*/
function batchMint(address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external;
/***********************************|
| Utility Functions |
|__________________________________*/
/**
* @notice Returns how many cards can currently be minted by this factory
*/
function getAvailableSupply() external view returns (uint256);
/**
* @notice Calculate the current period
*/
function livePeriod() external view returns (uint256);
/**
* @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types.
* @param interfaceID The ERC-165 interface ID that is queried for support.s
* @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface.
* This function MUST NOT consume more than 5,000 gas.
* @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported.
*/
function supportsInterface(bytes4 interfaceID) external pure returns (bool);
}pragma solidity 0.7.4;
/**
* @title SafeMath
* @dev Unsigned math operations with safety checks that revert on error
*/
library SafeMath {
/**
* @dev Multiplies two unsigned integers, reverts on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath#mul: OVERFLOW");
return c;
}
/**
* @dev Integer division of two unsigned integers truncating the quotient, reverts on division by zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// Solidity only automatically asserts when dividing by 0
require(b > 0, "SafeMath#div: DIVISION_BY_ZERO");
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Subtracts two unsigned integers, reverts on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a, "SafeMath#sub: UNDERFLOW");
uint256 c = a - b;
return c;
}
/**
* @dev Adds two unsigned integers, reverts on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath#add: OVERFLOW");
return c;
}
/**
* @dev Divides two unsigned integers and returns the remainder (unsigned integer modulo),
* reverts when dividing by zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
require(b != 0, "SafeMath#mod: DIVISION_BY_ZERO");
return a % b;
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
/**
* @title ERC165
* @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md
*/
interface IERC165 {
/**
* @notice Query if a contract implements an interface
* @dev Interface identification is specified in ERC-165. This function
* uses less than 30,000 gas
* @param _interfaceId The interface identifier, as specified in ERC-165
*/
function supportsInterface(bytes4 _interfaceId)
external
view
returns (bool);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import './IERC165.sol';
interface IERC1155 is IERC165 {
/****************************************|
| Events |
|_______________________________________*/
/**
* @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
* Operator MUST be msg.sender
* When minting/creating tokens, the `_from` field MUST be set to `0x0`
* When burning/destroying tokens, the `_to` field MUST be set to `0x0`
* The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
* To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
*/
event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount);
/**
* @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
* Operator MUST be msg.sender
* When minting/creating tokens, the `_from` field MUST be set to `0x0`
* When burning/destroying tokens, the `_to` field MUST be set to `0x0`
* The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
* To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
*/
event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts);
/**
* @dev MUST emit when an approval is updated
*/
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
/****************************************|
| Functions |
|_______________________________________*/
/**
* @notice Transfers amount of an _id from the _from address to the _to address specified
* @dev MUST emit TransferSingle event on success
* Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
* MUST throw if `_to` is the zero address
* MUST throw if balance of sender for token `_id` is lower than the `_amount` sent
* MUST throw on any other error
* When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155Received` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @dev MUST emit TransferBatch event on success
* Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
* MUST throw if `_to` is the zero address
* MUST throw if length of `_ids` is not the same as length of `_amounts`
* MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent
* MUST throw on any other error
* When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external;
/**
* @notice Get the balance of an account's Tokens
* @param _owner The address of the token holder
* @param _id ID of the Token
* @return The _owner's balance of the Token type requested
*/
function balanceOf(address _owner, uint256 _id) external view returns (uint256);
/**
* @notice Get the balance of multiple account/token pairs
* @param _owners The addresses of the token holders
* @param _ids ID of the Tokens
* @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
*/
function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory);
/**
* @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
* @dev MUST emit the ApprovalForAll event on success
* @param _operator Address to add to the set of authorized operators
* @param _approved True if the operator is approved, false to revoke approval
*/
function setApprovalForAll(address _operator, bool _approved) external;
/**
* @notice Queries the approval status of an operator for a given owner
* @param _owner The owner of the Tokens
* @param _operator Address of authorized operator
* @return isOperator True if the operator is approved, false if not
*/
function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
/**
* @dev ERC-1155 interface for accepting safe transfers.
*/
interface IERC1155TokenReceiver {
/**
* @notice Handle the receipt of a single ERC1155 token type
* @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated
* This function MAY throw to revert and reject the transfer
* Return of other amount than the magic value MUST result in the transaction being reverted
* Note: The token contract address is always the message sender
* @param _operator The address which called the `safeTransferFrom` function
* @param _from The address which previously owned the token
* @param _id The id of the token being transferred
* @param _amount The amount of tokens being transferred
* @param _data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
*/
function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data) external returns(bytes4);
/**
* @notice Handle the receipt of multiple ERC1155 token types
* @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated
* This function MAY throw to revert and reject the transfer
* Return of other amount than the magic value WILL result in the transaction being reverted
* Note: The token contract address is always the message sender
* @param _operator The address which called the `safeBatchTransferFrom` function
* @param _from The address which previously owned the token
* @param _ids An array containing ids of each token being transferred
* @param _amounts An array containing amounts of each token being transferred
* @param _data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
*/
function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external returns(bytes4);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "../../utils/SafeMath.sol";
import "../../interfaces/IERC1155TokenReceiver.sol";
import "../../interfaces/IERC1155.sol";
import "../../utils/Address.sol";
import "../../utils/ERC165.sol";
/**
* @dev Implementation of Multi-Token Standard contract. This implementation of the ERC-1155 standard
* utilizes the fact that balances of different token ids can be concatenated within individual
* uint256 storage slots. This allows the contract to batch transfer tokens more efficiently at
* the cost of limiting the maximum token balance each address can hold. This limit is
* 2^IDS_BITS_SIZE, which can be adjusted below. In practice, using IDS_BITS_SIZE smaller than 16
* did not lead to major efficiency gains.
*/
contract ERC1155PackedBalance is IERC1155, ERC165 {
using SafeMath for uint256;
using Address for address;
/***********************************|
| Variables and Events |
|__________________________________*/
// onReceive function signatures
bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61;
bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81;
// Constants regarding bin sizes for balance packing
// IDS_BITS_SIZE **MUST** be a power of 2 (e.g. 2, 4, 8, 16, 32, 64, 128)
uint256 internal constant IDS_BITS_SIZE = 32; // Max balance amount in bits per token ID
uint256 internal constant IDS_PER_UINT256 = 256 / IDS_BITS_SIZE; // Number of ids per uint256
// Operations for _updateIDBalance
enum Operations { Add, Sub }
// Token IDs balances ; balances[address][id] => balance (using array instead of mapping for efficiency)
mapping (address => mapping(uint256 => uint256)) internal balances;
// Operators
mapping (address => mapping(address => bool)) internal operators;
/***********************************|
| Public Transfer Functions |
|__________________________________*/
/**
* @notice Transfers amount amount of an _id from the _from address to the _to address specified
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data)
public override
{
// Requirements
require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155PackedBalance#safeTransferFrom: INVALID_OPERATOR");
require(_to != address(0),"ERC1155PackedBalance#safeTransferFrom: INVALID_RECIPIENT");
// require(_amount <= balances); Not necessary since checked with _viewUpdateBinValue() checks
_safeTransferFrom(_from, _to, _id, _amount);
_callonERC1155Received(_from, _to, _id, _amount, gasleft(), _data);
}
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @dev Arrays should be sorted so that all ids in a same storage slot are adjacent (more efficient)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
public override
{
// Requirements
require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155PackedBalance#safeBatchTransferFrom: INVALID_OPERATOR");
require(_to != address(0),"ERC1155PackedBalance#safeBatchTransferFrom: INVALID_RECIPIENT");
_safeBatchTransferFrom(_from, _to, _ids, _amounts);
_callonERC1155BatchReceived(_from, _to, _ids, _amounts, gasleft(), _data);
}
/***********************************|
| Internal Transfer Functions |
|__________________________________*/
/**
* @notice Transfers amount amount of an _id from the _from address to the _to address specified
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
*/
function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount)
internal
{
//Update balances
_updateIDBalance(_from, _id, _amount, Operations.Sub); // Subtract amount from sender
_updateIDBalance(_to, _id, _amount, Operations.Add); // Add amount to recipient
// Emit event
emit TransferSingle(msg.sender, _from, _to, _id, _amount);
}
/**
* @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...)
*/
function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, uint256 _gasLimit, bytes memory _data)
internal
{
// Check if recipient is contract
if (_to.isContract()) {
bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received{gas:_gasLimit}(msg.sender, _from, _id, _amount, _data);
require(retval == ERC1155_RECEIVED_VALUE, "ERC1155PackedBalance#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE");
}
}
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @dev Arrays should be sorted so that all ids in a same storage slot are adjacent (more efficient)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
*/
function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts)
internal
{
uint256 nTransfer = _ids.length; // Number of transfer to execute
require(nTransfer == _amounts.length, "ERC1155PackedBalance#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH");
if (_from != _to && nTransfer > 0) {
// Load first bin and index where the token ID balance exists
(uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);
// Balance for current bin in memory (initialized with first transfer)
uint256 balFrom = _viewUpdateBinValue(balances[_from][bin], index, _amounts[0], Operations.Sub);
uint256 balTo = _viewUpdateBinValue(balances[_to][bin], index, _amounts[0], Operations.Add);
// Last bin updated
uint256 lastBin = bin;
for (uint256 i = 1; i < nTransfer; i++) {
(bin, index) = getIDBinIndex(_ids[i]);
// If new bin
if (bin != lastBin) {
// Update storage balance of previous bin
balances[_from][lastBin] = balFrom;
balances[_to][lastBin] = balTo;
balFrom = balances[_from][bin];
balTo = balances[_to][bin];
// Bin will be the most recent bin
lastBin = bin;
}
// Update memory balance
balFrom = _viewUpdateBinValue(balFrom, index, _amounts[i], Operations.Sub);
balTo = _viewUpdateBinValue(balTo, index, _amounts[i], Operations.Add);
}
// Update storage of the last bin visited
balances[_from][bin] = balFrom;
balances[_to][bin] = balTo;
// If transfer to self, just make sure all amounts are valid
} else {
for (uint256 i = 0; i < nTransfer; i++) {
require(balanceOf(_from, _ids[i]) >= _amounts[i], "ERC1155PackedBalance#_safeBatchTransferFrom: UNDERFLOW");
}
}
// Emit event
emit TransferBatch(msg.sender, _from, _to, _ids, _amounts);
}
/**
* @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...)
*/
function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, uint256 _gasLimit, bytes memory _data)
internal
{
// Pass data if recipient is contract
if (_to.isContract()) {
bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived{gas: _gasLimit}(msg.sender, _from, _ids, _amounts, _data);
require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155PackedBalance#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE");
}
}
/***********************************|
| Operator Functions |
|__________________________________*/
/**
* @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
* @param _operator Address to add to the set of authorized operators
* @param _approved True if the operator is approved, false to revoke approval
*/
function setApprovalForAll(address _operator, bool _approved)
external override
{
// Update operator status
operators[msg.sender][_operator] = _approved;
emit ApprovalForAll(msg.sender, _operator, _approved);
}
/**
* @notice Queries the approval status of an operator for a given owner
* @param _owner The owner of the Tokens
* @param _operator Address of authorized operator
* @return isOperator True if the operator is approved, false if not
*/
function isApprovedForAll(address _owner, address _operator)
public override view returns (bool isOperator)
{
return operators[_owner][_operator];
}
/***********************************|
| Public Balance Functions |
|__________________________________*/
/**
* @notice Get the balance of an account's Tokens
* @param _owner The address of the token holder
* @param _id ID of the Token
* @return The _owner's balance of the Token type requested
*/
function balanceOf(address _owner, uint256 _id)
public override view returns (uint256)
{
uint256 bin;
uint256 index;
//Get bin and index of _id
(bin, index) = getIDBinIndex(_id);
return getValueInBin(balances[_owner][bin], index);
}
/**
* @notice Get the balance of multiple account/token pairs
* @param _owners The addresses of the token holders (sorted owners will lead to less gas usage)
* @param _ids ID of the Tokens (sorted ids will lead to less gas usage
* @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
*/
function balanceOfBatch(address[] memory _owners, uint256[] memory _ids)
public override view returns (uint256[] memory)
{
uint256 n_owners = _owners.length;
require(n_owners == _ids.length, "ERC1155PackedBalance#balanceOfBatch: INVALID_ARRAY_LENGTH");
// First values
(uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);
uint256 balance_bin = balances[_owners[0]][bin];
uint256 last_bin = bin;
// Initialization
uint256[] memory batchBalances = new uint256[](n_owners);
batchBalances[0] = getValueInBin(balance_bin, index);
// Iterate over each owner and token ID
for (uint256 i = 1; i < n_owners; i++) {
(bin, index) = getIDBinIndex(_ids[i]);
// SLOAD if bin changed for the same owner or if owner changed
if (bin != last_bin || _owners[i-1] != _owners[i]) {
balance_bin = balances[_owners[i]][bin];
last_bin = bin;
}
batchBalances[i] = getValueInBin(balance_bin, index);
}
return batchBalances;
}
/***********************************|
| Packed Balance Functions |
|__________________________________*/
/**
* @notice Update the balance of a id for a given address
* @param _address Address to update id balance
* @param _id Id to update balance of
* @param _amount Amount to update the id balance
* @param _operation Which operation to conduct :
* Operations.Add: Add _amount to id balance
* Operations.Sub: Substract _amount from id balance
*/
function _updateIDBalance(address _address, uint256 _id, uint256 _amount, Operations _operation)
internal
{
uint256 bin;
uint256 index;
// Get bin and index of _id
(bin, index) = getIDBinIndex(_id);
// Update balance
balances[_address][bin] = _viewUpdateBinValue(balances[_address][bin], index, _amount, _operation);
}
/**
* @notice Update a value in _binValues
* @param _binValues Uint256 containing values of size IDS_BITS_SIZE (the token balances)
* @param _index Index of the value in the provided bin
* @param _amount Amount to update the id balance
* @param _operation Which operation to conduct :
* Operations.Add: Add _amount to value in _binValues at _index
* Operations.Sub: Substract _amount from value in _binValues at _index
*/
function _viewUpdateBinValue(uint256 _binValues, uint256 _index, uint256 _amount, Operations _operation)
internal pure returns (uint256 newBinValues)
{
uint256 shift = IDS_BITS_SIZE * _index;
uint256 mask = (uint256(1) << IDS_BITS_SIZE) - 1;
if (_operation == Operations.Add) {
newBinValues = _binValues + (_amount << shift);
require(newBinValues >= _binValues, "ERC1155PackedBalance#_viewUpdateBinValue: OVERFLOW");
require(
((_binValues >> shift) & mask) + _amount < 2**IDS_BITS_SIZE, // Checks that no other id changed
"ERC1155PackedBalance#_viewUpdateBinValue: OVERFLOW"
);
} else if (_operation == Operations.Sub) {
newBinValues = _binValues - (_amount << shift);
require(newBinValues <= _binValues, "ERC1155PackedBalance#_viewUpdateBinValue: UNDERFLOW");
require(
((_binValues >> shift) & mask) >= _amount, // Checks that no other id changed
"ERC1155PackedBalance#_viewUpdateBinValue: UNDERFLOW"
);
} else {
revert("ERC1155PackedBalance#_viewUpdateBinValue: INVALID_BIN_WRITE_OPERATION"); // Bad operation
}
return newBinValues;
}
/**
* @notice Return the bin number and index within that bin where ID is
* @param _id Token id
* @return bin index (Bin number, ID"s index within that bin)
*/
function getIDBinIndex(uint256 _id)
public pure returns (uint256 bin, uint256 index)
{
bin = _id / IDS_PER_UINT256;
index = _id % IDS_PER_UINT256;
return (bin, index);
}
/**
* @notice Return amount in _binValues at position _index
* @param _binValues uint256 containing the balances of IDS_PER_UINT256 ids
* @param _index Index at which to retrieve amount
* @return amount at given _index in _bin
*/
function getValueInBin(uint256 _binValues, uint256 _index)
public pure returns (uint256)
{
// require(_index < IDS_PER_UINT256) is not required since getIDBinIndex ensures `_index < IDS_PER_UINT256`
// Mask to retrieve data for a given binData
uint256 mask = (uint256(1) << IDS_BITS_SIZE) - 1;
// Shift amount
uint256 rightShift = IDS_BITS_SIZE * _index;
return (_binValues >> rightShift) & mask;
}
/***********************************|
| ERC165 Functions |
|__________________________________*/
/**
* @notice Query if a contract implements an interface
* @param _interfaceID The interface identifier, as specified in ERC-165
* @return `true` if the contract implements `_interfaceID` and
*/
function supportsInterface(bytes4 _interfaceID) public override(ERC165, IERC165) virtual pure returns (bool) {
if (_interfaceID == type(IERC1155).interfaceId) {
return true;
}
return super.supportsInterface(_interfaceID);
}
}pragma solidity 0.7.4;
/**
* Utility library of inline functions on addresses
*/
library Address {
// Default hash for EOA accounts returned by extcodehash
bytes32 constant internal ACCOUNT_HASH = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
/**
* Returns whether the target address is a contract
* @dev This function will return false if invoked during the constructor of a contract.
* @param _address address of the account to check
* @return Whether the target address is a contract
*/
function isContract(address _address) internal view returns (bool) {
bytes32 codehash;
// Currently there is no better way to check if there is a contract in an address
// than to check the size of the code at that address or if it has a non-zero code hash or account hash
assembly { codehash := extcodehash(_address) }
return (codehash != 0x0 && codehash != ACCOUNT_HASH);
}
}pragma solidity 0.7.4;
import "../interfaces/IERC165.sol";
abstract contract ERC165 is IERC165 {
/**
* @notice Query if a contract implements an interface
* @param _interfaceID The interface identifier, as specified in ERC-165
* @return `true` if the contract implements `_interfaceID`
*/
function supportsInterface(bytes4 _interfaceID) virtual override public pure returns (bool) {
return _interfaceID == this.supportsInterface.selector;
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "../../utils/ERC165.sol";
import "../../utils/SafeMath.sol";
import "../../interfaces/IERC2981.sol";
/**
* @notice Contract return royalty information for tokens of this contract
* @dev This contract sets a global fee information for all token ids.
*/
contract ERC2981Global is IERC2981, ERC165 {
using SafeMath for uint256;
struct FeeInfo {
address receiver;
uint256 feeBasisPoints;
}
// Royalty Fee information struct
FeeInfo public globalRoyaltyInfo;
/**
* @notice Will set the basis point and royalty recipient that is applied to all assets
* @param _receiver Fee recipient that will receive the royalty payments
* @param _royaltyBasisPoints Basis points with 3 decimals representing the fee %
* e.g. a fee of 2% would be 20 (i.e. 20 / 1000 == 0.02, or 2%)
*/
function _setGlobalRoyaltyInfo(address _receiver, uint256 _royaltyBasisPoints) internal {
require(_receiver != address(0x0), "ERC2981Global#_setGlobalRoyalty: RECIPIENT_IS_0x0");
require(_royaltyBasisPoints <= 1000, "ERC2981Global#_setGlobalRoyalty: FEE_IS_ABOVE_100_PERCENT");
globalRoyaltyInfo.receiver = _receiver;
globalRoyaltyInfo.feeBasisPoints = _royaltyBasisPoints;
}
/***********************************|
| ERC-2981 Functions |
|__________________________________*/
/**
* @notice Called with the sale price to determine how much royalty is owed and to whom.
* @param _saleCost - the sale cost of the NFT asset specified by _tokenId
* @return receiver - address of who should be sent the royalty payment
* @return royaltyAmount - the royalty payment amount for _salePrice
*/
function royaltyInfo(
uint256,
uint256 _saleCost
) external view override returns (address receiver, uint256 royaltyAmount)
{
FeeInfo memory info = globalRoyaltyInfo;
return (info.receiver, _saleCost.mul(info.feeBasisPoints).div(1000));
}
/***********************************|
| ERC-165 Functions |
|__________________________________*/
/**
* @notice Query if a contract implements an interface
* @param _interfaceID The interface identifier, as specified in ERC-165
* @return `true` if the contract implements `_interfaceID` and
*/
function supportsInterface(bytes4 _interfaceID) public override(ERC165, IERC165) virtual pure returns (bool) {
if (_interfaceID == type(IERC2981).interfaceId) {
return true;
}
return super.supportsInterface(_interfaceID);
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import './IERC165.sol';
interface IERC2981 is IERC165 {
/**
* @notice Called with the sale price to determine how much royalty is owed and to whom.
* @param _tokenId - the NFT asset queried for royalty information
* @param _saleCost - the sale cost of the NFT asset specified by _tokenId
* @return receiver - address of who should be sent the royalty payment
* @return royaltyAmount - the royalty payment amount for _salePrice
*/
function royaltyInfo(uint256 _tokenId, uint256 _saleCost) external view returns (address receiver, uint256 royaltyAmount);
}pragma solidity 0.7.4;
import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";
/**
* @notice This is a contract allowing contract owner to mint up to N
* assets per period of 6 hours.
* @dev This contract should only be able to mint some asset types
*/
contract RewardFactory is TieredOwnable {
using SafeMath for uint256;
/***********************************|
| Variables |
|__________________________________*/
// Token information
ISkyweaverAssets immutable public skyweaverAssets; // ERC-1155 Skyweaver assets contract
// Period variables
uint256 internal period; // Current period
uint256 internal availableSupply; // Amount of assets that can currently be minted
uint256 public periodMintLimit; // Amount that can be minted within 6h
uint256 immutable public PERIOD_LENGTH; // Length of each mint periods in seconds
// Whitelist
bool internal immutable MINT_WHITELIST_ONLY;
mapping(uint256 => bool) public mintWhitelist;
// Event
event PeriodMintLimitChanged(uint256 oldMintingLimit, uint256 newMintingLimit);
event AssetsEnabled(uint256[] enabledIds);
event AssetsDisabled(uint256[] disabledIds);
/***********************************|
| Constructor |
|__________________________________*/
/**
* @notice Create factory, link skyweaver assets and store initial parameters
* @param _firstOwner Address of the first owner
* @param _assetsAddr The address of the ERC-1155 Assets Token contract
* @param _periodLength Number of seconds each period lasts
* @param _periodMintLimit Can only mint N assets per period
* @param _whitelistOnly Whether this factory uses a mint whitelist or not
*/
constructor(
address _firstOwner,
address _assetsAddr,
uint256 _periodLength,
uint256 _periodMintLimit,
bool _whitelistOnly
) TieredOwnable(_firstOwner) public {
require(
_assetsAddr != address(0) &&
_periodLength > 0 &&
_periodMintLimit > 0,
"RewardFactory#constructor: INVALID_INPUT"
);
// Assets
skyweaverAssets = ISkyweaverAssets(_assetsAddr);
// Set Period length
PERIOD_LENGTH = _periodLength;
// Set whether this factory uses a mint whitelist or not
MINT_WHITELIST_ONLY = _whitelistOnly;
// Set current period
period = block.timestamp / _periodLength; // From livePeriod()
availableSupply = _periodMintLimit;
// Rewards parameters
periodMintLimit = _periodMintLimit;
emit PeriodMintLimitChanged(0, _periodMintLimit);
}
/***********************************|
| Management Methods |
|__________________________________*/
/**
* @notice Will update the daily mint limit
* @dev This change will take effect immediatly once executed
* @param _newPeriodMintLimit Amount of assets that can be minted within a period
*/
function updatePeriodMintLimit(uint256 _newPeriodMintLimit) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
// Immediately update supply instead of waiting for next period
if (availableSupply > _newPeriodMintLimit) {
availableSupply = _newPeriodMintLimit;
}
emit PeriodMintLimitChanged(periodMintLimit, _newPeriodMintLimit);
periodMintLimit = _newPeriodMintLimit;
}
/**
* @notice Will enable these tokens to be minted by this factory
* @param _enabledIds IDs this factory can mint
*/
function enableMint(uint256[] calldata _enabledIds) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
for (uint256 i = 0; i < _enabledIds.length; i++) {
mintWhitelist[_enabledIds[i]] = true;
}
emit AssetsEnabled(_enabledIds);
}
/**
* @notice Will prevent these ids from being minted by this factory
* @param _disabledIds IDs this factory can mint
*/
function disableMint(uint256[] calldata _disabledIds) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
for (uint256 i = 0; i < _disabledIds.length; i++) {
mintWhitelist[_disabledIds[i]] = false;
}
emit AssetsDisabled(_disabledIds);
}
/***********************************|
| Receiver Method Handler |
|__________________________________*/
/**
* @notice Prevents receiving Ether or calls to unsuported methods
*/
fallback () external {
revert("RewardFactory#_: UNSUPPORTED_METHOD");
}
/***********************************|
| Minting Functions |
|__________________________________*/
/**
* @notice Will mint tokens to user
* @dev Can only mint up to the periodMintLimit in a given 6hour period
* @param _to The address that receives the assets
* @param _ids Array of Tokens ID that are minted
* @param _amounts Amount of Tokens id minted for each corresponding Token id in _ids
* @param _data Byte array passed to recipient if recipient is a contract
*/
function batchMint(address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data)
external onlyOwnerTier(1)
{
uint256 live_period = livePeriod();
uint256 stored_period = period;
uint256 available_supply;
// Update period and refresh the available supply if period
// is different, otherwise use current available supply.
if (live_period == stored_period) {
available_supply = availableSupply;
} else {
available_supply = periodMintLimit;
period = live_period;
}
// If there is an insufficient available supply, this will revert
for (uint256 i = 0; i < _ids.length; i++) {
available_supply = available_supply.sub(_amounts[i]);
if (MINT_WHITELIST_ONLY) {
require(mintWhitelist[_ids[i]], "RewardFactory#batchMint: ID_IS_NOT_WHITELISTED");
}
}
// Store available supply
availableSupply = available_supply;
// Mint assets
skyweaverAssets.batchMint(_to, _ids, _amounts, _data);
}
/***********************************|
| Utility Functions |
|__________________________________*/
/**
* @notice Returns how many cards can currently be minted by this factory
*/
function getAvailableSupply() external view returns (uint256) {
return livePeriod() == period ? availableSupply : periodMintLimit;
}
/**
* @notice Calculate the current period
*/
function livePeriod() public view returns (uint256) {
return block.timestamp / PERIOD_LENGTH;
}
/**
* @notice Indicates whether a contract implements a given interface.
* @param interfaceID The ERC-165 interface ID that is queried for support.
* @return True if contract interface is supported.
*/
function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
return interfaceID == type(IERC165).interfaceId;
}
}pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;
import "./Ownable.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";
/**
* @dev This contract allows an owner to execute registered calls after an expiration
* delay has passed. This contract can then be the owner of another contract to
* enforce delayed function calls.
* @dev Does not support passing ETH in calls for simplicity, but could be added in V2.
*/
contract DelayedOwner is Ownable {
using SafeMath for uint256;
// Time transactions must be registered before being executable
uint256 immutable internal EXECUTION_DELAY;
// Mapping between transaction id and transaction hashes
mapping(uint256 => bytes32) public txHashes;
// Events
event TransactionRegistered(Transaction transaction);
event TransactionCancelled(Transaction transaction);
event TransactionExecuted(Transaction transaction);
// Transaction structure
struct Transaction {
Status status; // Transaction status
uint256 triggerTime; // Timestamp after which the transaction can be executed
address target; // Address of the contract to call
uint256 id; // Transaction identifier (unique)
bytes data; // calldata to pass
}
enum Status {
NotRegistered, // 0x0 - Transaction was not registered
Pending, // 0x1 - Transaction was registered but not executed
Executed, // 0x2 - Transaction was executed
Cancelled // 0x3 - Transaction was registered and cancelled
}
/**
* @dev Registers the execution delay for this contract
* @param _firstOwner Address of the first owner
* @param _delay Amount of time in seconds the delay will be
*/
constructor (address _firstOwner, uint256 _delay) Ownable(_firstOwner) {
EXECUTION_DELAY = _delay;
}
/***********************************|
| Core Functions |
|__________________________________*/
/**
* @notice Register a transaction to execute post delay
* @param _tx Transaction to execute
*/
function register(Transaction memory _tx) onlyOwner() public {
require(txHashes[_tx.id] == 0x0, "DelayedOwner#register: TX_ALREADY_REGISTERED");
// Set trigger time and mark transaction as pending
_tx.triggerTime = block.timestamp.add(EXECUTION_DELAY);
_tx.status = Status.Pending;
// Store transaction
txHashes[_tx.id] = keccak256(abi.encode(_tx));
emit TransactionRegistered(_tx);
}
/**
* @notice Cancels a transaction that was registered but not yet executed or cancelled
* @param _tx Transaction to cancel
*/
function cancel(Transaction memory _tx) onlyOwner() onlyValidWitnesses(_tx) public {
require(_tx.status == Status.Pending, "DelayedOwner#cancel: TX_NOT_PENDING");
// Set status to Cancelled
_tx.status = Status.Cancelled;
// Store transaction
txHashes[_tx.id] = keccak256(abi.encode(_tx));
emit TransactionCancelled(_tx);
}
/**
* @notice Will execute transaction specified
* @param _tx Transaction to execute
*/
function execute(Transaction memory _tx) onlyValidWitnesses(_tx) public {
require(_tx.status == Status.Pending, "DelayedOwner#execute: TX_NOT_PENDING");
require(_tx.triggerTime <= block.timestamp, "DelayedOwne#execute: TX_NOT_YET_EXECUTABLE");
// Mark transaction as executed, preventing re-entrancy and replay
_tx.status = Status.Executed;
// Store transaction
txHashes[_tx.id] = keccak256(abi.encode(_tx));
// Execute transaction
(bool success,) = _tx.target.call(_tx.data);
require(success, "DelayedOwner#execute: TX_FAILED");
emit TransactionExecuted(_tx);
}
/***********************************|
| Utility Functions |
|__________________________________*/
/**
* @notice Verify if provided transaction object matches registered transaction
* @param _tx Transaction to validate
*/
function isValidWitness(Transaction memory _tx) public view returns (bool isValid) {
return txHashes[_tx.id] == keccak256(abi.encode(_tx));
}
/**
* @notice Will enforce that the provided transaction witness is valid
* @param _tx Transaction to validate
*/
modifier onlyValidWitnesses(Transaction memory _tx) {
require(
isValidWitness(_tx),
"DelayedOwner#onlyValidWitnesses: INVALID_TX_WITNESS"
);
_;
}
}pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;
/**
* @title Ownable
* @dev The Ownable contract has an owner address, and provides basic authorization control
* functions, this simplifies the implementation of "user permissions".
*/
contract Ownable {
address internal owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev The Ownable constructor sets the original `owner` of the contract to the specied address
* @param _firstOwner Address of the first owner
*/
constructor (address _firstOwner) {
owner = _firstOwner;
emit OwnershipTransferred(address(0), _firstOwner);
}
/**
* @dev Throws if called by any account other than the master owner.
*/
modifier onlyOwner() {
require(msg.sender == owner, "Ownable#onlyOwner: SENDER_IS_NOT_OWNER");
_;
}
/**
* @notice Transfers the ownership of the contract to new address
* @param _newOwner Address of the new owner
*/
function transferOwnership(address _newOwner) public onlyOwner {
require(_newOwner != address(0), "Ownable#transferOwnership: INVALID_ADDRESS");
owner = _newOwner;
emit OwnershipTransferred(owner, _newOwner);
}
/**
* @notice Returns the address of the owner.
*/
function getOwner() public view returns (address) {
return owner;
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "./ERC1155PackedBalance.sol";
/**
* @dev Multi-Fungible Tokens with minting and burning methods. These methods assume
* a parent contract to be executed as they are `internal` functions.
*/
contract ERC1155MintBurnPackedBalance is ERC1155PackedBalance {
/****************************************|
| Minting Functions |
|_______________________________________*/
/**
* @notice Mint _amount of tokens of a given id
* @param _to The address to mint tokens to
* @param _id Token id to mint
* @param _amount The amount to be minted
* @param _data Data to pass if receiver is contract
*/
function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data)
internal
{
//Add _amount
_updateIDBalance(_to, _id, _amount, Operations.Add); // Add amount to recipient
// Emit event
emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount);
// Calling onReceive method if recipient is contract
_callonERC1155Received(address(0x0), _to, _id, _amount, gasleft(), _data);
}
/**
* @notice Mint tokens for each (_ids[i], _amounts[i]) pair
* @param _to The address to mint tokens to
* @param _ids Array of ids to mint
* @param _amounts Array of amount of tokens to mint per id
* @param _data Data to pass if receiver is contract
*/
function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
internal
{
require(_ids.length == _amounts.length, "ERC1155MintBurnPackedBalance#_batchMint: INVALID_ARRAYS_LENGTH");
if (_ids.length > 0) {
// Load first bin and index where the token ID balance exists
(uint256 bin, uint256 index) = getIDBinIndex(_ids[0]);
// Balance for current bin in memory (initialized with first transfer)
uint256 balTo = _viewUpdateBinValue(balances[_to][bin], index, _amounts[0], Operations.Add);
// Number of transfer to execute
uint256 nTransfer = _ids.length;
// Last bin updated
uint256 lastBin = bin;
for (uint256 i = 1; i < nTransfer; i++) {
(bin, index) = getIDBinIndex(_ids[i]);
// If new bin
if (bin != lastBin) {
// Update storage balance of previous bin
balances[_to][lastBin] = balTo;
balTo = balances[_to][bin];
// Bin will be the most recent bin
lastBin = bin;
}
// Update memory balance
balTo = _viewUpdateBinValue(balTo, index, _amounts[i], Operations.Add);
}
// Update storage of the last bin visited
balances[_to][bin] = balTo;
}
// //Emit event
emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts);
// Calling onReceive method if recipient is contract
_callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, gasleft(), _data);
}
/****************************************|
| Burning Functions |
|_______________________________________*/
/**
* @notice Burn _amount of tokens of a given token id
* @param _from The address to burn tokens from
* @param _id Token id to burn
* @param _amount The amount to be burned
*/
function _burn(address _from, uint256 _id, uint256 _amount)
internal
{
// Substract _amount
_updateIDBalance(_from, _id, _amount, Operations.Sub);
// Emit event
emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount);
}
/**
* @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair
* @dev This batchBurn method does not implement the most efficient way of updating
* balances to reduce the potential bug surface as this function is expected to
* be less common than transfers. EIP-2200 makes this method significantly
* more efficient already for packed balances.
* @param _from The address to burn tokens from
* @param _ids Array of token ids to burn
* @param _amounts Array of the amount to be burned
*/
function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts)
internal
{
// Number of burning to execute
uint256 nBurn = _ids.length;
require(nBurn == _amounts.length, "ERC1155MintBurnPackedBalance#batchBurn: INVALID_ARRAYS_LENGTH");
// Executing all burning
for (uint256 i = 0; i < nBurn; i++) {
// Update storage balance
_updateIDBalance(_from, _ids[i], _amounts[i], Operations.Sub); // Add amount to recipient
}
// Emit batch burn event
emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts);
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "../../interfaces/IERC1155Metadata.sol";
import "../../utils/ERC165.sol";
/**
* @notice Contract that handles metadata related methods.
* @dev Methods assume a deterministic generation of URI based on token IDs.
* Methods also assume that URI uses hex representation of token IDs.
*/
contract ERC1155Metadata is IERC1155Metadata, ERC165 {
// URI's default URI prefix
string public baseURI;
string public name;
// set the initial name and base URI
constructor(string memory _name, string memory _baseURI) {
name = _name;
baseURI = _baseURI;
}
/***********************************|
| Metadata Public Functions |
|__________________________________*/
/**
* @notice A distinct Uniform Resource Identifier (URI) for a given token.
* @dev URIs are defined in RFC 3986.
* URIs are assumed to be deterministically generated based on token ID
* @return URI string
*/
function uri(uint256 _id) public override view returns (string memory) {
return string(abi.encodePacked(baseURI, _uint2str(_id), ".json"));
}
/***********************************|
| Metadata Internal Functions |
|__________________________________*/
/**
* @notice Will emit default URI log event for corresponding token _id
* @param _tokenIDs Array of IDs of tokens to log default URI
*/
function _logURIs(uint256[] memory _tokenIDs) internal {
string memory baseURL = baseURI;
string memory tokenURI;
for (uint256 i = 0; i < _tokenIDs.length; i++) {
tokenURI = string(abi.encodePacked(baseURL, _uint2str(_tokenIDs[i]), ".json"));
emit URI(tokenURI, _tokenIDs[i]);
}
}
/**
* @notice Will update the base URL of token's URI
* @param _newBaseMetadataURI New base URL of token's URI
*/
function _setBaseMetadataURI(string memory _newBaseMetadataURI) internal {
baseURI = _newBaseMetadataURI;
}
/**
* @notice Will update the name of the contract
* @param _newName New contract name
*/
function _setContractName(string memory _newName) internal {
name = _newName;
}
/**
* @notice Query if a contract implements an interface
* @param _interfaceID The interface identifier, as specified in ERC-165
* @return `true` if the contract implements `_interfaceID` and
*/
function supportsInterface(bytes4 _interfaceID) public override virtual pure returns (bool) {
if (_interfaceID == type(IERC1155Metadata).interfaceId) {
return true;
}
return super.supportsInterface(_interfaceID);
}
/***********************************|
| Utility Internal Functions |
|__________________________________*/
/**
* @notice Convert uint256 to string
* @param _i Unsigned integer to convert to string
*/
function _uint2str(uint256 _i) internal pure returns (string memory _uintAsString) {
if (_i == 0) {
return "0";
}
uint256 j = _i;
uint256 ii = _i;
uint256 len;
// Get number of bytes
while (j != 0) {
len++;
j /= 10;
}
bytes memory bstr = new bytes(len);
uint256 k = len - 1;
// Get each individual ASCII
while (ii != 0) {
bstr[k--] = byte(uint8(48 + ii % 10));
ii /= 10;
}
// Convert to string
return string(bstr);
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
interface IERC1155Metadata {
event URI(string _uri, uint256 indexed _id);
/****************************************|
| Functions |
|_______________________________________*/
/**
* @notice A distinct Uniform Resource Identifier (URI) for a given token.
* @dev URIs are defined in RFC 3986.
* URIs are assumed to be deterministically generated based on token ID
* Token IDs are assumed to be represented in their hex format in URIs
* @return URI string
*/
function uri(uint256 _id) external view returns (string memory);
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;
import "../tokens/ERC1155/ERC1155MintBurn.sol";
import "../tokens/ERC1155/ERC1155Metadata.sol";
contract ERC1155MintBurnMock is ERC1155MintBurn, ERC1155Metadata {
// set the initial name and base URI
constructor(string memory _name, string memory _baseURI) ERC1155Metadata(_name, _baseURI) {}
/**
* @notice Query if a contract implements an interface
* @dev Parent contract inheriting multiple contracts with supportsInterface()
* need to implement an overriding supportsInterface() function specifying
* all inheriting contracts that have a supportsInterface() function.
* @param _interfaceID The interface identifier, as specified in ERC-165
* @return `true` if the contract implements `_interfaceID`
*/
function supportsInterface(
bytes4 _interfaceID
) public override(
ERC1155,
ERC1155Metadata
) pure virtual returns (bool) {
return super.supportsInterface(_interfaceID);
}
/***********************************|
| Minting Functions |
|__________________________________*/
/**
* @dev Mint _value of tokens of a given id
* @param _to The address to mint tokens to.
* @param _id token id to mint
* @param _value The amount to be minted
* @param _data Data to be passed if receiver is contract
*/
function mintMock(address _to, uint256 _id, uint256 _value, bytes memory _data)
public
{
super._mint(_to, _id, _value, _data);
}
/**
* @dev Mint tokens for each ids in _ids
* @param _to The address to mint tokens to.
* @param _ids Array of ids to mint
* @param _values Array of amount of tokens to mint per id
* @param _data Data to be passed if receiver is contract
*/
function batchMintMock(address _to, uint256[] memory _ids, uint256[] memory _values, bytes memory _data)
public
{
super._batchMint(_to, _ids, _values, _data);
}
/***********************************|
| Burning Functions |
|__________________________________*/
/**
* @dev burn _value of tokens of a given token id
* @param _from The address to burn tokens from.
* @param _id token id to burn
* @param _value The amount to be burned
*/
function burnMock(address _from, uint256 _id, uint256 _value)
public
{
super._burn(_from, _id, _value);
}
/**
* @dev burn _value of tokens of a given token id
* @param _from The address to burn tokens from.
* @param _ids Array of token ids to burn
* @param _values Array of the amount to be burned
*/
function batchBurnMock(address _from, uint256[] memory _ids, uint256[] memory _values)
public
{
super._batchBurn(_from, _ids, _values);
}
/***********************************|
| Unsupported Functions |
|__________________________________*/
fallback () virtual external {
revert("ERC1155MetaMintBurnMock: INVALID_METHOD");
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "./ERC1155.sol";
/**
* @dev Multi-Fungible Tokens with minting and burning methods. These methods assume
* a parent contract to be executed as they are `internal` functions
*/
contract ERC1155MintBurn is ERC1155 {
using SafeMath for uint256;
/****************************************|
| Minting Functions |
|_______________________________________*/
/**
* @notice Mint _amount of tokens of a given id
* @param _to The address to mint tokens to
* @param _id Token id to mint
* @param _amount The amount to be minted
* @param _data Data to pass if receiver is contract
*/
function _mint(address _to, uint256 _id, uint256 _amount, bytes memory _data)
internal
{
// Add _amount
balances[_to][_id] = balances[_to][_id].add(_amount);
// Emit event
emit TransferSingle(msg.sender, address(0x0), _to, _id, _amount);
// Calling onReceive method if recipient is contract
_callonERC1155Received(address(0x0), _to, _id, _amount, gasleft(), _data);
}
/**
* @notice Mint tokens for each ids in _ids
* @param _to The address to mint tokens to
* @param _ids Array of ids to mint
* @param _amounts Array of amount of tokens to mint per id
* @param _data Data to pass if receiver is contract
*/
function _batchMint(address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
internal
{
require(_ids.length == _amounts.length, "ERC1155MintBurn#batchMint: INVALID_ARRAYS_LENGTH");
// Number of mints to execute
uint256 nMint = _ids.length;
// Executing all minting
for (uint256 i = 0; i < nMint; i++) {
// Update storage balance
balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]);
}
// Emit batch mint event
emit TransferBatch(msg.sender, address(0x0), _to, _ids, _amounts);
// Calling onReceive method if recipient is contract
_callonERC1155BatchReceived(address(0x0), _to, _ids, _amounts, gasleft(), _data);
}
/****************************************|
| Burning Functions |
|_______________________________________*/
/**
* @notice Burn _amount of tokens of a given token id
* @param _from The address to burn tokens from
* @param _id Token id to burn
* @param _amount The amount to be burned
*/
function _burn(address _from, uint256 _id, uint256 _amount)
internal
{
//Substract _amount
balances[_from][_id] = balances[_from][_id].sub(_amount);
// Emit event
emit TransferSingle(msg.sender, _from, address(0x0), _id, _amount);
}
/**
* @notice Burn tokens of given token id for each (_ids[i], _amounts[i]) pair
* @param _from The address to burn tokens from
* @param _ids Array of token ids to burn
* @param _amounts Array of the amount to be burned
*/
function _batchBurn(address _from, uint256[] memory _ids, uint256[] memory _amounts)
internal
{
// Number of mints to execute
uint256 nBurn = _ids.length;
require(nBurn == _amounts.length, "ERC1155MintBurn#batchBurn: INVALID_ARRAYS_LENGTH");
// Executing all minting
for (uint256 i = 0; i < nBurn; i++) {
// Update storage balance
balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]);
}
// Emit batch mint event
emit TransferBatch(msg.sender, _from, address(0x0), _ids, _amounts);
}
}// SPDX-License-Identifier: Apache-2.0
pragma solidity 0.7.4;
import "../../utils/SafeMath.sol";
import "../../interfaces/IERC1155TokenReceiver.sol";
import "../../interfaces/IERC1155.sol";
import "../../utils/Address.sol";
import "../../utils/ERC165.sol";
/**
* @dev Implementation of Multi-Token Standard contract
*/
contract ERC1155 is IERC1155, ERC165 {
using SafeMath for uint256;
using Address for address;
/***********************************|
| Variables and Events |
|__________________________________*/
// onReceive function signatures
bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61;
bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81;
// Objects balances
mapping (address => mapping(uint256 => uint256)) internal balances;
// Operator Functions
mapping (address => mapping(address => bool)) internal operators;
/***********************************|
| Public Transfer Functions |
|__________________________________*/
/**
* @notice Transfers amount amount of an _id from the _from address to the _to address specified
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes memory _data)
public override
{
require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeTransferFrom: INVALID_OPERATOR");
require(_to != address(0),"ERC1155#safeTransferFrom: INVALID_RECIPIENT");
// require(_amount <= balances[_from][_id]) is not necessary since checked with safemath operations
_safeTransferFrom(_from, _to, _id, _amount);
_callonERC1155Received(_from, _to, _id, _amount, gasleft(), _data);
}
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, bytes memory _data)
public override
{
// Requirements
require((msg.sender == _from) || isApprovedForAll(_from, msg.sender), "ERC1155#safeBatchTransferFrom: INVALID_OPERATOR");
require(_to != address(0), "ERC1155#safeBatchTransferFrom: INVALID_RECIPIENT");
_safeBatchTransferFrom(_from, _to, _ids, _amounts);
_callonERC1155BatchReceived(_from, _to, _ids, _amounts, gasleft(), _data);
}
/***********************************|
| Internal Transfer Functions |
|__________________________________*/
/**
* @notice Transfers amount amount of an _id from the _from address to the _to address specified
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
*/
function _safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount)
internal
{
// Update balances
balances[_from][_id] = balances[_from][_id].sub(_amount); // Subtract amount
balances[_to][_id] = balances[_to][_id].add(_amount); // Add amount
// Emit event
emit TransferSingle(msg.sender, _from, _to, _id, _amount);
}
/**
* @notice Verifies if receiver is contract and if so, calls (_to).onERC1155Received(...)
*/
function _callonERC1155Received(address _from, address _to, uint256 _id, uint256 _amount, uint256 _gasLimit, bytes memory _data)
internal
{
// Check if recipient is contract
if (_to.isContract()) {
bytes4 retval = IERC1155TokenReceiver(_to).onERC1155Received{gas: _gasLimit}(msg.sender, _from, _id, _amount, _data);
require(retval == ERC1155_RECEIVED_VALUE, "ERC1155#_callonERC1155Received: INVALID_ON_RECEIVE_MESSAGE");
}
}
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
*/
function _safeBatchTransferFrom(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts)
internal
{
require(_ids.length == _amounts.length, "ERC1155#_safeBatchTransferFrom: INVALID_ARRAYS_LENGTH");
// Number of transfer to execute
uint256 nTransfer = _ids.length;
// Executing all transfers
for (uint256 i = 0; i < nTransfer; i++) {
// Update storage balance of previous bin
balances[_from][_ids[i]] = balances[_from][_ids[i]].sub(_amounts[i]);
balances[_to][_ids[i]] = balances[_to][_ids[i]].add(_amounts[i]);
}
// Emit event
emit TransferBatch(msg.sender, _from, _to, _ids, _amounts);
}
/**
* @notice Verifies if receiver is contract and if so, calls (_to).onERC1155BatchReceived(...)
*/
function _callonERC1155BatchReceived(address _from, address _to, uint256[] memory _ids, uint256[] memory _amounts, uint256 _gasLimit, bytes memory _data)
internal
{
// Pass data if recipient is contract
if (_to.isContract()) {
bytes4 retval = IERC1155TokenReceiver(_to).onERC1155BatchReceived{gas: _gasLimit}(msg.sender, _from, _ids, _amounts, _data);
require(retval == ERC1155_BATCH_RECEIVED_VALUE, "ERC1155#_callonERC1155BatchReceived: INVALID_ON_RECEIVE_MESSAGE");
}
}
/***********************************|
| Operator Functions |
|__________________________________*/
/**
* @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
* @param _operator Address to add to the set of authorized operators
* @param _approved True if the operator is approved, false to revoke approval
*/
function setApprovalForAll(address _operator, bool _approved)
external override
{
// Update operator status
operators[msg.sender][_operator] = _approved;
emit ApprovalForAll(msg.sender, _operator, _approved);
}
/**
* @notice Queries the approval status of an operator for a given owner
* @param _owner The owner of the Tokens
* @param _operator Address of authorized operator
* @return isOperator True if the operator is approved, false if not
*/
function isApprovedForAll(address _owner, address _operator)
public override view returns (bool isOperator)
{
return operators[_owner][_operator];
}
/***********************************|
| Balance Functions |
|__________________________________*/
/**
* @notice Get the balance of an account's Tokens
* @param _owner The address of the token holder
* @param _id ID of the Token
* @return The _owner's balance of the Token type requested
*/
function balanceOf(address _owner, uint256 _id)
public override view returns (uint256)
{
return balances[_owner][_id];
}
/**
* @notice Get the balance of multiple account/token pairs
* @param _owners The addresses of the token holders
* @param _ids ID of the Tokens
* @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
*/
function balanceOfBatch(address[] memory _owners, uint256[] memory _ids)
public override view returns (uint256[] memory)
{
require(_owners.length == _ids.length, "ERC1155#balanceOfBatch: INVALID_ARRAY_LENGTH");
// Variables
uint256[] memory batchBalances = new uint256[](_owners.length);
// Iterate over each owner and token ID
for (uint256 i = 0; i < _owners.length; i++) {
batchBalances[i] = balances[_owners[i]][_ids[i]];
}
return batchBalances;
}
/***********************************|
| ERC165 Functions |
|__________________________________*/
/**
* @notice Query if a contract implements an interface
* @param _interfaceID The interface identifier, as specified in ERC-165
* @return `true` if the contract implements `_interfaceID` and
*/
function supportsInterface(bytes4 _interfaceID) public override(ERC165, IERC165) virtual pure returns (bool) {
if (_interfaceID == type(IERC1155).interfaceId) {
return true;
}
return super.supportsInterface(_interfaceID);
}
}pragma solidity 0.7.4;
import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "@0xsequence/erc-1155/contracts/utils/SafeMath.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC1155TokenReceiver.sol";
/**
* @notice Allows players to convert their silver cards and Wrapped DAI (wDAI) to conquest entries.
*
* @dev Assumes both cards and entries have the same number of decimals, if not, need to change
* the amount minted.
*
* @dev This contract should only be able to mint conquest entries.
*/
contract ConquestEntriesFactory is IERC1155TokenReceiver, TieredOwnable {
using SafeMath for uint256;
/***********************************|
| Variables |
|__________________________________*/
// Assets
ISkyweaverAssets immutable public skyweaverAssets; // ERC-1155 Skyweaver assets contract
IERC1155 immutable internal wDai; // ERC-1155 Wrapped DAI contract
uint256 immutable public wDaiID; // ID of wDAI token in respective ERC-1155 contract
uint256 immutable public silverRangeMin; // Lower bound for the range of asset IDs that can be converted to entries
uint256 immutable public silverRangeMax; // Upper bound for the range of asset IDs that can be converted to entries
// Conquest entry token id
uint256 immutable public conquestEntryID;
// Parameters
uint256 constant internal CARD_DECIMALS = 2; // Number of decimals cards have
uint256 constant internal ENTRIES_DECIMALS = 2; // Number of decimals entries have
uint256 constant internal wDAI_DECIMALS = 6; // Number of decimals wDAI have
uint256 constant internal wDAI_REQUIRED = 15 * 10**(wDAI_DECIMALS-1); // 1.5 wDAI for 1 conquest entry (after decimals)
/***********************************|
| Constructor |
|__________________________________*/
/**
* @notice Create factory, link skyweaver assets and store initial parameters
* @param _firstOwner Address of the first owner
* @param _skyweaverAssetsAddress The address of the ERC-1155 Assets Token contract
* @param _wDaiAddress The address of the ERC-1155 Wrapped DAI
* @param _wDaiID Wrapped DAI token id
* @param _conquestEntryTokenId Conquest entry token id
* @param _silverRangeMin Minimum id for silver cards
* @param _silverRangeMax Maximum id for silver cards
*/
constructor(
address _firstOwner,
address _skyweaverAssetsAddress,
address _wDaiAddress,
uint256 _wDaiID,
uint256 _conquestEntryTokenId,
uint256 _silverRangeMin,
uint256 _silverRangeMax
) TieredOwnable(_firstOwner) public
{
require(
_skyweaverAssetsAddress != address(0) &&
_wDaiAddress != address(0) &&
_silverRangeMin < _silverRangeMax,
"ConquestEntriesFactory#constructor: INVALID_INPUT"
);
// Assets
skyweaverAssets = ISkyweaverAssets(_skyweaverAssetsAddress);
wDai = IERC1155(_wDaiAddress);
wDaiID = _wDaiID;
conquestEntryID = _conquestEntryTokenId;
silverRangeMin = _silverRangeMin;
silverRangeMax = _silverRangeMax;
}
/***********************************|
| Receiver Method Handler |
|__________________________________*/
/**
* @notice Prevents receiving Ether or calls to unsuported methods
*/
fallback () external {
revert("ConquestEntriesFactory#_: UNSUPPORTED_METHOD");
}
/**
* @notice Players converting silver cards to conquest entries
* @dev Payload is passed to and verified by onERC1155BatchReceived()
*/
function onERC1155Received(
address _operator,
address _from,
uint256 _id,
uint256 _amount,
bytes calldata _data
)
external override returns(bytes4)
{
// Convert payload to arrays to pass to onERC1155BatchReceived()
uint256[] memory ids = new uint256[](1);
uint256[] memory amounts = new uint256[](1);
ids[0] = _id;
amounts[0] = _amount;
// Will revert call if doesn't pass
onERC1155BatchReceived(_operator, _from, ids, amounts, _data);
// Return success
return IERC1155TokenReceiver.onERC1155Received.selector;
}
/**
* @notice Players converting silver cards or wDAIs to conquest entries
* @param _from Address who sent the token
* @param _ids An array containing ids of each Token being transferred
* @param _amounts An array containing amounts of each Token being transferred
* @param _data If data is provided, it should be address who will receive the entries
*/
function onERC1155BatchReceived(
address, // _operator
address _from,
uint256[] memory _ids,
uint256[] memory _amounts,
bytes memory _data
)
public override returns(bytes4)
{
// Number of entries to mint
uint256 n_entries = 0;
// Burn cards or store wDAI
if (msg.sender == address(skyweaverAssets)) {
// Validate IDs and count number of entries to mint
for (uint256 i = 0; i < _ids.length; i++) {
require(
silverRangeMin <= _ids[i] && _ids[i] <= silverRangeMax,
"ConquestEntriesFactory#onERC1155BatchReceived: ID_IS_OUT_OF_RANGE"
);
n_entries = n_entries.add(_amounts[i]);
}
// Account for cards decimals
n_entries = n_entries.div(10**CARD_DECIMALS);
// Burn silver cards received
skyweaverAssets.batchBurn(_ids, _amounts);
} else if (msg.sender == address(wDai)) {
require(_ids.length == 1, "ConquestEntriesFactory#onERC1155BatchReceived: INVALID_ARRAY_LENGTH");
require(_ids[0] == wDaiID, "ConquestEntriesFactory#onERC1155BatchReceived: INVALID_wDAI_ID");
n_entries = _amounts[0] / wDAI_REQUIRED;
// Do nothing else. wDAIs are stored until withdrawn
} else {
revert("ConquestEntriesFactory#onERC1155BatchReceived: INVALID_TOKEN_ADDRESS");
}
// If an address is specified in _data, use it as receiver, otherwise use _from address
address receiver = _data.length > 0 ? abi.decode(_data, (address)) : _from;
// Mint conquest entries (with decimals)
skyweaverAssets.mint(receiver, conquestEntryID, n_entries*10**ENTRIES_DECIMALS, "");
// Return success
return IERC1155TokenReceiver.onERC1155BatchReceived.selector;
}
/**
* @notice Send current wDAI balance of this contract to recipient
* @param _recipient Address where the currency will be sent to
* @param _data Data to pass with transfer function
*/
function withdraw(address _recipient, bytes calldata _data) external onlyOwnerTier(HIGHEST_OWNER_TIER) {
require(_recipient != address(0x0), "ConquestEntriesFactory#withdraw: INVALID_RECIPIENT");
uint256 this_balance = wDai.balanceOf(address(this), wDaiID);
wDai.safeTransferFrom(address(this), _recipient, wDaiID, this_balance, _data);
}
/***********************************|
| Utility Functions |
|__________________________________*/
/**
* @notice Indicates whether a contract implements a given interface.
* @param interfaceID The ERC-165 interface ID that is queried for support.
* @return True if contract interface is supported.
*/
function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
return interfaceID == type(IERC165).interfaceId ||
interfaceID == type(IERC1155TokenReceiver).interfaceId;
}
}pragma solidity 0.7.4;
import "../interfaces/ISkyweaverAssets.sol";
contract FactoryMock {
ISkyweaverAssets internal skyweaverAssets; //SkyWeaver Curencies Factory Manager Contract
constructor(address _factoryManagerAddr) public {
skyweaverAssets = ISkyweaverAssets(_factoryManagerAddr);
}
function batchMint(
address _to,
uint256[] memory _ids,
uint256[] memory _amounts,
bytes memory _data) public
{
skyweaverAssets.batchMint(_to, _ids, _amounts, _data);
}
function mint(
address _to,
uint256 _id,
uint256 _amount,
bytes memory _data) public
{
skyweaverAssets.mint(_to, _id, _amount, _data);
}
}pragma solidity 0.7.4;
import "../utils/TieredOwnable.sol";
import "../interfaces/ISkyweaverAssets.sol";
import "@0xsequence/erc-1155/contracts/interfaces/IERC165.sol";
/**
* This is a contract allowing owner to mint any tokens within a given
* range. This factory will be used to mint community related assets, special
* event assets that are meant to be given away.
*/
contract FreemintFactory is TieredOwnable {
// ERC-1155 Skyweaver assets contract
ISkyweaverAssets internal skyweaverAssets;
/***********************************|
| Constructor |
|__________________________________*/
/**
* @notice Create factory & link skyweaver assets
* @param _firstOwner Address of the first owner
* @param _assetsAddr The address of the ERC-1155 Assets Token contract
*/
constructor(address _firstOwner, address _assetsAddr) TieredOwnable(_firstOwner) public {
require(
_assetsAddr != address(0),
"FreemintFactory#constructor: INVALID_INPUT"
);
skyweaverAssets = ISkyweaverAssets(_assetsAddr);
}
/***********************************|
| Minting Function |
|__________________________________*/
/**
* @notice Will mint a bundle of tokens to users
* @param _recipients Arrays of addresses to mint _amounts of _ids
* @param _ids Array of Tokens ID that are minted
* @param _amounts Amount of Tokens id minted for each corresponding Token id in _ids
*/
function batchMint(address[] calldata _recipients, uint256[] calldata _ids, uint256[] calldata _amounts)
external onlyOwnerTier(1)
{
for (uint256 i = 0 ; i < _recipients.length; i++) {
skyweaverAssets.batchMint(_recipients[i], _ids, _amounts, "");
}
}
/***********************************|
| Misc Functions |
|__________________________________*/
/**
* @notice Returns the address of the skyweaver assets contract
*/
function getSkyweaverAssets() external view returns (address) {
return address(skyweaverAssets);
}
/**
* @notice Prevents receiving Ether, ERC-1155 or calls to unsuported methods
*/
fallback () external {
revert("FreemintFactory#_: UNSUPPORTED_METHOD");
}
/**
* @notice Indicates whether a contract implements a given interface.
* @param interfaceID The ERC-165 interface ID that is queried for support.
* @return True if contract interface is supported.
*/
function supportsInterface(bytes4 interfaceID) external pure returns (bool) {
return interfaceID == type(IERC165).interfaceId;
}
}pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;
import "../utils/TieredOwnable.sol";
contract TieredOwnableMock is TieredOwnable {
constructor(address _firstOwner) TieredOwnable(_firstOwner) public {}
function onlyMaxTier() external onlyOwnerTier(HIGHEST_OWNER_TIER) returns(bool) {
return true;
}
function onlyTierFive() external onlyOwnerTier(5) returns(bool) {
return true;
}
function onlyTierZero() external onlyOwnerTier(0) returns(bool) {
return true;
}
function anyone() external returns(bool) {
return true;
}
}pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;
import "@0xsequence/erc-1155/contracts/mocks/ERC1155MintBurnMock.sol";
contract ERC1155Mock is ERC1155MintBurnMock {
constructor() ERC1155MintBurnMock('ERC1155Mock', "") {}
}pragma solidity 0.7.4;
pragma experimental ABIEncoderV2;
import "../utils/Ownable.sol";
contract OwnableMock is Ownable {
constructor(address _firstOwner) Ownable(_firstOwner) public {}
function call_onlyOwner() external onlyOwner() returns(bool) {
return true;
}
function call_anyone() external returns(bool) {
return true;
}
function call_throw() external returns(bool) {
revert(":/");
return true;
}
fallback() external {}
}{
"optimizer": {
"enabled": true,
"runs": 100000,
"details": {
"yul": true,
"constantOptimizer": false
}
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_firstOwner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_owner","type":"address"},{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":false,"internalType":"bool","name":"_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"}],"name":"FactoryActivation","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"}],"name":"FactoryShutdown","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"newMaxIssuances","type":"uint256[]"}],"name":"MaxIssuancesChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"},{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"indexed":false,"internalType":"struct SkyweaverAssets.AssetRange","name":"new_range","type":"tuple"}],"name":"MintPermissionAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"factory","type":"address"},{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"indexed":false,"internalType":"struct SkyweaverAssets.AssetRange","name":"deleted_range","type":"tuple"}],"name":"MintPermissionRemoved","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":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"indexed":false,"internalType":"struct SkyweaverAssets.AssetRange","name":"locked_range","type":"tuple"}],"name":"RangeLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_operator","type":"address"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"address","name":"_to","type":"address"},{"indexed":false,"internalType":"uint256","name":"_id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"_uri","type":"string"},{"indexed":true,"internalType":"uint256","name":"_id","type":"uint256"}],"name":"URI","type":"event"},{"stateMutability":"nonpayable","type":"fallback"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"activateFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"uint64","name":"_minRange","type":"uint64"},{"internalType":"uint64","name":"_maxRange","type":"uint64"},{"internalType":"uint64","name":"_startTime","type":"uint64"},{"internalType":"uint64","name":"_endTime","type":"uint64"}],"name":"addMintPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_owners","type":"address[]"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"batchBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"batchMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"getCurrentIssuances","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"getFactoryAccessRanges","outputs":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"internalType":"struct SkyweaverAssets.AssetRange[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"getFactoryStatus","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"getIDBinIndex","outputs":[{"internalType":"uint256","name":"bin","type":"uint256"},{"internalType":"uint256","name":"index","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getLockedRanges","outputs":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"internalType":"struct SkyweaverAssets.AssetRange[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"}],"name":"getMaxIssuances","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_binValues","type":"uint256"},{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getValueInBin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"globalRoyaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"feeBasisPoints","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isOperator","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint64","name":"minID","type":"uint64"},{"internalType":"uint64","name":"maxID","type":"uint64"},{"internalType":"uint64","name":"startTime","type":"uint64"},{"internalType":"uint64","name":"endTime","type":"uint64"}],"internalType":"struct SkyweaverAssets.AssetRange","name":"_range","type":"tuple"}],"name":"lockRangeMintPermissions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIDs","type":"uint256[]"}],"name":"logURIs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"},{"internalType":"uint256","name":"_rangeIndex","type":"uint256"}],"name":"removeMintPermission","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"_saleCost","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"bool","name":"_approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseMetadataURI","type":"string"}],"name":"setBaseMetadataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_receiver","type":"address"},{"internalType":"uint256","name":"_royaltyBasisPoints","type":"uint256"}],"name":"setGlobalRoyaltyInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_newMaxIssuances","type":"uint256[]"}],"name":"setMaxIssuances","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factory","type":"address"}],"name":"shutdownFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"_interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]Contract Creation Code
0x60806040523480156200001157600080fd5b50604051620052dc380380620052dc8339810160408190526200003491620001c7565b604080518082018252600981527f536b797765617665720000000000000000000000000000000000000000000000602080830191825283519081019093526000835281518493916200008a91600391906200011b565b508051620000a09060029060208401906200011b565b5050600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040519091506000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3505062000204565b828054600181600116156101000203166002900490600052602060002090601f0160209004810192826200015357600085556200019e565b82601f106200016e57805160ff19168380011785556200019e565b828001600101855582156200019e579182015b828111156200019e57825182559160200191906001019062000181565b50620001ac929150620001b0565b5090565b5b80821115620001ac5760008155600101620001b1565b600060208284031215620001d9578081fd5b815173ffffffffffffffffffffffffffffffffffffffff81168114620001fd578182fd5b9392505050565b6150c880620002146000396000f3fe608060405234801561001057600080fd5b50600436106102255760003560e01c80639136ce1f1161012a578063d46c069e116100bd578063e985e9c51161008c578063f242432a11610071578063f242432a146104eb578063f2fde38b146104fe578063f795ab751461051157610225565b8063e985e9c5146104c5578063eaec5f81146104d857610225565b8063d46c069e1461046b578063db90e83c1461047e578063e1a972721461049f578063e4b37d33146104b257610225565b8063adccc471116100f9578063adccc4711461042a578063b390c0ab1461043d578063b48ab8b614610450578063c9823cc61461046357610225565b80639136ce1f146103de57806393cfa682146103f1578063a22cb46514610404578063a36b3f291461041757610225565b80632eb2c2d6116101bd5780636c0360eb1161018c5780637c44a8bb116101715780637c44a8bb146103a35780637e518ec8146103b6578063893d20e8146103c957610225565b80636c0360eb14610388578063731133e91461039057610225565b80632eb2c2d61461032d578063458d2844146103405780634e1273f414610353578063657afa891461037357610225565b80630e89341c116101f95780630e89341c146102d357806315a08ab8146102e657806320ec271b146102f95780632a55205a1461030c57610225565b8062fdd58e1461026057806301ffc9a71461028957806306fdde03146102a957806307800c9b146102be575b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610257906148ce565b60405180910390fd5b61027361026e366004614298565b610524565b6040516102809190614c7e565b60405180910390f35b61029c6102973660046144f5565b61057b565b6040516102809190614798565b6102b161058e565b60405161028091906147a3565b6102d16102cc366004614327565b61063a565b005b6102b16102e13660046145df565b610a0f565b6102d16102f436600461448c565b610b62565b6102d161030736600461448c565b610d3c565b61031f61031a3660046145f7565b610db0565b6040516102809291906146ba565b6102d161033b3660046140c0565b610e12565b6102d161034e366004614298565b610f1d565b61036661036136600461438b565b611312565b6040516102809190614760565b61037b611591565b60405161028091906146e0565b6102b161164c565b6102d161039e3660046142c1565b6116c2565b6102d16103b1366004614074565b611790565b6102d16103c4366004614535565b611855565b6103d16118e9565b6040516102809190614699565b6102d16103ec366004614074565b611905565b6102d16103ff366004614298565b6119cd565b6102d161041236600461425e565b611a28565b61037b610425366004614074565b611ac1565b6102d1610438366004614569565b611b9f565b6102d161044b3660046145f7565b611d57565b6102d161045e3660046141c9565b611d62565b61031f611d78565b6102d161047936600461444c565b611d9a565b61049161048c3660046145df565b611e27565b604051610280929190614c87565b6103666104ad36600461444c565b611e34565b6103666104c036600461444c565b611ed5565b61029c6104d336600461408e565b611f6d565b6102736104e63660046145f7565b611fa8565b6102d16104f9366004614166565b611fbb565b6102d161050c366004614074565b6120bf565b61029c61051f366004614074565b6121d2565b600080600061053284611e27565b73ffffffffffffffffffffffffffffffffffffffff871660009081526020818152604080832085845290915290205491935091506105709082611fa8565b925050505b92915050565b6000610586826121fd565b90505b919050565b6003805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156106325780601f1061060757610100808354040283529160200191610632565b820191906000526020600020905b81548152906001019060200180831161061557829003601f168201915b505050505081565b60065473ffffffffffffffffffffffffffffffffffffffff16331461068b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b60008367ffffffffffffffff16116106cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614a79565b8267ffffffffffffffff168467ffffffffffffffff16111561071d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614905565b8067ffffffffffffffff168267ffffffffffffffff161061076a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614b33565b60005b6009548110156108705761077f613de4565b6009828154811061078c57fe5b600091825260209182902060408051608081018252919092015467ffffffffffffffff8082168084526801000000000000000083048216958401959095527001000000000000000000000000000000008204811693830193909352780100000000000000000000000000000000000000000000000090048216606082015292508616108061083157508567ffffffffffffffff16816020015167ffffffffffffffff16105b610867576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614a1c565b5060010161076d565b50610879613de4565b506040805160808101825267ffffffffffffffff808716825285811660208084019182528683168486019081528684166060860190815273ffffffffffffffffffffffffffffffffffffffff8c166000818152600885528881208054600181018255908252949020875194018054955193519251871678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff938816700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff95891668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff979099167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009098169790971795909516969096179290921693909317929092161790915591519091907f188968bccf857d854c73494ca4da4cc4ae2769e4b732db8f40dfa62b86b1c40a906109ff908490614c70565b60405180910390a2505050505050565b60606002610a1c8361225a565b6040516020018083805460018160011615610100020316600290048015610a7a5780601f10610a58576101008083540402835291820191610a7a565b820191906000526020600020905b815481529060010190602001808311610a66575b5050825160208401908083835b60208310610ac457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a87565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990911692169190911790527f2e6a736f6e000000000000000000000000000000000000000000000000000000920191825250604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe50181526005909201905295945050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b828114610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614871565b60005b83811015610cf8576000600b6000878785818110610c0957fe5b905060200201358152602001908152602001600020541115610cb357828282818110610c3157fe5b905060200201356000108015610c7d5750600b6000868684818110610c5257fe5b90506020020135815260200190815260200160002054838383818110610c7457fe5b90506020020135105b610cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614ad6565b828282818110610cbf57fe5b90506020020135600b6000878785818110610cd657fe5b6020908102929092013583525081019190915260400160002055600101610bef565b507f91f9ea1e3a6a1fd246959c27978a42e04c0c3c954e7ffa52e3ed1509be4811be84848484604051610d2e949392919061472e565b60405180910390a150505050565b610daa338585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080890282810182019093528882529093508892508791829185019084908082843760009201919091525061238692505050565b50505050565b600080610dbb613e0b565b506040805180820190915260045473ffffffffffffffffffffffffffffffffffffffff1680825260055460208301819052610e05906103e890610dff90889061252f565b906125bf565b92509250505b9250929050565b3373ffffffffffffffffffffffffffffffffffffffff86161480610e3b5750610e3b8533611f6d565b610e90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180614e46603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8416610efc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180614d11603d913960400191505060405180910390fd5b610f0885858585612643565b610f16858585855a86612a50565b5050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610f6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600860205260409020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610fbe613de4565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600860205260409020805484908110610fef57fe5b600091825260209182902060408051608081018252929091015467ffffffffffffffff8082168452680100000000000000008204811694840194909452700100000000000000000000000000000000810484169183019190915278010000000000000000000000000000000000000000000000009004909116606082015290508183146112585761107e613de4565b73ffffffffffffffffffffffffffffffffffffffff851660009081526008602052604090208054849081106110af57fe5b6000918252602080832060408051608081018252919093015467ffffffffffffffff80821683526801000000000000000082048116838501527001000000000000000000000000000000008204811683860152780100000000000000000000000000000000000000000000000090910416606082015273ffffffffffffffffffffffffffffffffffffffff8916845260089091529120805491925082918690811061115657fe5b60009182526020918290208351910180549284015160408501516060909501517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090941667ffffffffffffffff938416177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000091841691909102177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000948316949094029390931777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009190921602179055505b73ffffffffffffffffffffffffffffffffffffffff8416600090815260086020526040902080548061128657fe5b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081019190915501905560405173ffffffffffffffffffffffffffffffffffffffff8516907f1bca5c143feb87c2d4e8d2d1fd73ba6f43f551ba73c58634f56bbe30701f06d490611304908490614c70565b60405180910390a250505050565b81518151606091908114611371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614cd86039913960400191505060405180910390fd5b6000806113918560008151811061138457fe5b6020026020010151611e27565b915091506000806000886000815181106113a757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020549050600083905060608567ffffffffffffffff8111801561141b57600080fd5b50604051908082528060200260200182016040528015611445578160200160208202803683370190505b5090506114528385611fa8565b8160008151811061145f57fe5b602090810291909101015260015b868110156115845761148489828151811061138457fe5b909650945082861415806114ed575089818151811061149f57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168a60018303815181106114cc57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614155b1561155b576000808b838151811061150157fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008781526020019081526020016000205493508592505b6115658486611fa8565b82828151811061157157fe5b602090810291909101015260010161146d565b5098975050505050505050565b60606009805480602002602001604051908101604052809291908181526020016000905b82821015611643576000848152602090819020604080516080810182529185015467ffffffffffffffff80821684526801000000000000000082048116848601527001000000000000000000000000000000008204811692840192909252780100000000000000000000000000000000000000000000000090041660608201528252600190920191016115b5565b50505050905090565b600280546040805160206001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909316849004601f810184900484028201840190925281815292918301828280156106325780601f1061060757610100808354040283529160200191610632565b604080516001808252818301909252606091602080830190803683375050604080516001808252818301909252929350606092915060208083019080368337019050509050858260008151811061171557fe5b602002602001018181525050848160008151811061172f57fe5b6020026020010181815250506117458282612cc5565b61178787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612fc192505050565b50505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff1633146117e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f472ecaf428225ecdcc1f686a662ed1ba0627c365542e086b483bacca0fcfa5f99190a250565b60065473ffffffffffffffffffffffffffffffffffffffff1633146118a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e582828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061303592505050565b5050565b60065473ffffffffffffffffffffffffffffffffffffffff1690565b60065473ffffffffffffffffffffffffffffffffffffffff163314611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f672dbf7f8dabd5b1b39124540440a9ef2537a03c053f111f7e90850e57e2efb69190a250565b60065473ffffffffffffffffffffffffffffffffffffffff163314611a1e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e58282613048565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600860209081526040808320805482518185028101850190935280835260609492939192909184015b82821015611b94576000848152602090819020604080516080810182529185015467ffffffffffffffff8082168452680100000000000000008204811684860152700100000000000000000000000000000000820481169284019290925278010000000000000000000000000000000000000000000000009004166060820152825260019092019101611b06565b505050509050919050565b60065473ffffffffffffffffffffffffffffffffffffffff163314611bf0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6009805460018101825560009190915281517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af9091018054602084015160408086015160608701517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090941667ffffffffffffffff968716177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000093871693909302929092177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000928616929092029190911777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490921693909302179055517f522c18973f048c2a178766b76cb19456e9dbd776f104c0b77c6166e582212f2c90611d4c908390614c70565b60405180910390a150565b6118e533838361315a565b611d6c8383612cc5565b610daa848484846131c4565b60045460055473ffffffffffffffffffffffffffffffffffffffff9091169082565b60065473ffffffffffffffffffffffffffffffffffffffff163314611deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e582828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061344e92505050565b6008810491600790911690565b606081818167ffffffffffffffff81118015611e4f57600080fd5b50604051908082528060200260200182016040528015611e79578160200160208202803683370190505b50905060005b82811015611ecc57600b6000878784818110611e9757fe5b90506020020135815260200190815260200160002054828281518110611eb957fe5b6020908102919091010152600101611e7f565b50949350505050565b606081818167ffffffffffffffff81118015611ef057600080fd5b50604051908082528060200260200182016040528015611f1a578160200160208202803683370190505b50905060005b82811015611ecc57600a6000878784818110611f3857fe5b90506020020135815260200190815260200160002054828281518110611f5a57fe5b6020908102919091010152600101611f20565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205460ff1690565b6020810282901c63ffffffff1692915050565b3373ffffffffffffffffffffffffffffffffffffffff86161480611fe45750611fe48533611f6d565b612039576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180614d816037913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166120a5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180614fa66038913960400191505060405180910390fd5b6120b18585858561370f565b610f16858585855a866137b3565b60065473ffffffffffffffffffffffffffffffffffffffff163314612110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811661215d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610257906149bf565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821792839055604051919216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a00000000000000000000000000000000000000000000000000000000141561225157506001610589565b610586826139a4565b60608161229b575060408051808201909152600181527f30000000000000000000000000000000000000000000000000000000000000006020820152610589565b818060005b82156122b457600101600a830492506122a0565b60608167ffffffffffffffff811180156122cd57600080fd5b506040519080825280601f01601f1916602001820160405280156122f8576020820181803683370190505b5090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015b831561237c57600a840660300160f81b8282806001900393508151811061234257fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8404935061231f565b5095945050505050565b8151815181146123e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180614eb3603d913960400191505060405180910390fd5b60005b818110156124275761241f858583815181106123fc57fe5b602002602001015185848151811061241057fe5b60200260200101516001613a01565b6001016123e4565b50600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156124d55781810151838201526020016124bd565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156125145781810151838201526020016124fc565b5050505090500194505050505060405180910390a450505050565b60008261253e57506000610575565b8282028284828161254b57fe5b04146125b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536166654d617468236d756c3a204f564552464c4f5700000000000000000000604482015290519081900360640190fd5b9392505050565b600080821161262f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d617468236469763a204449564953494f4e5f42595f5a45524f0000604482015290519081900360640190fd5b600082848161263a57fe5b04949350505050565b81518151811461269e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526042815260200180614db86042913960600191505060405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141580156126da5750600081115b156128ac576000806126f28560008151811061138457fe5b73ffffffffffffffffffffffffffffffffffffffff891660009081526020818152604080832085845290915281205487519395509193509161274a919084908890859061273b57fe5b60200260200101516001613a88565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208181526040808320878452909152812054875192935090916127a0919085908990859061279157fe5b60200260200101516000613a88565b90508360015b8681101561285a576127bd89828151811061138457fe5b909650945081861461282c5773ffffffffffffffffffffffffffffffffffffffff8b811660009081526020818152604080832086845280835281842098909855928d16825281815282822094825284815282822095909555878152948452808520549290935291909220549084905b61283d84868a848151811061273b57fe5b935061285083868a848151811061279157fe5b92506001016127a6565b505073ffffffffffffffffffffffffffffffffffffffff808a16600090815260208181526040808320888452825280832095909555918a16815280825283812095815294905292209190915550612949565b60005b81811015612947578281815181106128c357fe5b60200260200101516128e8878684815181106128db57fe5b6020026020010151610524565b101561293f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180614ef06036913960400191505060405180910390fd5b6001016128af565b505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156129f55781810151838201526020016129dd565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612a34578181015183820152602001612a1c565b5050505090500194505050505060405180910390a45050505050565b612a6f8573ffffffffffffffffffffffffffffffffffffffff16613c9b565b15612cbd5760008573ffffffffffffffffffffffffffffffffffffffff1663bc197c8184338a8989886040518763ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b83811015612b27578181015183820152602001612b0f565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015612b66578181015183820152602001612b4e565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015612ba2578181015183820152602001612b8a565b50505050905090810190601f168015612bcf5780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600088803b158015612bf457600080fd5b5087f1158015612c08573d6000803e3d6000fd5b50505050506040513d6020811015612c1f57600080fd5b505190507fffffffff0000000000000000000000000000000000000000000000000000000081167fbc197c810000000000000000000000000000000000000000000000000000000014611787576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604c815260200180614dfa604c913960600191505060405180910390fd5b505050505050565b3360009081526007602052604090205460ff16612d0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614814565b33600090815260086020526040902054612d26613de4565b3360009081526008602052604081208054909190612d4057fe5b6000918252602080832060408051608081018252939091015467ffffffffffffffff80821685526801000000000000000082048116938501939093527001000000000000000000000000000000008104831691840191909152780100000000000000000000000000000000000000000000000090041660608201529150805b8551811015612cbd576000868281518110612dd657fe5b602002602001015190506000868381518110612dee57fe5b602002602001015190506000600b60008481526020019081526020016000205490505b856040015167ffffffffffffffff16421080612e3a5750856060015167ffffffffffffffff1642115b80612e4f5750855167ffffffffffffffff1683105b80612e67575082866020015167ffffffffffffffff16105b15612f4b57600185019450868510612eab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614962565b336000908152600860205260409020805486908110612ec657fe5b600091825260209182902060408051608081018252929091015467ffffffffffffffff808216845268010000000000000000820481169484019490945270010000000000000000000000000000000081048416918301919091527801000000000000000000000000000000000000000000000000900490911660608201529550612e11565b8015612fb6576000838152600a6020526040812054612f6a9084613cd2565b905081811115612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614c13565b6000848152600a60205260409020555b505050600101612dbf565b612fce8484846000613a01565b6040805184815260208101849052815173ffffffffffffffffffffffffffffffffffffffff87169260009233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62929181900390910190a4610daa60008585855a866137b3565b80516118e5906002906020840190613e22565b73ffffffffffffffffffffffffffffffffffffffff82166130b4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614e826031913960400191505060405180910390fd5b6103e881111561310f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614f266039913960400191505060405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9390931692909217909155600555565b6131678383836001613a01565b6040805183815260208101839052815160009273ffffffffffffffffffffffffffffffffffffffff87169233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62929181900390910190a4505050565b815183511461321e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180615023603e913960400191505060405180910390fd5b82511561333e576000806132388560008151811061138457fe5b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208181526040808320858452909152812054875193955091935091613281919084908890859061279157fe5b86519091508360015b82811015613305576132a189828151811061138457fe5b90965094508186146132ea5773ffffffffffffffffffffffffffffffffffffffff8a16600090815260208181526040808320948352939052828120949094558584529220549184905b6132fb84868a848151811061279157fe5b935060010161328a565b50505073ffffffffffffffffffffffffffffffffffffffff87166000908152602081815260408083209583529490529290922091909155505b8373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156133eb5781810151838201526020016133d3565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561342a578181015183820152602001613412565b5050505090500194505050505060405180910390a4610daa60008585855a86612a50565b60028054604080516020601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156134f55780601f106134ca576101008083540402835291602001916134f5565b820191906000526020600020905b8154815290600101906020018083116134d857829003601f168201915b50505050509050606060005b8351811015610daa578261352785838151811061351a57fe5b602002602001015161225a565b6040516020018083805190602001908083835b6020831061357757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161353a565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905285519190930192850191508083835b602083106135fb57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016135be565b6001836020036101000a038019825116818451168082178552505050505050905001807f2e6a736f6e00000000000000000000000000000000000000000000000000000081525060050192505050604051602081830303815290604052915083818151811061366657fe5b60200260200101517f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b836040518080602001828103825283818151815260200191508051906020019080838360005b838110156136cd5781810151838201526020016136b5565b50505050905090810190601f1680156136fa5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2600101613501565b61371c8483836001613a01565b6137298383836000613a01565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051808381526020018281526020019250505060405180910390a450505050565b6137d28573ffffffffffffffffffffffffffffffffffffffff16613c9b565b15612cbd5760008573ffffffffffffffffffffffffffffffffffffffff1663f23a6e6184338a8989886040518763ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561388b578181015183820152602001613873565b50505050905090810190601f1680156138b85780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600088803b1580156138db57600080fd5b5087f11580156138ef573d6000803e3d6000fd5b50505050506040513d602081101561390657600080fd5b505190507fffffffff0000000000000000000000000000000000000000000000000000000081167ff23a6e610000000000000000000000000000000000000000000000000000000014611787576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526047815260200180614f5f6047913960600191505060405180910390fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f0e89341c0000000000000000000000000000000000000000000000000000000014156139f857506001610589565b61058682613d46565b600080613a0d85611e27565b73ffffffffffffffffffffffffffffffffffffffff88166000908152602081815260408083208584529091529020549193509150613a4d90828686613a88565b73ffffffffffffffffffffffffffffffffffffffff909616600090815260208181526040808320948352939052919091209490945550505050565b60006020840263ffffffff82846001811115613aa057fe5b1415613b6e5784821b8701925086831015613b06576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806150616032913960400191505060405180910390fd5b64010000000087831c8216860110613b69576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806150616032913960400191505060405180910390fd5b613c91565b6001846001811115613b7c57fe5b1415613c405784821b8703925086831115613be2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180614d4e6033913960400191505060405180910390fd5b84818389901c161015613b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180614d4e6033913960400191505060405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526045815260200180614fde6045913960600191505060405180910390fd5b5050949350505050565b6000813f80158015906125b857507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470141592915050565b6000828201838110156125b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536166654d617468236164643a204f564552464c4f5700000000000000000000604482015290519081900360640190fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a26000000000000000000000000000000000000000000000000000000001415613d9a57506001610589565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610586565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604080518082019091526000808252602082015290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282613e585760008555613e9e565b82601f10613e7157805160ff1916838001178555613e9e565b82800160010185558215613e9e579182015b82811115613e9e578251825591602001919060010190613e83565b50613eaa929150613eae565b5090565b5b80821115613eaa5760008155600101613eaf565b803573ffffffffffffffffffffffffffffffffffffffff8116811461058957600080fd5b60008083601f840112613ef8578081fd5b50813567ffffffffffffffff811115613f0f578182fd5b6020830191508360208083028501011115610e0b57600080fd5b600082601f830112613f39578081fd5b8135613f4c613f4782614cb9565b614c95565b818152915060208083019084810181840286018201871015613f6d57600080fd5b60005b84811015613f8c57813584529282019290820190600101613f70565b505050505092915050565b60008083601f840112613fa8578182fd5b50813567ffffffffffffffff811115613fbf578182fd5b602083019150836020828501011115610e0b57600080fd5b600082601f830112613fe7578081fd5b813567ffffffffffffffff811115613ffb57fe5b61402c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614c95565b915080825283602082850101111561404357600080fd5b8060208401602084013760009082016020015292915050565b803567ffffffffffffffff8116811461058957600080fd5b600060208284031215614085578081fd5b6125b882613ec3565b600080604083850312156140a0578081fd5b6140a983613ec3565b91506140b760208401613ec3565b90509250929050565b600080600080600060a086880312156140d7578081fd5b6140e086613ec3565b94506140ee60208701613ec3565b9350604086013567ffffffffffffffff8082111561410a578283fd5b61411689838a01613f29565b9450606088013591508082111561412b578283fd5b61413789838a01613f29565b9350608088013591508082111561414c578283fd5b5061415988828901613fd7565b9150509295509295909350565b600080600080600060a0868803121561417d578081fd5b61418686613ec3565b945061419460208701613ec3565b93506040860135925060608601359150608086013567ffffffffffffffff8111156141bd578182fd5b61415988828901613fd7565b600080600080608085870312156141de578384fd5b6141e785613ec3565b9350602085013567ffffffffffffffff80821115614203578485fd5b61420f88838901613f29565b94506040870135915080821115614224578384fd5b61423088838901613f29565b93506060870135915080821115614245578283fd5b5061425287828801613fd7565b91505092959194509250565b60008060408385031215614270578182fd5b61427983613ec3565b91506020830135801515811461428d578182fd5b809150509250929050565b600080604083850312156142aa578182fd5b6142b383613ec3565b946020939093013593505050565b6000806000806000608086880312156142d8578283fd5b6142e186613ec3565b94506020860135935060408601359250606086013567ffffffffffffffff81111561430a578182fd5b61431688828901613f97565b969995985093965092949392505050565b600080600080600060a0868803121561433e578283fd5b61434786613ec3565b94506143556020870161405c565b93506143636040870161405c565b92506143716060870161405c565b915061437f6080870161405c565b90509295509295909350565b6000806040838503121561439d578182fd5b823567ffffffffffffffff808211156143b4578384fd5b818501915085601f8301126143c7578384fd5b81356143d5613f4782614cb9565b80828252602080830192508086018a8283870289010111156143f5578889fd5b8896505b8487101561441e5761440a81613ec3565b8452600196909601959281019281016143f9565b509096508701359350505080821115614435578283fd5b5061444285828601613f29565b9150509250929050565b6000806020838503121561445e578182fd5b823567ffffffffffffffff811115614474578283fd5b61448085828601613ee7565b90969095509350505050565b600080600080604085870312156144a1578182fd5b843567ffffffffffffffff808211156144b8578384fd5b6144c488838901613ee7565b909650945060208701359150808211156144dc578384fd5b506144e987828801613ee7565b95989497509550505050565b600060208284031215614506578081fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146125b8578182fd5b60008060208385031215614547578182fd5b823567ffffffffffffffff81111561455d578283fd5b61448085828601613f97565b60006080828403121561457a578081fd5b6040516080810181811067ffffffffffffffff8211171561459757fe5b6040526145a38361405c565b81526145b16020840161405c565b60208201526145c26040840161405c565b60408201526145d36060840161405c565b60608201529392505050565b6000602082840312156145f0578081fd5b5035919050565b60008060408385031215614609578182fd5b50508035926020909101359150565b60008284527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115614649578081fd5b6020830280836020870137939093016020019283525090919050565b805167ffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156147225761470f838551614665565b92840192608092909201916001016146fc565b50909695505050505050565b600060408252614742604083018688614618565b8281036020840152614755818587614618565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156147225783518352928401929184019160010161477c565b901515815260200190565b6000602080835283518082850152825b818110156147cf578581018301518582016040015282016147b3565b818111156147e05783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60208082526032908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f464143544f52595f4e4f545f4143544956450000000000000000000000000000606082015260800190565b60208082526036908201527f536b79776561766572417373657473237365744d617849737375616e6365733a60408201527f20494e56414c49445f4152524159535f4c454e47544800000000000000000000606082015260800190565b60208082526012908201527f554e535550504f525445445f4d4554484f440000000000000000000000000000604082015260600190565b60208082526030908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a20494e56414c49445f52414e474500000000000000000000000000000000606082015260800190565b6020808252602f908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f49445f4f55545f4f465f52414e47450000000000000000000000000000000000606082015260800190565b6020808252602a908201527f4f776e61626c65237472616e736665724f776e6572736869703a20494e56414c60408201527f49445f4144445245535300000000000000000000000000000000000000000000606082015260800190565b6020808252603c908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a204f5645524c41505f574954485f4c4f434b45445f52414e474500000000606082015260800190565b6020808252602d908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a204e554c4c5f52414e474500000000000000000000000000000000000000606082015260800190565b60208082526039908201527f536b79776561766572417373657473237365744d617849737375616e6365733a60408201527f20494e56414c49445f4e45575f4d41585f49535355414e434500000000000000606082015260800190565b60208082526049908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a2053544152545f54494d455f49535f4e4f545f4c45535345525f5448454e60608201527f5f454e445f54494d450000000000000000000000000000000000000000000000608082015260a00190565b60208082526026908201527f4f776e61626c65236f6e6c794f776e65723a2053454e4445525f49535f4e4f5460408201527f5f4f574e45520000000000000000000000000000000000000000000000000000606082015260800190565b60208082526035908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f4d41585f49535355414e43455f45584345454445440000000000000000000000606082015260800190565b608081016105758284614665565b90815260200190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715614cb157fe5b604052919050565b600067ffffffffffffffff821115614ccd57fe5b506020908102019056fe455243313135355061636b656442616c616e63652362616c616e63654f6642617463683a20494e56414c49445f41525241595f4c454e475448455243313135355061636b656442616c616e6365237361666542617463685472616e7366657246726f6d3a20494e56414c49445f524543495049454e54455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a20554e444552464c4f57455243313135355061636b656442616c616e636523736166655472616e7366657246726f6d3a20494e56414c49445f4f50455241544f52455243313135355061636b656442616c616e6365235f7361666542617463685472616e7366657246726f6d3a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f63616c6c6f6e45524331313535426174636852656365697665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745455243313135355061636b656442616c616e6365237361666542617463685472616e7366657246726f6d3a20494e56414c49445f4f50455241544f5245524332393831476c6f62616c235f736574476c6f62616c526f79616c74793a20524543495049454e545f49535f307830455243313135354d696e744275726e5061636b656442616c616e63652362617463684275726e3a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f7361666542617463685472616e7366657246726f6d3a20554e444552464c4f5745524332393831476c6f62616c235f736574476c6f62616c526f79616c74793a204645455f49535f41424f56455f3130305f50455243454e54455243313135355061636b656442616c616e6365235f63616c6c6f6e4552433131353552656365697665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745455243313135355061636b656442616c616e636523736166655472616e7366657246726f6d3a20494e56414c49445f524543495049454e54455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a20494e56414c49445f42494e5f57524954455f4f5045524154494f4e455243313135354d696e744275726e5061636b656442616c616e6365235f62617463684d696e743a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a204f564552464c4f57a2646970667358221220fb1372790e40e3e548bbc115377592682a7efd66fc87555aa190c17a7e2027e864736f6c63430007040033000000000000000000000000ec32359f21cf24e7d5097813577ee1f2c22fa57b
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102255760003560e01c80639136ce1f1161012a578063d46c069e116100bd578063e985e9c51161008c578063f242432a11610071578063f242432a146104eb578063f2fde38b146104fe578063f795ab751461051157610225565b8063e985e9c5146104c5578063eaec5f81146104d857610225565b8063d46c069e1461046b578063db90e83c1461047e578063e1a972721461049f578063e4b37d33146104b257610225565b8063adccc471116100f9578063adccc4711461042a578063b390c0ab1461043d578063b48ab8b614610450578063c9823cc61461046357610225565b80639136ce1f146103de57806393cfa682146103f1578063a22cb46514610404578063a36b3f291461041757610225565b80632eb2c2d6116101bd5780636c0360eb1161018c5780637c44a8bb116101715780637c44a8bb146103a35780637e518ec8146103b6578063893d20e8146103c957610225565b80636c0360eb14610388578063731133e91461039057610225565b80632eb2c2d61461032d578063458d2844146103405780634e1273f414610353578063657afa891461037357610225565b80630e89341c116101f95780630e89341c146102d357806315a08ab8146102e657806320ec271b146102f95780632a55205a1461030c57610225565b8062fdd58e1461026057806301ffc9a71461028957806306fdde03146102a957806307800c9b146102be575b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610257906148ce565b60405180910390fd5b61027361026e366004614298565b610524565b6040516102809190614c7e565b60405180910390f35b61029c6102973660046144f5565b61057b565b6040516102809190614798565b6102b161058e565b60405161028091906147a3565b6102d16102cc366004614327565b61063a565b005b6102b16102e13660046145df565b610a0f565b6102d16102f436600461448c565b610b62565b6102d161030736600461448c565b610d3c565b61031f61031a3660046145f7565b610db0565b6040516102809291906146ba565b6102d161033b3660046140c0565b610e12565b6102d161034e366004614298565b610f1d565b61036661036136600461438b565b611312565b6040516102809190614760565b61037b611591565b60405161028091906146e0565b6102b161164c565b6102d161039e3660046142c1565b6116c2565b6102d16103b1366004614074565b611790565b6102d16103c4366004614535565b611855565b6103d16118e9565b6040516102809190614699565b6102d16103ec366004614074565b611905565b6102d16103ff366004614298565b6119cd565b6102d161041236600461425e565b611a28565b61037b610425366004614074565b611ac1565b6102d1610438366004614569565b611b9f565b6102d161044b3660046145f7565b611d57565b6102d161045e3660046141c9565b611d62565b61031f611d78565b6102d161047936600461444c565b611d9a565b61049161048c3660046145df565b611e27565b604051610280929190614c87565b6103666104ad36600461444c565b611e34565b6103666104c036600461444c565b611ed5565b61029c6104d336600461408e565b611f6d565b6102736104e63660046145f7565b611fa8565b6102d16104f9366004614166565b611fbb565b6102d161050c366004614074565b6120bf565b61029c61051f366004614074565b6121d2565b600080600061053284611e27565b73ffffffffffffffffffffffffffffffffffffffff871660009081526020818152604080832085845290915290205491935091506105709082611fa8565b925050505b92915050565b6000610586826121fd565b90505b919050565b6003805460408051602060026001851615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190941693909304601f810184900484028201840190925281815292918301828280156106325780601f1061060757610100808354040283529160200191610632565b820191906000526020600020905b81548152906001019060200180831161061557829003601f168201915b505050505081565b60065473ffffffffffffffffffffffffffffffffffffffff16331461068b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b60008367ffffffffffffffff16116106cf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614a79565b8267ffffffffffffffff168467ffffffffffffffff16111561071d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614905565b8067ffffffffffffffff168267ffffffffffffffff161061076a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614b33565b60005b6009548110156108705761077f613de4565b6009828154811061078c57fe5b600091825260209182902060408051608081018252919092015467ffffffffffffffff8082168084526801000000000000000083048216958401959095527001000000000000000000000000000000008204811693830193909352780100000000000000000000000000000000000000000000000090048216606082015292508616108061083157508567ffffffffffffffff16816020015167ffffffffffffffff16105b610867576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614a1c565b5060010161076d565b50610879613de4565b506040805160808101825267ffffffffffffffff808716825285811660208084019182528683168486019081528684166060860190815273ffffffffffffffffffffffffffffffffffffffff8c166000818152600885528881208054600181018255908252949020875194018054955193519251871678010000000000000000000000000000000000000000000000000277ffffffffffffffffffffffffffffffffffffffffffffffff938816700100000000000000000000000000000000027fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff95891668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff979099167fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000009098169790971795909516969096179290921693909317929092161790915591519091907f188968bccf857d854c73494ca4da4cc4ae2769e4b732db8f40dfa62b86b1c40a906109ff908490614c70565b60405180910390a2505050505050565b60606002610a1c8361225a565b6040516020018083805460018160011615610100020316600290048015610a7a5780601f10610a58576101008083540402835291820191610a7a565b820191906000526020600020905b815481529060010190602001808311610a66575b5050825160208401908083835b60208310610ac457805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09092019160209182019101610a87565b5181516020939093036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01801990911692169190911790527f2e6a736f6e000000000000000000000000000000000000000000000000000000920191825250604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe50181526005909201905295945050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b828114610bec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614871565b60005b83811015610cf8576000600b6000878785818110610c0957fe5b905060200201358152602001908152602001600020541115610cb357828282818110610c3157fe5b905060200201356000108015610c7d5750600b6000868684818110610c5257fe5b90506020020135815260200190815260200160002054838383818110610c7457fe5b90506020020135105b610cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614ad6565b828282818110610cbf57fe5b90506020020135600b6000878785818110610cd657fe5b6020908102929092013583525081019190915260400160002055600101610bef565b507f91f9ea1e3a6a1fd246959c27978a42e04c0c3c954e7ffa52e3ed1509be4811be84848484604051610d2e949392919061472e565b60405180910390a150505050565b610daa338585808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152505060408051602080890282810182019093528882529093508892508791829185019084908082843760009201919091525061238692505050565b50505050565b600080610dbb613e0b565b506040805180820190915260045473ffffffffffffffffffffffffffffffffffffffff1680825260055460208301819052610e05906103e890610dff90889061252f565b906125bf565b92509250505b9250929050565b3373ffffffffffffffffffffffffffffffffffffffff86161480610e3b5750610e3b8533611f6d565b610e90576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603c815260200180614e46603c913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8416610efc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180614d11603d913960400191505060405180910390fd5b610f0885858585612643565b610f16858585855a86612a50565b5050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610f6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600860205260409020547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01610fbe613de4565b73ffffffffffffffffffffffffffffffffffffffff84166000908152600860205260409020805484908110610fef57fe5b600091825260209182902060408051608081018252929091015467ffffffffffffffff8082168452680100000000000000008204811694840194909452700100000000000000000000000000000000810484169183019190915278010000000000000000000000000000000000000000000000009004909116606082015290508183146112585761107e613de4565b73ffffffffffffffffffffffffffffffffffffffff851660009081526008602052604090208054849081106110af57fe5b6000918252602080832060408051608081018252919093015467ffffffffffffffff80821683526801000000000000000082048116838501527001000000000000000000000000000000008204811683860152780100000000000000000000000000000000000000000000000090910416606082015273ffffffffffffffffffffffffffffffffffffffff8916845260089091529120805491925082918690811061115657fe5b60009182526020918290208351910180549284015160408501516060909501517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090941667ffffffffffffffff938416177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000091841691909102177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000948316949094029390931777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009190921602179055505b73ffffffffffffffffffffffffffffffffffffffff8416600090815260086020526040902080548061128657fe5b60008281526020812082017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081019190915501905560405173ffffffffffffffffffffffffffffffffffffffff8516907f1bca5c143feb87c2d4e8d2d1fd73ba6f43f551ba73c58634f56bbe30701f06d490611304908490614c70565b60405180910390a250505050565b81518151606091908114611371576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614cd86039913960400191505060405180910390fd5b6000806113918560008151811061138457fe5b6020026020010151611e27565b915091506000806000886000815181106113a757fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000848152602001908152602001600020549050600083905060608567ffffffffffffffff8111801561141b57600080fd5b50604051908082528060200260200182016040528015611445578160200160208202803683370190505b5090506114528385611fa8565b8160008151811061145f57fe5b602090810291909101015260015b868110156115845761148489828151811061138457fe5b909650945082861415806114ed575089818151811061149f57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff168a60018303815181106114cc57fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1614155b1561155b576000808b838151811061150157fe5b602002602001015173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008781526020019081526020016000205493508592505b6115658486611fa8565b82828151811061157157fe5b602090810291909101015260010161146d565b5098975050505050505050565b60606009805480602002602001604051908101604052809291908181526020016000905b82821015611643576000848152602090819020604080516080810182529185015467ffffffffffffffff80821684526801000000000000000082048116848601527001000000000000000000000000000000008204811692840192909252780100000000000000000000000000000000000000000000000090041660608201528252600190920191016115b5565b50505050905090565b600280546040805160206001841615610100027fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01909316849004601f810184900484028201840190925281815292918301828280156106325780601f1061060757610100808354040283529160200191610632565b604080516001808252818301909252606091602080830190803683375050604080516001808252818301909252929350606092915060208083019080368337019050509050858260008151811061171557fe5b602002602001018181525050848160008151811061172f57fe5b6020026020010181815250506117458282612cc5565b61178787878787878080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250612fc192505050565b50505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff1633146117e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f472ecaf428225ecdcc1f686a662ed1ba0627c365542e086b483bacca0fcfa5f99190a250565b60065473ffffffffffffffffffffffffffffffffffffffff1633146118a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e582828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061303592505050565b5050565b60065473ffffffffffffffffffffffffffffffffffffffff1690565b60065473ffffffffffffffffffffffffffffffffffffffff163314611956576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811660008181526007602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f672dbf7f8dabd5b1b39124540440a9ef2537a03c053f111f7e90850e57e2efb69190a250565b60065473ffffffffffffffffffffffffffffffffffffffff163314611a1e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e58282613048565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016861515908117909155815190815290519293927f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31929181900390910190a35050565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600860209081526040808320805482518185028101850190935280835260609492939192909184015b82821015611b94576000848152602090819020604080516080810182529185015467ffffffffffffffff8082168452680100000000000000008204811684860152700100000000000000000000000000000000820481169284019290925278010000000000000000000000000000000000000000000000009004166060820152825260019092019101611b06565b505050509050919050565b60065473ffffffffffffffffffffffffffffffffffffffff163314611bf0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6009805460018101825560009190915281517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af9091018054602084015160408086015160608701517fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000090941667ffffffffffffffff968716177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000093871693909302929092177fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff16700100000000000000000000000000000000928616929092029190911777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009490921693909302179055517f522c18973f048c2a178766b76cb19456e9dbd776f104c0b77c6166e582212f2c90611d4c908390614c70565b60405180910390a150565b6118e533838361315a565b611d6c8383612cc5565b610daa848484846131c4565b60045460055473ffffffffffffffffffffffffffffffffffffffff9091169082565b60065473ffffffffffffffffffffffffffffffffffffffff163314611deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b6118e582828080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061344e92505050565b6008810491600790911690565b606081818167ffffffffffffffff81118015611e4f57600080fd5b50604051908082528060200260200182016040528015611e79578160200160208202803683370190505b50905060005b82811015611ecc57600b6000878784818110611e9757fe5b90506020020135815260200190815260200160002054828281518110611eb957fe5b6020908102919091010152600101611e7f565b50949350505050565b606081818167ffffffffffffffff81118015611ef057600080fd5b50604051908082528060200260200182016040528015611f1a578160200160208202803683370190505b50905060005b82811015611ecc57600a6000878784818110611f3857fe5b90506020020135815260200190815260200160002054828281518110611f5a57fe5b6020908102919091010152600101611f20565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205460ff1690565b6020810282901c63ffffffff1692915050565b3373ffffffffffffffffffffffffffffffffffffffff86161480611fe45750611fe48533611f6d565b612039576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526037815260200180614d816037913960400191505060405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff84166120a5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180614fa66038913960400191505060405180910390fd5b6120b18585858561370f565b610f16858585855a866137b3565b60065473ffffffffffffffffffffffffffffffffffffffff163314612110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614bb6565b73ffffffffffffffffffffffffffffffffffffffff811661215d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610257906149bf565b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83811691821792839055604051919216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b73ffffffffffffffffffffffffffffffffffffffff1660009081526007602052604090205460ff1690565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a00000000000000000000000000000000000000000000000000000000141561225157506001610589565b610586826139a4565b60608161229b575060408051808201909152600181527f30000000000000000000000000000000000000000000000000000000000000006020820152610589565b818060005b82156122b457600101600a830492506122a0565b60608167ffffffffffffffff811180156122cd57600080fd5b506040519080825280601f01601f1916602001820160405280156122f8576020820181803683370190505b5090507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82015b831561237c57600a840660300160f81b8282806001900393508151811061234257fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8404935061231f565b5095945050505050565b8151815181146123e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603d815260200180614eb3603d913960400191505060405180910390fd5b60005b818110156124275761241f858583815181106123fc57fe5b602002602001015185848151811061241057fe5b60200260200101516001613a01565b6001016123e4565b50600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156124d55781810151838201526020016124bd565b50505050905001838103825284818151815260200191508051906020019060200280838360005b838110156125145781810151838201526020016124fc565b5050505090500194505050505060405180910390a450505050565b60008261253e57506000610575565b8282028284828161254b57fe5b04146125b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536166654d617468236d756c3a204f564552464c4f5700000000000000000000604482015290519081900360640190fd5b9392505050565b600080821161262f57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f536166654d617468236469763a204449564953494f4e5f42595f5a45524f0000604482015290519081900360640190fd5b600082848161263a57fe5b04949350505050565b81518151811461269e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526042815260200180614db86042913960600191505060405180910390fd5b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16141580156126da5750600081115b156128ac576000806126f28560008151811061138457fe5b73ffffffffffffffffffffffffffffffffffffffff891660009081526020818152604080832085845290915281205487519395509193509161274a919084908890859061273b57fe5b60200260200101516001613a88565b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208181526040808320878452909152812054875192935090916127a0919085908990859061279157fe5b60200260200101516000613a88565b90508360015b8681101561285a576127bd89828151811061138457fe5b909650945081861461282c5773ffffffffffffffffffffffffffffffffffffffff8b811660009081526020818152604080832086845280835281842098909855928d16825281815282822094825284815282822095909555878152948452808520549290935291909220549084905b61283d84868a848151811061273b57fe5b935061285083868a848151811061279157fe5b92506001016127a6565b505073ffffffffffffffffffffffffffffffffffffffff808a16600090815260208181526040808320888452825280832095909555918a16815280825283812095815294905292209190915550612949565b60005b81811015612947578281815181106128c357fe5b60200260200101516128e8878684815181106128db57fe5b6020026020010151610524565b101561293f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526036815260200180614ef06036913960400191505060405180910390fd5b6001016128af565b505b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156129f55781810151838201526020016129dd565b50505050905001838103825284818151815260200191508051906020019060200280838360005b83811015612a34578181015183820152602001612a1c565b5050505090500194505050505060405180910390a45050505050565b612a6f8573ffffffffffffffffffffffffffffffffffffffff16613c9b565b15612cbd5760008573ffffffffffffffffffffffffffffffffffffffff1663bc197c8184338a8989886040518763ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff168152602001806020018060200180602001848103845287818151815260200191508051906020019060200280838360005b83811015612b27578181015183820152602001612b0f565b50505050905001848103835286818151815260200191508051906020019060200280838360005b83811015612b66578181015183820152602001612b4e565b50505050905001848103825285818151815260200191508051906020019080838360005b83811015612ba2578181015183820152602001612b8a565b50505050905090810190601f168015612bcf5780820380516001836020036101000a031916815260200191505b5098505050505050505050602060405180830381600088803b158015612bf457600080fd5b5087f1158015612c08573d6000803e3d6000fd5b50505050506040513d6020811015612c1f57600080fd5b505190507fffffffff0000000000000000000000000000000000000000000000000000000081167fbc197c810000000000000000000000000000000000000000000000000000000014611787576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252604c815260200180614dfa604c913960600191505060405180910390fd5b505050505050565b3360009081526007602052604090205460ff16612d0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614814565b33600090815260086020526040902054612d26613de4565b3360009081526008602052604081208054909190612d4057fe5b6000918252602080832060408051608081018252939091015467ffffffffffffffff80821685526801000000000000000082048116938501939093527001000000000000000000000000000000008104831691840191909152780100000000000000000000000000000000000000000000000090041660608201529150805b8551811015612cbd576000868281518110612dd657fe5b602002602001015190506000868381518110612dee57fe5b602002602001015190506000600b60008481526020019081526020016000205490505b856040015167ffffffffffffffff16421080612e3a5750856060015167ffffffffffffffff1642115b80612e4f5750855167ffffffffffffffff1683105b80612e67575082866020015167ffffffffffffffff16105b15612f4b57600185019450868510612eab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614962565b336000908152600860205260409020805486908110612ec657fe5b600091825260209182902060408051608081018252929091015467ffffffffffffffff808216845268010000000000000000820481169484019490945270010000000000000000000000000000000081048416918301919091527801000000000000000000000000000000000000000000000000900490911660608201529550612e11565b8015612fb6576000838152600a6020526040812054612f6a9084613cd2565b905081811115612fa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161025790614c13565b6000848152600a60205260409020555b505050600101612dbf565b612fce8484846000613a01565b6040805184815260208101849052815173ffffffffffffffffffffffffffffffffffffffff87169260009233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62929181900390910190a4610daa60008585855a866137b3565b80516118e5906002906020840190613e22565b73ffffffffffffffffffffffffffffffffffffffff82166130b4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614e826031913960400191505060405180910390fd5b6103e881111561310f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526039815260200180614f266039913960400191505060405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9390931692909217909155600555565b6131678383836001613a01565b6040805183815260208101839052815160009273ffffffffffffffffffffffffffffffffffffffff87169233927fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62929181900390910190a4505050565b815183511461321e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252603e815260200180615023603e913960400191505060405180910390fd5b82511561333e576000806132388560008151811061138457fe5b73ffffffffffffffffffffffffffffffffffffffff8816600090815260208181526040808320858452909152812054875193955091935091613281919084908890859061279157fe5b86519091508360015b82811015613305576132a189828151811061138457fe5b90965094508186146132ea5773ffffffffffffffffffffffffffffffffffffffff8a16600090815260208181526040808320948352939052828120949094558584529220549184905b6132fb84868a848151811061279157fe5b935060010161328a565b50505073ffffffffffffffffffffffffffffffffffffffff87166000908152602081815260408083209583529490529290922091909155505b8373ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051808060200180602001838103835285818151815260200191508051906020019060200280838360005b838110156133eb5781810151838201526020016133d3565b50505050905001838103825284818151815260200191508051906020019060200280838360005b8381101561342a578181015183820152602001613412565b5050505090500194505050505060405180910390a4610daa60008585855a86612a50565b60028054604080516020601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61010060018716150201909416859004938401819004810282018101909252828152606093909290918301828280156134f55780601f106134ca576101008083540402835291602001916134f5565b820191906000526020600020905b8154815290600101906020018083116134d857829003601f168201915b50505050509050606060005b8351811015610daa578261352785838151811061351a57fe5b602002602001015161225a565b6040516020018083805190602001908083835b6020831061357757805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0909201916020918201910161353a565b51815160209384036101000a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018019909216911617905285519190930192850191508083835b602083106135fb57805182527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe090920191602091820191016135be565b6001836020036101000a038019825116818451168082178552505050505050905001807f2e6a736f6e00000000000000000000000000000000000000000000000000000081525060050192505050604051602081830303815290604052915083818151811061366657fe5b60200260200101517f6bb7ff708619ba0610cba295a58592e0451dee2622938c8755667688daf3529b836040518080602001828103825283818151815260200191508051906020019080838360005b838110156136cd5781810151838201526020016136b5565b50505050905090810190601f1680156136fa5780820380516001836020036101000a031916815260200191505b509250505060405180910390a2600101613501565b61371c8483836001613a01565b6137298383836000613a01565b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628585604051808381526020018281526020019250505060405180910390a450505050565b6137d28573ffffffffffffffffffffffffffffffffffffffff16613c9b565b15612cbd5760008573ffffffffffffffffffffffffffffffffffffffff1663f23a6e6184338a8989886040518763ffffffff1660e01b8152600401808673ffffffffffffffffffffffffffffffffffffffff1681526020018573ffffffffffffffffffffffffffffffffffffffff16815260200184815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b8381101561388b578181015183820152602001613873565b50505050905090810190601f1680156138b85780820380516001836020036101000a031916815260200191505b509650505050505050602060405180830381600088803b1580156138db57600080fd5b5087f11580156138ef573d6000803e3d6000fd5b50505050506040513d602081101561390657600080fd5b505190507fffffffff0000000000000000000000000000000000000000000000000000000081167ff23a6e610000000000000000000000000000000000000000000000000000000014611787576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526047815260200180614f5f6047913960600191505060405180910390fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f0e89341c0000000000000000000000000000000000000000000000000000000014156139f857506001610589565b61058682613d46565b600080613a0d85611e27565b73ffffffffffffffffffffffffffffffffffffffff88166000908152602081815260408083208584529091529020549193509150613a4d90828686613a88565b73ffffffffffffffffffffffffffffffffffffffff909616600090815260208181526040808320948352939052919091209490945550505050565b60006020840263ffffffff82846001811115613aa057fe5b1415613b6e5784821b8701925086831015613b06576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806150616032913960400191505060405180910390fd5b64010000000087831c8216860110613b69576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806150616032913960400191505060405180910390fd5b613c91565b6001846001811115613b7c57fe5b1415613c405784821b8703925086831115613be2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180614d4e6033913960400191505060405180910390fd5b84818389901c161015613b69576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526033815260200180614d4e6033913960400191505060405180910390fd5b6040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526045815260200180614fde6045913960600191505060405180910390fd5b5050949350505050565b6000813f80158015906125b857507fc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470141592915050565b6000828201838110156125b857604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f536166654d617468236164643a204f564552464c4f5700000000000000000000604482015290519081900360640190fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fd9b67a26000000000000000000000000000000000000000000000000000000001415613d9a57506001610589565b7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610586565b60408051608081018252600080825260208201819052918101829052606081019190915290565b604080518082019091526000808252602082015290565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282613e585760008555613e9e565b82601f10613e7157805160ff1916838001178555613e9e565b82800160010185558215613e9e579182015b82811115613e9e578251825591602001919060010190613e83565b50613eaa929150613eae565b5090565b5b80821115613eaa5760008155600101613eaf565b803573ffffffffffffffffffffffffffffffffffffffff8116811461058957600080fd5b60008083601f840112613ef8578081fd5b50813567ffffffffffffffff811115613f0f578182fd5b6020830191508360208083028501011115610e0b57600080fd5b600082601f830112613f39578081fd5b8135613f4c613f4782614cb9565b614c95565b818152915060208083019084810181840286018201871015613f6d57600080fd5b60005b84811015613f8c57813584529282019290820190600101613f70565b505050505092915050565b60008083601f840112613fa8578182fd5b50813567ffffffffffffffff811115613fbf578182fd5b602083019150836020828501011115610e0b57600080fd5b600082601f830112613fe7578081fd5b813567ffffffffffffffff811115613ffb57fe5b61402c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601614c95565b915080825283602082850101111561404357600080fd5b8060208401602084013760009082016020015292915050565b803567ffffffffffffffff8116811461058957600080fd5b600060208284031215614085578081fd5b6125b882613ec3565b600080604083850312156140a0578081fd5b6140a983613ec3565b91506140b760208401613ec3565b90509250929050565b600080600080600060a086880312156140d7578081fd5b6140e086613ec3565b94506140ee60208701613ec3565b9350604086013567ffffffffffffffff8082111561410a578283fd5b61411689838a01613f29565b9450606088013591508082111561412b578283fd5b61413789838a01613f29565b9350608088013591508082111561414c578283fd5b5061415988828901613fd7565b9150509295509295909350565b600080600080600060a0868803121561417d578081fd5b61418686613ec3565b945061419460208701613ec3565b93506040860135925060608601359150608086013567ffffffffffffffff8111156141bd578182fd5b61415988828901613fd7565b600080600080608085870312156141de578384fd5b6141e785613ec3565b9350602085013567ffffffffffffffff80821115614203578485fd5b61420f88838901613f29565b94506040870135915080821115614224578384fd5b61423088838901613f29565b93506060870135915080821115614245578283fd5b5061425287828801613fd7565b91505092959194509250565b60008060408385031215614270578182fd5b61427983613ec3565b91506020830135801515811461428d578182fd5b809150509250929050565b600080604083850312156142aa578182fd5b6142b383613ec3565b946020939093013593505050565b6000806000806000608086880312156142d8578283fd5b6142e186613ec3565b94506020860135935060408601359250606086013567ffffffffffffffff81111561430a578182fd5b61431688828901613f97565b969995985093965092949392505050565b600080600080600060a0868803121561433e578283fd5b61434786613ec3565b94506143556020870161405c565b93506143636040870161405c565b92506143716060870161405c565b915061437f6080870161405c565b90509295509295909350565b6000806040838503121561439d578182fd5b823567ffffffffffffffff808211156143b4578384fd5b818501915085601f8301126143c7578384fd5b81356143d5613f4782614cb9565b80828252602080830192508086018a8283870289010111156143f5578889fd5b8896505b8487101561441e5761440a81613ec3565b8452600196909601959281019281016143f9565b509096508701359350505080821115614435578283fd5b5061444285828601613f29565b9150509250929050565b6000806020838503121561445e578182fd5b823567ffffffffffffffff811115614474578283fd5b61448085828601613ee7565b90969095509350505050565b600080600080604085870312156144a1578182fd5b843567ffffffffffffffff808211156144b8578384fd5b6144c488838901613ee7565b909650945060208701359150808211156144dc578384fd5b506144e987828801613ee7565b95989497509550505050565b600060208284031215614506578081fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146125b8578182fd5b60008060208385031215614547578182fd5b823567ffffffffffffffff81111561455d578283fd5b61448085828601613f97565b60006080828403121561457a578081fd5b6040516080810181811067ffffffffffffffff8211171561459757fe5b6040526145a38361405c565b81526145b16020840161405c565b60208201526145c26040840161405c565b60408201526145d36060840161405c565b60608201529392505050565b6000602082840312156145f0578081fd5b5035919050565b60008060408385031215614609578182fd5b50508035926020909101359150565b60008284527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff831115614649578081fd5b6020830280836020870137939093016020019283525090919050565b805167ffffffffffffffff908116835260208083015182169084015260408083015182169084015260609182015116910152565b73ffffffffffffffffffffffffffffffffffffffff91909116815260200190565b73ffffffffffffffffffffffffffffffffffffffff929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b818110156147225761470f838551614665565b92840192608092909201916001016146fc565b50909695505050505050565b600060408252614742604083018688614618565b8281036020840152614755818587614618565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b818110156147225783518352928401929184019160010161477c565b901515815260200190565b6000602080835283518082850152825b818110156147cf578581018301518582016040015282016147b3565b818111156147e05783604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b60208082526032908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f464143544f52595f4e4f545f4143544956450000000000000000000000000000606082015260800190565b60208082526036908201527f536b79776561766572417373657473237365744d617849737375616e6365733a60408201527f20494e56414c49445f4152524159535f4c454e47544800000000000000000000606082015260800190565b60208082526012908201527f554e535550504f525445445f4d4554484f440000000000000000000000000000604082015260600190565b60208082526030908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a20494e56414c49445f52414e474500000000000000000000000000000000606082015260800190565b6020808252602f908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f49445f4f55545f4f465f52414e47450000000000000000000000000000000000606082015260800190565b6020808252602a908201527f4f776e61626c65237472616e736665724f776e6572736869703a20494e56414c60408201527f49445f4144445245535300000000000000000000000000000000000000000000606082015260800190565b6020808252603c908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a204f5645524c41505f574954485f4c4f434b45445f52414e474500000000606082015260800190565b6020808252602d908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a204e554c4c5f52414e474500000000000000000000000000000000000000606082015260800190565b60208082526039908201527f536b79776561766572417373657473237365744d617849737375616e6365733a60408201527f20494e56414c49445f4e45575f4d41585f49535355414e434500000000000000606082015260800190565b60208082526049908201527f536b79776561766572417373657473236164644d696e745065726d697373696f60408201527f6e3a2053544152545f54494d455f49535f4e4f545f4c45535345525f5448454e60608201527f5f454e445f54494d450000000000000000000000000000000000000000000000608082015260a00190565b60208082526026908201527f4f776e61626c65236f6e6c794f776e65723a2053454e4445525f49535f4e4f5460408201527f5f4f574e45520000000000000000000000000000000000000000000000000000606082015260800190565b60208082526035908201527f536b79776561766572417373657473235f76616c69646174654d696e74733a2060408201527f4d41585f49535355414e43455f45584345454445440000000000000000000000606082015260800190565b608081016105758284614665565b90815260200190565b918252602082015260400190565b60405181810167ffffffffffffffff81118282101715614cb157fe5b604052919050565b600067ffffffffffffffff821115614ccd57fe5b506020908102019056fe455243313135355061636b656442616c616e63652362616c616e63654f6642617463683a20494e56414c49445f41525241595f4c454e475448455243313135355061636b656442616c616e6365237361666542617463685472616e7366657246726f6d3a20494e56414c49445f524543495049454e54455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a20554e444552464c4f57455243313135355061636b656442616c616e636523736166655472616e7366657246726f6d3a20494e56414c49445f4f50455241544f52455243313135355061636b656442616c616e6365235f7361666542617463685472616e7366657246726f6d3a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f63616c6c6f6e45524331313535426174636852656365697665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745455243313135355061636b656442616c616e6365237361666542617463685472616e7366657246726f6d3a20494e56414c49445f4f50455241544f5245524332393831476c6f62616c235f736574476c6f62616c526f79616c74793a20524543495049454e545f49535f307830455243313135354d696e744275726e5061636b656442616c616e63652362617463684275726e3a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f7361666542617463685472616e7366657246726f6d3a20554e444552464c4f5745524332393831476c6f62616c235f736574476c6f62616c526f79616c74793a204645455f49535f41424f56455f3130305f50455243454e54455243313135355061636b656442616c616e6365235f63616c6c6f6e4552433131353552656365697665643a20494e56414c49445f4f4e5f524543454956455f4d455353414745455243313135355061636b656442616c616e636523736166655472616e7366657246726f6d3a20494e56414c49445f524543495049454e54455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a20494e56414c49445f42494e5f57524954455f4f5045524154494f4e455243313135354d696e744275726e5061636b656442616c616e6365235f62617463684d696e743a20494e56414c49445f4152524159535f4c454e475448455243313135355061636b656442616c616e6365235f7669657755706461746542696e56616c75653a204f564552464c4f57a2646970667358221220fb1372790e40e3e548bbc115377592682a7efd66fc87555aa190c17a7e2027e864736f6c63430007040033
Deployed Bytecode Sourcemap
802:16008:25:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8925:28;;;;;;;;;;:::i;:::-;;;;;;;;9699:261:10;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16607:201:25;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;476:18:7:-;;;:::i;:::-;;;;;;;:::i;3968:1055:25:-;;;;;;:::i;:::-;;:::i;:::-;;999:147:7;;;;;;:::i;:::-;;:::i;7368:692:25:-;;;;;;:::i;:::-;;:::i;15497:146::-;;;;;;:::i;:::-;;:::i;1737:262:11:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;3444:547:10:-;;;;;;:::i;:::-;;:::i;5272:859:25:-;;;;;;:::i;:::-;;:::i;10318:1013:10:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;14675:101:25:-;;;:::i;:::-;;;;;;;:::i;451:21:7:-;;;:::i;10147:367:25:-;;;;;;:::i;:::-;;:::i;3363:144::-;;;;;;:::i;:::-;;:::i;15890:137::-;;;;;;:::i;:::-;;:::i;1280:73:27:-;;;:::i;:::-;;;;;;;:::i;3092:145:25:-;;;;;;:::i;:::-;;:::i;8529:163::-;;;;;;:::i;:::-;;:::i;8707:230:10:-;;;;;;:::i;:::-;;:::i;14469:138:25:-;;;;;;:::i;:::-;;:::i;6779:145::-;;;;;;:::i;:::-;;:::i;15141:110::-;;;;;;:::i;:::-;;:::i;9563:313::-;;;;;;:::i;:::-;;:::i;513:32:11:-;;;:::i;16177:98:25:-;;;;;;:::i;:::-;;:::i;14001:189:10:-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;13143:352:25:-;;;;;;:::i;:::-;;:::i;13838:372::-;;;;;;:::i;:::-;;:::i;9199:160:10:-;;;;;;:::i;:::-;;:::i;14447:432::-;;;;;;:::i;:::-;;:::i;2360:598::-;;;;;;:::i;:::-;;:::i;993:224:27:-;;;;;;:::i;:::-;;:::i;14282:116:25:-;;;;;;:::i;:::-;;:::i;9699:261:10:-;9781:7;9798:11;9815:13;9881:18;9895:3;9881:13;:18::i;:::-;9926:16;;;:8;:16;;;;;;;;;;;:21;;;;;;;;;9866:33;;-1:-1:-1;9866:33:10;-1:-1:-1;9912:43:10;;9866:33;9912:13;:43::i;:::-;9905:50;;;;9699:261;;;;;:::o;16607:201:25:-;16747:4;16766:37;16790:12;16766:23;:37::i;:::-;16759:44;;16607:201;;;;:::o;476:18:7:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;3968:1055:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;4132:1:25::1;4120:9;:13;;;4112:71;;;;;;;;;;;;:::i;:::-;4210:9;4197:22;;:9;:22;;;;4189:83;;;;;;;;;;;;:::i;:::-;4299:8;4286:21;;:10;:21;;;4278:107;;;;;;;;;;;;:::i;:::-;4510:9;4505:286;4529:12;:19:::0;4525:23;::::1;4505:286;;;4563:30;;:::i;:::-;4596:12;4609:1;4596:15;;;;;;;;;::::0;;;::::1;::::0;;;;4563:48:::1;::::0;;::::1;::::0;::::1;::::0;;4596:15;;;::::1;4563:48:::0;::::1;::::0;;::::1;::::0;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;;;;;;::::1;::::0;::::1;::::0;;;;;-1:-1:-1;4637:30:25;::::1;;::::0;4636:68:::1;;;4694:9;4673:30;;:12;:18;;;:30;;;4636:68;4619:165;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;4550:3:25::1;;4505:286;;;;4847:23;;:::i;:::-;-1:-1:-1::0;4873:54:25::1;::::0;;::::1;::::0;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;::::1;;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;;;;::::1;::::0;;;;;;4933:26:::1;::::0;::::1;-1:-1:-1::0;4933:26:25;;;:16:::1;:26:::0;;;;;:38;;::::1;::::0;::::1;::::0;;;;;;;;;;;::::1;::::0;;;;;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;;;4982:36;;4873:54;;4933:26;4982:36:::1;::::0;::::1;::::0;4873:54;;4982:36:::1;:::i;:::-;;;;;;;;856:1:27;3968:1055:25::0;;;;;:::o;999:147:7:-;1055:13;1107:7;1116:14;1126:3;1116:9;:14::i;:::-;1090:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;1090:50:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1090:50:7;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;999:147:7:o;7368:692:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;7490:38:25;;::::1;7482:105;;;;;;;;;;;;:::i;:::-;7681:9;7676:325;7696:15:::0;;::::1;7676:325;;;7754:1;7731:11;:20;7743:4;;7748:1;7743:7;;;;;;;;;;;;;7731:20;;;;;;;;;;;;:24;7727:218;;;7790:16;;7807:1;7790:19;;;;;;;;;;;;;7786:1;:23;:69;;;;;7835:11;:20;7847:4;;7852:1;7847:7;;;;;;;;;;;;;7835:20;;;;;;;;;;;;7813:16;;7830:1;7813:19;;;;;;;;;;;;;:42;7786:69;7767:169;;;;;;;;;;;;:::i;:::-;7975:16;;7992:1;7975:19;;;;;;;;;;;;;7952:11;:20;7964:4;;7969:1;7964:7;;;;;;;;::::0;;::::1;::::0;;;::::1;;7952:20:::0;;-1:-1:-1;7952:20:25;::::1;::::0;;;;;;-1:-1:-1;7952:20:25;:42;7713:3:::1;;7676:325;;;;8012:43;8032:4;;8038:16;;8012:43;;;;;;;;;:::i;:::-;;;;;;;;7368:692:::0;;;;:::o;15497:146::-;15600:38;15611:10;15623:4;;15600:38;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;15600:38:25;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15629:8:25;;-1:-1:-1;15629:8:25;;;;15600:38;;;15629:8;;15600:38;15629:8;15600:38;;;;;;;;;-1:-1:-1;15600:10:25;;-1:-1:-1;;;15600:38:25:i;:::-;15497:146;;;;:::o;1737:262:11:-;1831:16;1849:21;1881:19;;:::i;:::-;-1:-1:-1;1881:39:11;;;;;;;;;1903:17;1881:39;;;;;;;;;;;;;;1949:44;;1988:4;;1949:34;;:9;;:13;:34::i;:::-;:38;;:44::i;:::-;1926:68;;;;;1737:262;;;;;;:::o;3444:547:10:-;3630:10;:19;;;;;3629:60;;;3654:35;3671:5;3678:10;3654:16;:35::i;:::-;3621:133;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3768:17;;;3760:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3857:50;3880:5;3887:3;3892:4;3898:8;3857:22;:50::i;:::-;3913:73;3941:5;3948:3;3953:4;3959:8;3969:9;3980:5;3913:27;:73::i;:::-;3444:547;;;;;:::o;5272:859:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;5518:26:25::1;::::0;::::1;5497:18;5518:26:::0;;;:16:::1;:26;::::0;;;;:33;:37;;5617:33:::1;;:::i;:::-;5653:26;::::0;::::1;;::::0;;;:16:::1;:26;::::0;;;;:39;;5680:11;;5653:39;::::1;;;;;;::::0;;;::::1;::::0;;;;5617:75:::1;::::0;;::::1;::::0;::::1;::::0;;5653:39;;;::::1;5617:75:::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;;;;;;;;::::1;::::0;;::::1;::::0;;;;;-1:-1:-1;5721:25:25;;::::1;5717:272;;5756:28;;:::i;:::-;5787:26;::::0;::::1;;::::0;;;:16:::1;:26;::::0;;;;:38;;5814:10;;5787:38;::::1;;;;;;::::0;;;::::1;::::0;;;5756:69:::1;::::0;;::::1;::::0;::::1;::::0;;5787:38;;;::::1;5756:69:::0;::::1;::::0;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;;;;::::1;;::::0;;;;5874:26:::1;::::0;::::1;::::0;;5756:69:::1;5874:26:::0;;;;;:39;;5756:69;;-1:-1:-1;5756:69:25;;5901:11;;5874:39;::::1;;;;;;::::0;;;::::1;::::0;;;;:52;;:39;::::1;:52:::0;;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;;;;::::1;;::::0;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;;;::::0;;-1:-1:-1;5717:272:25::1;6035:26;::::0;::::1;;::::0;;;:16:::1;:26;::::0;;;;:32;;;::::1;;;;;::::0;;;::::1;::::0;;;;;;;;;;;;;;;6078:48:::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;6110:15;;6078:48:::1;:::i;:::-;;;;;;;;856:1:27;;5272:859:25::0;;:::o;10318:1013:10:-;10470:14;;10510:11;;10425:16;;10470:14;10498:23;;10490:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10611:11;10624:13;10641:22;10655:4;10660:1;10655:7;;;;;;;;;;;;;;10641:13;:22::i;:::-;10610:53;;;;10669:19;10691:8;:20;10700:7;10708:1;10700:10;;;;;;;;;;;;;;10691:20;;;;;;;;;;;;;;;:25;10712:3;10691:25;;;;;;;;;;;;10669:47;;10722:16;10741:3;10722:22;;10773:30;10820:8;10806:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10806:23:10;;10773:56;;10854:33;10868:11;10881:5;10854:13;:33::i;:::-;10835:13;10849:1;10835:16;;;;;;;;;;;;;;;;;:52;10955:1;10938:362;10962:8;10958:1;:12;10938:362;;;11000:22;11014:4;11019:1;11014:7;;;;;;;11000:22;10985:37;;-1:-1:-1;10985:37:10;-1:-1:-1;11104:15:10;;;;;:45;;;11139:7;11147:1;11139:10;;;;;;;;;;;;;;11123:26;;:7;11133:1;11131;:3;11123:12;;;;;;;;;;;;;;:26;;;;11104:45;11100:133;;;11175:8;:20;11184:7;11192:1;11184:10;;;;;;;;;;;;;;11175:20;;;;;;;;;;;;;;;:25;11196:3;11175:25;;;;;;;;;;;;11161:39;;11221:3;11210:14;;11100:133;11260:33;11274:11;11287:5;11260:13;:33::i;:::-;11241:13;11255:1;11241:16;;;;;;;;;;;;;;;;;:52;10972:3;;10938:362;;;-1:-1:-1;11313:13:10;10318:1013;-1:-1:-1;;;;;;;;10318:1013:10:o;14675:101:25:-;14725:19;14759:12;14752:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14675:101;:::o;451:21:7:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10147:367:25;10303:16;;;10317:1;10303:16;;;;;;;;;10280:20;;10303:16;;;;;;;;;-1:-1:-1;;10352:16:25;;;10366:1;10352:16;;;;;;;;;10280:39;;-1:-1:-1;10325:24:25;;10352:16;-1:-1:-1;10352:16:25;;;;;;;;;;;-1:-1:-1;10352:16:25;10325:43;;10383:3;10374;10378:1;10374:6;;;;;;;;;;;;;:12;;;;;10405:7;10392;10400:1;10392:10;;;;;;;;;;;;;:20;;;;;10444:28;10459:3;10464:7;10444:14;:28::i;:::-;10478:31;10484:3;10489;10494:7;10503:5;;10478:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10478:5:25;;-1:-1:-1;;;10478:31:25:i;:::-;10147:367;;;;;;;:::o;3363:144::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;3433:25:25::1;::::0;::::1;3461:5;3433:25:::0;;;:15:::1;:25;::::0;;;;;:33;;;::::1;::::0;;3477:25;::::1;::::0;3461:5;3477:25:::1;3363:144:::0;:::o;15890:137::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;15982:40:25::1;16002:19;;15982:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;15982:19:25::1;::::0;-1:-1:-1;;;15982:40:25:i:1;:::-;15890:137:::0;;:::o;1280:73:27:-;1343:5;;;;1280:73;:::o;3092:145:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;3162:25:25::1;::::0;::::1;;::::0;;;:15:::1;:25;::::0;;;;;:32;;;::::1;3190:4;3162:32;::::0;;3205:27;::::1;::::0;3162:25;3205:27:::1;3092:145:::0;:::o;8529:163::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;8634:53:25::1;8656:9;8667:19;8634:21;:53::i;8707:230:10:-:0;8839:10;8829:21;;;;:9;:21;;;;;;;;;:32;;;;;;;;;;;;:44;;;;;;;;;;;;;8884:48;;;;;;;8829:32;;8839:10;8884:48;;;;;;;;;;;8707:230;;:::o;14469:138:25:-;14576:26;;;;;;;:16;:26;;;;;;;;14569:33;;;;;;;;;;;;;;;;;14542:19;;14569:33;;14576:26;;14569:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14469:138;;;:::o;6779:145::-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;6864:12:25::1;:25:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;6864:25:25;;;;;;;;;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;::::1;::::0;;;;::::1;;::::0;;::::1;;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;;::::1;;::::0;;6900:19;::::1;::::0;::::1;::::0;6864:25;;6900:19:::1;:::i;:::-;;;;;;;;6779:145:::0;:::o;15141:110::-;15215:31;15221:10;15233:3;15238:7;15215:5;:31::i;9563:313::-;9733:30;9748:4;9754:8;9733:14;:30::i;:::-;9833:38;9844:3;9849:4;9855:8;9865:5;9833:10;:38::i;513:32:11:-;;;;;;;;;;;:::o;16177:98:25:-;802:5:27;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;16251:19:25::1;16260:9;;16251:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;;-1:-1:-1;16251:8:25::1;::::0;-1:-1:-1;;;16251:19:25:i:1;14001:189:10:-:0;1505:19;14104:21;;;14139;;;;;14001:189::o;13143:352:25:-;13216:16;13255:4;13216:16;13255:4;13305:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13305:19:25;;13272:52;;13380:9;13375:89;13399:4;13395:1;:8;13375:89;;;13437:11;:20;13449:4;;13454:1;13449:7;;;;;;;;;;;;;13437:20;;;;;;;;;;;;13418:13;13432:1;13418:16;;;;;;;;;;;;;;;;;:39;13405:3;;13375:89;;;-1:-1:-1;13477:13:25;13143:352;-1:-1:-1;;;;13143:352:25:o;13838:372::-;13915:16;13954:4;13915:16;13954:4;14008:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14008:19:25;;13971:56;;14083:9;14078:97;14102:4;14098:1;:8;14078:97;;;14144:15;:24;14160:4;;14165:1;14160:7;;;;;;;;;;;;;14144:24;;;;;;;;;;;;14121:17;14139:1;14121:20;;;;;;;;;;;;;;;;;:47;14108:3;;14078:97;;9199:160:10;9326:17;;;;9294:15;9326:17;;;:9;:17;;;;;;;;:28;;;;;;;;;;;;;;;9199:160::o;14447:432::-;1395:2;14806:22;;14842:24;;;14725:33;14841;14447:432;;;;:::o;2360:598::-;2521:10;:19;;;;;2520:60;;;2545:35;2562:5;2569:10;2545:16;:35::i;:::-;2512:128;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2654:17;;;2646:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2838:43;2856:5;2863:3;2868;2873:7;2838:17;:43::i;:::-;2887:66;2910:5;2917:3;2922;2927:7;2936:9;2947:5;2887:22;:66::i;993:224:27:-;802:5;;;;788:10;:19;780:70;;;;;;;;;;;;:::i;:::-;1070:23:::1;::::0;::::1;1062:78;;;;;;;;;;;;:::i;:::-;1146:5;:17:::0;;;::::1;;::::0;;::::1;::::0;;::::1;::::0;;;;1174:38:::1;::::0;1146:17;;1195:5:::1;::::0;1174:38:::1;::::0;-1:-1:-1;;1174:38:27::1;993:224:::0;:::o;14282:116:25:-;14368:25;;14349:4;14368:25;;;:15;:25;;;;;;;;;14282:116::o;2336:243:11:-;2439:4;2455:42;;;2471:26;2455:42;2451:74;;;-1:-1:-1;2514:4:11;2507:11;;2451:74;2537:37;2561:12;2537:23;:37::i;2843:513:7:-;2897:27;2936:7;2932:38;;-1:-1:-1;2953:10:7;;;;;;;;;;;;;;;;;;;2932:38;2988:2;;2976:9;3062:50;3069:6;;3062:50;;3085:5;;3103:2;3098:7;;;;3062:50;;;3118:17;3148:3;3138:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3138:14:7;-1:-1:-1;3118:34:7;-1:-1:-1;3170:7:7;;;3217:84;3224:7;;3217:84;;3274:2;3269;:7;3264:2;:12;3253:25;;3241:4;3246:3;;;;;;;3241:9;;;;;;;;;;;:37;;;;;;;;;;-1:-1:-1;3292:2:7;3286:8;;;;3217:84;;;-1:-1:-1;3346:4:7;2843:513;-1:-1:-1;;;;;2843:513:7:o;4124:589:9:-;4282:11;;4316:15;;4307:24;;4299:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4438:9;4433:173;4457:5;4453:1;:9;4433:173;;;4509:63;4526:5;4535:4;4540:1;4535:7;;;;;;;;;;;;;;4544:8;4553:1;4544:11;;;;;;;;;;;;;;4557:14;4509:16;:63::i;:::-;4464:3;;4433:173;;;;4687:3;4646:62;;4672:5;4646:62;;4660:10;4646:62;;;4693:4;4699:8;4646:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4124:589;;;;:::o;224:407:14:-;282:7;506:6;502:35;;-1:-1:-1;529:1:14;522:8;;502:35;555:5;;;559:1;555;:5;:1;574:5;;;;;:10;566:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;625:1;224:407;-1:-1:-1;;;224:407:14:o;753:308::-;811:7;900:1;896;:5;888:48;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;942:9;958:1;954;:5;;;;;;;753:308;-1:-1:-1;;;;753:308:14:o;5742:1939:10:-;5893:11;;5964:15;;5951:28;;5943:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6070:3;6061:12;;:5;:12;;;;:29;;;;;6089:1;6077:9;:13;6061:29;6057:1537;;;6169:11;6182:13;6199:22;6213:4;6218:1;6213:7;;;;;;;6199:22;6345:15;;;6307;6345;;;;;;;;;;;:20;;;;;;;;;6374:11;;6168:53;;-1:-1:-1;6168:53:10;;-1:-1:-1;6307:15:10;6325:77;;6345:20;6168:53;;6374:8;;6307:15;;6374:11;;;;;;;;;;6387:14;6325:19;:77::i;:::-;6446:13;;;6410;6446;;;;;;;;;;;:18;;;;;;;;;6473:11;;6307:95;;-1:-1:-1;6410:13:10;;6426:75;;6446:18;6466:5;;6473:8;;6410:13;;6473:11;;;;;;;;;;6486:14;6426:19;:75::i;:::-;6410:91;-1:-1:-1;6554:3:10;6583:1;6566:649;6590:9;6586:1;:13;6566:649;;;6631:22;6645:4;6650:1;6645:7;;;;;;;6631:22;6616:37;;-1:-1:-1;6616:37:10;-1:-1:-1;6690:14:10;;;6686:323;;6770:15;;;;:8;:15;;;;;;;;;;;:24;;;;;;;;;:34;;;;6816:13;;;;;;;;;;;:22;;;;;;;;;:30;;;;6869:20;;;;;;;;;;6909:18;;;;;;;;;;6869:20;;6686:323;7062:64;7082:7;7091:5;7098:8;7107:1;7098:11;;;;;;;7062:64;7052:74;;7144:62;7164:5;7171;7178:8;7187:1;7178:11;;;;;;;7144:62;7136:70;-1:-1:-1;6601:3:10;;6566:649;;;-1:-1:-1;;7271:15:10;;;;:8;:15;;;;;;;;;;;:20;;;;;;;;:30;;;;7309:13;;;;;;;;;;;:18;;;;;;;;:26;;;;-1:-1:-1;6057:1537:10;;;7427:9;7422:166;7446:9;7442:1;:13;7422:166;;;7509:8;7518:1;7509:11;;;;;;;;;;;;;;7480:25;7490:5;7497:4;7502:1;7497:7;;;;;;;;;;;;;;7480:9;:25::i;:::-;:40;;7472:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7457:3;;7422:166;;;;6057:1537;7656:3;7623:53;;7649:5;7623:53;;7637:10;7623:53;;;7661:4;7667:8;7623:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5742:1939;;;;;:::o;7794:516::-;8015:16;:3;:14;;;:16::i;:::-;8011:295;;;8041:13;8079:3;8057:49;;;8112:9;8123:10;8135:5;8142:4;8148:8;8158:5;8057:107;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;8057:107:10;;-1:-1:-1;8180:38:10;;;8190:28;8180:38;8172:127;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8011:295;7794:516;;;;;;:::o;11084:1593:25:-;11197:10;11181:27;;;;:15;:27;;;;;;;;11173:90;;;;;;;;;;;;:::i;:::-;11335:10;11299:16;11318:28;;;:16;:28;;;;;:35;11396:23;;:::i;:::-;11439:10;11422:28;;;;:16;:28;;;;;:31;;:28;;;:31;;;;;;;;;;;;11396:57;;;;;;;;11422:31;;;;11396:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11422:31:25;11596:1077;11620:4;:11;11616:1;:15;11596:1077;;;11646:10;11659:4;11664:1;11659:7;;;;;;;;;;;;;;11646:20;;11674:14;11691:8;11700:1;11691:11;;;;;;;;;;;;;;11674:28;;11710:20;11733:11;:15;11745:2;11733:15;;;;;;;;;;;;11710:38;;11965:384;11990:5;:15;;;11972:33;;:15;:33;:68;;;;12027:5;:13;;;12009:31;;:15;:31;11972:68;:88;;;-1:-1:-1;12049:11:25;;12044:16;;;;11972:88;:108;;;;12078:2;12064:5;:11;;;:16;;;11972:108;11965:384;;;12107:1;12092:16;;;;12221:8;12207:11;:22;12199:82;;;;;;;;;;;;:::i;:::-;12316:10;12299:28;;;;:16;:28;;;;;:41;;12328:11;;12299:41;;;;;;;;;;;;;;;12291:49;;;;;;;;12299:41;;;;12291:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;11965:384:25;;;12404:16;;12400:267;;12432:28;12463:19;;;:15;:19;;;;;;:31;;12487:6;12463:23;:31::i;:::-;12432:62;;12536:12;12512:20;:36;;12504:102;;;;;;;;;;;;:::i;:::-;12616:19;;;;:15;:19;;;;;:42;12400:267;-1:-1:-1;;;11633:3:25;;11596:1077;;727:428:9;844:53;861:3;868;873:7;882:14;844:16;:53::i;:::-;954:59;;;;;;;;;;;;;;;;;;989:3;;969:10;;954:59;;;;;;;;;;;1077:73;1108:3;1114;1119;1124:7;1133:9;1144:5;1077:22;:73::i;1861:113:7:-;1940:29;;;;:7;;:29;;;;;:::i;884:393:11:-;986:25;;;978:87;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1102:4;1079:19;:27;;1071:97;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1174:17;:38;;;;;;;;;;;;;;;;1218:32;:54;884:393::o;3306:255:9:-;3412:53;3429:5;3436:3;3441:7;3450:14;3412:16;:53::i;:::-;3495:61;;;;;;;;;;;;;;3537:3;;3495:61;;;;3510:10;;3495:61;;;;;;;;;;;3306:255;;;:::o;1449:1512::-;1596:8;:15;1581:4;:11;:30;1573:105;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1689:11;;:15;1685:1036;;1783:11;1796:13;1813:22;1827:4;1832:1;1827:7;;;;;;;1813:22;1957:13;;;1921;1957;;;;;;;;;;;:18;;;;;;;;;1984:11;;1782:53;;-1:-1:-1;1782:53:9;;-1:-1:-1;1921:13:9;1937:75;;1957:18;1782:53;;1984:8;;1921:13;;1984:11;;;1937:75;2080:11;;1921:91;;-1:-1:-1;2144:3:9;2173:1;2156:476;2180:9;2176:1;:13;2156:476;;;2221:22;2235:4;2240:1;2235:7;;;;;;;2221:22;2206:37;;-1:-1:-1;2206:37:9;-1:-1:-1;2280:14:9;;;2276:234;;2360:13;;;:8;:13;;;;;;;;;;;:22;;;;;;;;;:30;;;;2410:18;;;;;;;;;2276:234;2561:62;2581:5;2588;2595:8;2604:1;2595:11;;;;;;;2561:62;2553:70;-1:-1:-1;2191:3:9;;2156:476;;;-1:-1:-1;;;2688:13:9;;;:8;:13;;;;;;;;;;;:18;;;;;;;;;;:26;;;;-1:-1:-1;1685:1036:9;2792:3;2752:60;;2786:3;2752:60;;2766:10;2752:60;;;2797:4;2803:8;2752:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2876:80;2912:3;2918;2923:4;2929:8;2939:9;2950:5;2876:27;:80::i;1421:311:7:-;1506:7;1482:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:21;;:31;;1506:7;;1482:31;;1506:7;1482:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1519:22;1553:9;1548:180;1572:9;:16;1568:1;:20;1548:180;;;1638:7;1647:23;1657:9;1667:1;1657:12;;;;;;;;;;;;;;1647:9;:23::i;:::-;1621:59;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;1621:59:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1603:78;;1708:9;1718:1;1708:12;;;;;;;;;;;;;;1694:27;1698:8;1694:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1590:3;;1548:180;;4381:385:10;4509:53;4526:5;4533:3;4538:7;4547:14;4509:16;:53::i;:::-;4599;4616:3;4623;4628:7;4637:14;4599:16;:53::i;:::-;4743:3;4709:52;;4736:5;4709:52;;4724:10;4709:52;;;4748:3;4753:7;4709:52;;;;;;;;;;;;;;;;;;;;;;;;4381:385;;;;:::o;4874:468::-;5066:16;:3;:14;;;:16::i;:::-;5062:276;;;5092:13;5130:3;5108:44;;;5157:9;5168:10;5180:5;5187:3;5192:7;5201:5;5108:99;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5108:99:10;;-1:-1:-1;5223:32:10;;;5233:22;5223:32;5215:116;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2379:234:7;2465:4;2481:50;;;2497:34;2481:50;2477:82;;;-1:-1:-1;2548:4:7;2541:11;;2477:82;2571:37;2595:12;2571:23;:37::i;11845:352:10:-;11963:11;11980:13;12047:18;12061:3;12047:13;:18::i;:::-;12140;;;:8;:18;;;;;;;;;;;:23;;;;;;;;;12032:33;;-1:-1:-1;12032:33:10;-1:-1:-1;12120:72:10;;12032:33;12172:7;12181:10;12120:19;:72::i;:::-;12094:18;;;;:8;:18;;;;;;;;;;;:23;;;;;;;;;;:98;;;;-1:-1:-1;;;;11845:352:10:o;12664:1162::-;12796:20;1395:2;12842:22;;12885:33;12796:20;12929:10;:28;;;;;;;;;12925:871;;;12996:16;;;12982:31;;;-1:-1:-1;13029:26:10;;;;13021:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13178:16;13137:19;;;13136:28;;13135:40;;:59;13118:181;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12925:871;;;13331:14;13317:10;:28;;;;;;;;;13313:483;;;13384:16;;;13370:31;;;-1:-1:-1;13417:26:10;;;;13409:90;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13558:7;13549:4;13540:5;13526:10;:19;;13525:28;13524:41;;13507:164;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13313:483;13693:79;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13313:483;13802:19;;12664:1162;;;;;;:::o;541:398:12:-;602:4;854:21;;890:15;;;;;:43;;-1:-1:-1;206:66:12;909:24;;;882:52;-1:-1:-1;;541:398:12:o;1419:158:14:-;1477:7;1504:5;;;1523:6;;;;1515:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15216:243:10;15319:4;15335:42;;;15351:26;15335:42;15331:74;;;-1:-1:-1;15394:4:10;15387:11;;15331:74;427:31:13;411:47;;;;15417:37:10;306:157:13:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:198:29;84:20;;144:42;133:54;;123:65;;113:2;;202:1;199;192:12;217:400;;;350:3;343:4;335:6;331:17;327:27;317:2;;373:6;365;358:22;317:2;-1:-1:-1;401:20:29;;444:18;433:30;;430:2;;;483:8;473;466:26;430:2;527:4;519:6;515:17;503:29;;590:3;583:4;575;567:6;563:17;555:6;551:30;547:41;544:50;541:2;;;607:1;604;597:12;622:692;;735:3;728:4;720:6;716:17;712:27;702:2;;757:5;750;743:20;702:2;801:6;788:20;826:69;841:53;887:6;841:53;:::i;:::-;826:69;:::i;:::-;929:21;;;817:78;-1:-1:-1;969:4:29;989:14;;;;1023:15;;;1069;;;1057:28;;1053:37;;1050:46;-1:-1:-1;1047:2:29;;;1109:1;1106;1099:12;1047:2;1131:1;1141:167;1155:6;1152:1;1149:13;1141:167;;;1216:17;;1204:30;;1254:12;;;;1286;;;;1177:1;1170:9;1141:167;;;1145:3;;;;;692:622;;;;:::o;1319:377::-;;;1436:3;1429:4;1421:6;1417:17;1413:27;1403:2;;1461:8;1451;1444:26;1403:2;-1:-1:-1;1491:20:29;;1534:18;1523:30;;1520:2;;;1573:8;1563;1556:26;1520:2;1617:4;1609:6;1605:17;1593:29;;1669:3;1662:4;1653:6;1645;1641:19;1637:30;1634:39;1631:2;;;1686:1;1683;1676:12;1701:580;;1798:3;1791:4;1783:6;1779:17;1775:27;1765:2;;1820:5;1813;1806:20;1765:2;1864:6;1851:20;1894:18;1886:6;1883:30;1880:2;;;1916:9;1880:2;1945:117;2056:4;1987:66;1980:4;1972:6;1968:17;1964:90;1960:101;1945:117;:::i;:::-;1936:126;;2085:6;2078:5;2071:21;2139:3;2132:4;2123:6;2115;2111:19;2107:30;2104:39;2101:2;;;2156:1;2153;2146:12;2101:2;2219:6;2212:4;2204:6;2200:17;2193:4;2186:5;2182:16;2169:57;2273:1;2246:18;;;2266:4;2242:29;2235:40;2250:5;1755:526;-1:-1:-1;;1755:526:29:o;2286:173::-;2355:20;;2415:18;2404:30;;2394:41;;2384:2;;2449:1;2446;2439:12;2464:198;;2576:2;2564:9;2555:7;2551:23;2547:32;2544:2;;;2597:6;2589;2582:22;2544:2;2625:31;2646:9;2625:31;:::i;2667:274::-;;;2796:2;2784:9;2775:7;2771:23;2767:32;2764:2;;;2817:6;2809;2802:22;2764:2;2845:31;2866:9;2845:31;:::i;:::-;2835:41;;2895:40;2931:2;2920:9;2916:18;2895:40;:::i;:::-;2885:50;;2754:187;;;;;:::o;2946:1001::-;;;;;;3185:3;3173:9;3164:7;3160:23;3156:33;3153:2;;;3207:6;3199;3192:22;3153:2;3235:31;3256:9;3235:31;:::i;:::-;3225:41;;3285:40;3321:2;3310:9;3306:18;3285:40;:::i;:::-;3275:50;;3376:2;3365:9;3361:18;3348:32;3399:18;3440:2;3432:6;3429:14;3426:2;;;3461:6;3453;3446:22;3426:2;3489:67;3548:7;3539:6;3528:9;3524:22;3489:67;:::i;:::-;3479:77;;3609:2;3598:9;3594:18;3581:32;3565:48;;3638:2;3628:8;3625:16;3622:2;;;3659:6;3651;3644:22;3622:2;3687:69;3748:7;3737:8;3726:9;3722:24;3687:69;:::i;:::-;3677:79;;3809:3;3798:9;3794:19;3781:33;3765:49;;3839:2;3829:8;3826:16;3823:2;;;3860:6;3852;3845:22;3823:2;;3888:53;3933:7;3922:8;3911:9;3907:24;3888:53;:::i;:::-;3878:63;;;3143:804;;;;;;;;:::o;3952:632::-;;;;;;4141:3;4129:9;4120:7;4116:23;4112:33;4109:2;;;4163:6;4155;4148:22;4109:2;4191:31;4212:9;4191:31;:::i;:::-;4181:41;;4241:40;4277:2;4266:9;4262:18;4241:40;:::i;:::-;4231:50;;4328:2;4317:9;4313:18;4300:32;4290:42;;4379:2;4368:9;4364:18;4351:32;4341:42;;4434:3;4423:9;4419:19;4406:33;4462:18;4454:6;4451:30;4448:2;;;4499:6;4491;4484:22;4448:2;4527:51;4570:7;4561:6;4550:9;4546:22;4527:51;:::i;4589:924::-;;;;;4811:3;4799:9;4790:7;4786:23;4782:33;4779:2;;;4833:6;4825;4818:22;4779:2;4861:31;4882:9;4861:31;:::i;:::-;4851:41;;4943:2;4932:9;4928:18;4915:32;4966:18;5007:2;4999:6;4996:14;4993:2;;;5028:6;5020;5013:22;4993:2;5056:67;5115:7;5106:6;5095:9;5091:22;5056:67;:::i;:::-;5046:77;;5176:2;5165:9;5161:18;5148:32;5132:48;;5205:2;5195:8;5192:16;5189:2;;;5226:6;5218;5211:22;5189:2;5254:69;5315:7;5304:8;5293:9;5289:24;5254:69;:::i;:::-;5244:79;;5376:2;5365:9;5361:18;5348:32;5332:48;;5405:2;5395:8;5392:16;5389:2;;;5426:6;5418;5411:22;5389:2;;5454:53;5499:7;5488:8;5477:9;5473:24;5454:53;:::i;:::-;5444:63;;;4769:744;;;;;;;:::o;5518:369::-;;;5644:2;5632:9;5623:7;5619:23;5615:32;5612:2;;;5665:6;5657;5650:22;5612:2;5693:31;5714:9;5693:31;:::i;:::-;5683:41;;5774:2;5763:9;5759:18;5746:32;5821:5;5814:13;5807:21;5800:5;5797:32;5787:2;;5848:6;5840;5833:22;5787:2;5876:5;5866:15;;;5602:285;;;;;:::o;5892:266::-;;;6021:2;6009:9;6000:7;5996:23;5992:32;5989:2;;;6042:6;6034;6027:22;5989:2;6070:31;6091:9;6070:31;:::i;:::-;6060:41;6148:2;6133:18;;;;6120:32;;-1:-1:-1;;;5979:179:29:o;6163:644::-;;;;;;6345:3;6333:9;6324:7;6320:23;6316:33;6313:2;;;6367:6;6359;6352:22;6313:2;6395:31;6416:9;6395:31;:::i;:::-;6385:41;;6473:2;6462:9;6458:18;6445:32;6435:42;;6524:2;6513:9;6509:18;6496:32;6486:42;;6579:2;6568:9;6564:18;6551:32;6606:18;6598:6;6595:30;6592:2;;;6643:6;6635;6628:22;6592:2;6687:60;6739:7;6730:6;6719:9;6715:22;6687:60;:::i;:::-;6303:504;;;;-1:-1:-1;6303:504:29;;-1:-1:-1;6766:8:29;;6661:86;6303:504;-1:-1:-1;;;6303:504:29:o;6812:496::-;;;;;;6988:3;6976:9;6967:7;6963:23;6959:33;6956:2;;;7010:6;7002;6995:22;6956:2;7038:31;7059:9;7038:31;:::i;:::-;7028:41;;7088:39;7123:2;7112:9;7108:18;7088:39;:::i;:::-;7078:49;;7146:39;7181:2;7170:9;7166:18;7146:39;:::i;:::-;7136:49;;7204:39;7239:2;7228:9;7224:18;7204:39;:::i;:::-;7194:49;;7262:40;7297:3;7286:9;7282:19;7262:40;:::i;:::-;7252:50;;6946:362;;;;;;;;:::o;7313:1246::-;;;7492:2;7480:9;7471:7;7467:23;7463:32;7460:2;;;7513:6;7505;7498:22;7460:2;7558:9;7545:23;7587:18;7628:2;7620:6;7617:14;7614:2;;;7649:6;7641;7634:22;7614:2;7692:6;7681:9;7677:22;7667:32;;7737:7;7730:4;7726:2;7722:13;7718:27;7708:2;;7764:6;7756;7749:22;7708:2;7809;7796:16;7832:69;7847:53;7893:6;7847:53;:::i;7832:69::-;7923:3;7947:6;7942:3;7935:19;7973:4;8002:2;7997:3;7993:12;7986:19;;8033:2;8029;8025:11;8086:7;8081:2;8075;8067:6;8063:15;8059:2;8055:24;8051:33;8048:46;8045:2;;;8112:6;8104;8097:22;8045:2;8139:6;8130:15;;8154:175;8168:6;8165:1;8162:13;8154:175;;;8229:25;8250:3;8229:25;:::i;:::-;8217:38;;8190:1;8183:9;;;;;8275:12;;;;8307;;8154:175;;;-1:-1:-1;8348:5:29;;-1:-1:-1;8391:18:29;;8378:32;;-1:-1:-1;;;8422:16:29;;;8419:2;;;8456:6;8448;8441:22;8419:2;;8484:69;8545:7;8534:8;8523:9;8519:24;8484:69;:::i;:::-;8474:79;;;7450:1109;;;;;:::o;8564:463::-;;;8711:2;8699:9;8690:7;8686:23;8682:32;8679:2;;;8732:6;8724;8717:22;8679:2;8777:9;8764:23;8810:18;8802:6;8799:30;8796:2;;;8847:6;8839;8832:22;8796:2;8891:76;8959:7;8950:6;8939:9;8935:22;8891:76;:::i;:::-;8986:8;;8865:102;;-1:-1:-1;8669:358:29;-1:-1:-1;;;;8669:358:29:o;9032:815::-;;;;;9231:2;9219:9;9210:7;9206:23;9202:32;9199:2;;;9252:6;9244;9237:22;9199:2;9297:9;9284:23;9326:18;9367:2;9359:6;9356:14;9353:2;;;9388:6;9380;9373:22;9353:2;9432:76;9500:7;9491:6;9480:9;9476:22;9432:76;:::i;:::-;9527:8;;-1:-1:-1;9406:102:29;-1:-1:-1;9615:2:29;9600:18;;9587:32;;-1:-1:-1;9631:16:29;;;9628:2;;;9665:6;9657;9650:22;9628:2;;9709:78;9779:7;9768:8;9757:9;9753:24;9709:78;:::i;:::-;9189:658;;;;-1:-1:-1;9806:8:29;-1:-1:-1;;;;9189:658:29:o;9852:352::-;;9963:2;9951:9;9942:7;9938:23;9934:32;9931:2;;;9984:6;9976;9969:22;9931:2;10028:9;10015:23;10078:66;10071:5;10067:78;10060:5;10057:89;10047:2;;10165:6;10157;10150:22;10209:432;;;10341:2;10329:9;10320:7;10316:23;10312:32;10309:2;;;10362:6;10354;10347:22;10309:2;10407:9;10394:23;10440:18;10432:6;10429:30;10426:2;;;10477:6;10469;10462:22;10426:2;10521:60;10573:7;10564:6;10553:9;10549:22;10521:60;:::i;10646:670::-;;10786:3;10774:9;10765:7;10761:23;10757:33;10754:2;;;10808:6;10800;10793:22;10754:2;10846;10840:9;10888:3;10880:6;10876:16;10958:6;10946:10;10943:22;10922:18;10910:10;10907:34;10904:62;10901:2;;;10969:9;10901:2;10996;10989:22;11035:30;11055:9;11035:30;:::i;:::-;11027:6;11020:46;11099:39;11134:2;11123:9;11119:18;11099:39;:::i;:::-;11094:2;11086:6;11082:15;11075:64;11172:39;11207:2;11196:9;11192:18;11172:39;:::i;:::-;11167:2;11159:6;11155:15;11148:64;11245:39;11280:2;11269:9;11265:18;11245:39;:::i;:::-;11240:2;11228:15;;11221:64;11232:6;10744:572;-1:-1:-1;;;10744:572:29:o;11321:190::-;;11433:2;11421:9;11412:7;11408:23;11404:32;11401:2;;;11454:6;11446;11439:22;11401:2;-1:-1:-1;11482:23:29;;11391:120;-1:-1:-1;11391:120:29:o;11516:258::-;;;11645:2;11633:9;11624:7;11620:23;11616:32;11613:2;;;11666:6;11658;11651:22;11613:2;-1:-1:-1;;11694:23:29;;;11764:2;11749:18;;;11736:32;;-1:-1:-1;11603:171:29:o;11779:416::-;;11885:6;11880:3;11873:19;11915:66;11907:6;11904:78;11901:2;;;11997:3;11992;11985:16;11901:2;12040:4;12032:6;12028:17;12090:8;12083:5;12076:4;12071:3;12067:14;12054:45;12122:18;;;;12142:4;12118:29;12156:15;;;-1:-1:-1;12118:29:29;;11863:332;-1:-1:-1;11863:332:29:o;12200:339::-;12320:12;;12277:18;12316:21;;;12304:34;;12391:4;12380:16;;;12374:23;12370:32;;12354:14;;;12347:56;12456:4;12445:16;;;12439:23;12435:32;;12419:14;;;12412:56;12521:4;12510:16;;;12504:23;12500:32;12484:14;;12477:56;12257:282::o;12544:226::-;12720:42;12708:55;;;;12690:74;;12678:2;12663:18;;12645:125::o;12775:297::-;12979:42;12967:55;;;;12949:74;;13054:2;13039:18;;13032:34;12937:2;12922:18;;12904:168::o;13077:718::-;13304:2;13356:21;;;13426:13;;13329:18;;;13448:22;;;13077:718;;13304:2;13527:15;;;;13501:2;13486:18;;;13077:718;13573:196;13587:6;13584:1;13581:13;13573:196;;;13636:51;13683:3;13674:6;13668:13;13636:51;:::i;:::-;13744:15;;;;13716:4;13707:14;;;;;13609:1;13602:9;13573:196;;;-1:-1:-1;13786:3:29;;13284:511;-1:-1:-1;;;;;;13284:511:29:o;13800:531::-;;14077:2;14066:9;14059:21;14103:79;14178:2;14167:9;14163:18;14155:6;14147;14103:79;:::i;:::-;14230:9;14222:6;14218:22;14213:2;14202:9;14198:18;14191:50;14258:67;14318:6;14310;14302;14258:67;:::i;:::-;14250:75;14049:282;-1:-1:-1;;;;;;;14049:282:29:o;14336:635::-;14507:2;14559:21;;;14629:13;;14532:18;;;14651:22;;;14336:635;;14507:2;14730:15;;;;14704:2;14689:18;;;14336:635;14776:169;14790:6;14787:1;14784:13;14776:169;;;14851:13;;14839:26;;14920:15;;;;14885:12;;;;14812:1;14805:9;14776:169;;14976:187;15141:14;;15134:22;15116:41;;15104:2;15089:18;;15071:92::o;15168:662::-;;15309:2;15338;15327:9;15320:21;15370:6;15364:13;15413:6;15408:2;15397:9;15393:18;15386:34;15438:4;15451:140;15465:6;15462:1;15459:13;15451:140;;;15560:14;;;15556:23;;15550:30;15526:17;;;15545:2;15522:26;15515:66;15480:10;;15451:140;;;15609:6;15606:1;15603:13;15600:2;;;15679:4;15674:2;15665:6;15654:9;15650:22;15646:31;15639:45;15600:2;-1:-1:-1;15746:2:29;15734:15;15751:66;15730:88;15715:104;;;;15821:2;15711:113;;15289:541;-1:-1:-1;;;15289:541:29:o;15835:414::-;16037:2;16019:21;;;16076:2;16056:18;;;16049:30;16115:34;16110:2;16095:18;;16088:62;16186:20;16181:2;16166:18;;16159:48;16239:3;16224:19;;16009:240::o;16254:418::-;16456:2;16438:21;;;16495:2;16475:18;;;16468:30;16534:34;16529:2;16514:18;;16507:62;16605:24;16600:2;16585:18;;16578:52;16662:3;16647:19;;16428:244::o;16677:342::-;16879:2;16861:21;;;16918:2;16898:18;;;16891:30;16957:20;16952:2;16937:18;;16930:48;17010:2;16995:18;;16851:168::o;17024:412::-;17226:2;17208:21;;;17265:2;17245:18;;;17238:30;17304:34;17299:2;17284:18;;17277:62;17375:18;17370:2;17355:18;;17348:46;17426:3;17411:19;;17198:238::o;17441:411::-;17643:2;17625:21;;;17682:2;17662:18;;;17655:30;17721:34;17716:2;17701:18;;17694:62;17792:17;17787:2;17772:18;;17765:45;17842:3;17827:19;;17615:237::o;17857:406::-;18059:2;18041:21;;;18098:2;18078:18;;;18071:30;18137:34;18132:2;18117:18;;18110:62;18208:12;18203:2;18188:18;;18181:40;18253:3;18238:19;;18031:232::o;18268:424::-;18470:2;18452:21;;;18509:2;18489:18;;;18482:30;18548:34;18543:2;18528:18;;18521:62;18619:30;18614:2;18599:18;;18592:58;18682:3;18667:19;;18442:250::o;18697:409::-;18899:2;18881:21;;;18938:2;18918:18;;;18911:30;18977:34;18972:2;18957:18;;18950:62;19048:15;19043:2;19028:18;;19021:43;19096:3;19081:19;;18871:235::o;19111:421::-;19313:2;19295:21;;;19352:2;19332:18;;;19325:30;19391:34;19386:2;19371:18;;19364:62;19462:27;19457:2;19442:18;;19435:55;19522:3;19507:19;;19285:247::o;19537:477::-;19739:2;19721:21;;;19778:2;19758:18;;;19751:30;19817:34;19812:2;19797:18;;19790:62;19888:34;19883:2;19868:18;;19861:62;19960:11;19954:3;19939:19;;19932:40;20004:3;19989:19;;19711:303::o;20019:402::-;20221:2;20203:21;;;20260:2;20240:18;;;20233:30;20299:34;20294:2;20279:18;;20272:62;20370:8;20365:2;20350:18;;20343:36;20411:3;20396:19;;20193:228::o;20426:417::-;20628:2;20610:21;;;20667:2;20647:18;;;20640:30;20706:34;20701:2;20686:18;;20679:62;20777:23;20772:2;20757:18;;20750:51;20833:3;20818:19;;20600:243::o;20848:259::-;21038:3;21023:19;;21051:50;21027:9;21083:6;21051:50;:::i;21112:177::-;21258:25;;;21246:2;21231:18;;21213:76::o;21294:248::-;21468:25;;;21524:2;21509:18;;21502:34;21456:2;21441:18;;21423:119::o;21547:242::-;21617:2;21611:9;21647:17;;;21694:18;21679:34;;21715:22;;;21676:62;21673:2;;;21741:9;21673:2;21768;21761:22;21591:198;;-1:-1:-1;21591:198:29:o;21794:183::-;;21893:18;21885:6;21882:30;21879:2;;;21915:9;21879:2;-1:-1:-1;21966:4:29;21947:17;;;21943:28;;21869:108::o
Swarm Source
ipfs://fb1372790e40e3e548bbc115377592682a7efd66fc87555aa190c17a7e2027e8
Loading...
Loading
Loading...
Loading
OVERVIEW
A trading card game from another dimension.Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ 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.