Overview
GLMR Balance
GLMR Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| 0x640eeeaf7f02246553af1f28c9ac709e628cbbb22a0a2a82635740796dbf2350 | - | (pending) | 7 secs ago | IN | 0 GLMR | (Pending) | |||
| Submit Score | 14101023 | 38 secs ago | IN | 0 GLMR | 0.00399775 | ||||
| Submit Score | 14101021 | 1 min ago | IN | 0 GLMR | 0.00399775 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.00169053 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.0016909 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.00169053 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.00169015 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.0016909 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.00169053 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.00169053 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.00169053 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.00169053 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.0016909 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.0016909 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.00176425 | ||||
| Submit Score | 14101020 | 1 min ago | IN | 0 GLMR | 0.00399775 | ||||
| Submit Score | 14101019 | 1 min ago | IN | 0 GLMR | 0.00399775 | ||||
| Submit Score | 14101008 | 2 mins ago | IN | 0 GLMR | 0.00399775 | ||||
| Submit Score | 14101000 | 3 mins ago | IN | 0 GLMR | 0.0016909 | ||||
| Submit Score | 14101000 | 3 mins ago | IN | 0 GLMR | 0.00169053 | ||||
| Submit Score | 14101000 | 3 mins ago | IN | 0 GLMR | 0.0016909 | ||||
| Submit Score | 14101000 | 3 mins ago | IN | 0 GLMR | 0.0016909 | ||||
| Submit Score | 14101000 | 3 mins ago | IN | 0 GLMR | 0.00169053 | ||||
| Submit Score | 14101000 | 3 mins ago | IN | 0 GLMR | 0.00185775 | ||||
| Submit Score | 14101000 | 3 mins ago | IN | 0 GLMR | 0.00399775 |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
Leaderboards
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
No with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import {AccessControl} from "../lib/openzeppelin-contracts/contracts/access/AccessControl.sol";
import {Pausable} from "../lib/openzeppelin-contracts/contracts/utils/Pausable.sol";
contract Leaderboards is AccessControl, Pausable {
bytes32 public constant UPDATER_ROLE = keccak256("UPDATER_ROLE");
bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
// Global maximum reasonable score to prevent errors/bugs (default for all boards)
uint256 public constant MAX_REASONABLE_SCORE = 1e18;
/**
* @dev Score entry struct (metadata stored separately for gas efficiency)
*/
struct ScoreEntry {
address player;
uint256 score;
uint256 timestamp;
}
// Mapping: boardName => array of score entries
mapping(string => ScoreEntry[]) private boardScores;
// Mapping: boardName => player address => their latest score index
mapping(string => mapping(address => uint256)) private playerLatestScoreIndex;
// Mapping: boardName => player address => whether they have a score
mapping(string => mapping(address => bool)) private playerHasScore;
// Separate metadata storage for gas efficiency
mapping(string => mapping(address => bytes)) private playerMetadata;
// Per-board maximum scores (0 = use global default)
mapping(string => uint256) private boardMaxScore;
event ScoreSubmitted(
string indexed boardName,
address indexed player,
uint256 score,
uint256 timestamp,
bool isAccumulative
);
event MetadataUpdated(string indexed boardName, address indexed player, bytes metadata);
event UpdaterRoleGranted(address indexed account, address indexed granter);
event UpdaterRoleRevoked(address indexed account, address indexed revoker);
event ScoreRemoved(string indexed boardName, address indexed player);
event BoardCleared(string indexed boardName, uint256 entriesRemoved);
event BoardMaxScoreSet(string indexed boardName, uint256 maxScore);
constructor() {
_grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
_grantRole(UPDATER_ROLE, msg.sender);
_grantRole(PAUSER_ROLE, msg.sender);
}
/**
* @dev Submit a score to a leaderboard
* @param boardName The name of the leaderboard
* @param player The address of the player
* @param score The score value
* @param metadata Optional metadata encoded as bytes (use abi.encode for structured data)
* @param isAccumulative If true, adds to existing score; if false, replaces existing score
*/
function submitScore(
string memory boardName,
address player,
uint256 score,
bytes memory metadata,
bool isAccumulative
) external onlyRole(UPDATER_ROLE) whenNotPaused {
require(bytes(boardName).length > 0, "Board name required");
require(player != address(0), "Invalid player address");
// Get board-specific limit, or global default if not set
uint256 maxScore = boardMaxScore[boardName];
if (maxScore == 0) {
maxScore = MAX_REASONABLE_SCORE;
}
// Check input score is within limit
require(score <= maxScore, "Score exceeds maximum");
uint256 finalScore = score;
// If player already has a score
if (playerHasScore[boardName][player]) {
uint256 existingIndex = playerLatestScoreIndex[boardName][player];
// If accumulative mode, add to existing score
if (isAccumulative) {
uint256 existingScore = boardScores[boardName][existingIndex].score;
// Handle overflow by capping at max value
unchecked {
finalScore = existingScore + score;
if (finalScore < existingScore) {
finalScore = type(uint256).max;
}
}
}
// Check final accumulated score is within limit
require(finalScore <= maxScore, "Score exceeds maximum");
// Update existing entry in place
boardScores[boardName][existingIndex].score = finalScore;
boardScores[boardName][existingIndex].timestamp = block.timestamp;
emit ScoreSubmitted(boardName, player, finalScore, block.timestamp, isAccumulative);
} else {
// First time submitting score - add new entry
// Final score already checked above, so no need to recheck here
ScoreEntry memory entry =
ScoreEntry({player: player, score: finalScore, timestamp: block.timestamp});
boardScores[boardName].push(entry);
uint256 newIndex = boardScores[boardName].length - 1;
playerLatestScoreIndex[boardName][player] = newIndex;
playerHasScore[boardName][player] = true;
emit ScoreSubmitted(boardName, player, finalScore, block.timestamp, isAccumulative);
}
// Update metadata separately if provided
if (metadata.length > 0) {
playerMetadata[boardName][player] = metadata;
emit MetadataUpdated(boardName, player, metadata);
}
}
/**
* @dev Get all scores for a leaderboard
* WARNING: May be gas-expensive or fail for boards with many players. Use getBoardScoresPaginated instead.
* @param boardName The name of the leaderboard
* @return Array of score entries
*/
function getBoardScores(string memory boardName) external view returns (ScoreEntry[] memory) {
return boardScores[boardName];
}
/**
* @dev Get paginated scores for a leaderboard (gas-efficient for large boards)
* @param boardName The name of the leaderboard
* @param offset Starting index
* @param limit Maximum number of entries to return
* @return Array of score entries
*/
function getBoardScoresPaginated(string memory boardName, uint256 offset, uint256 limit)
external
view
returns (ScoreEntry[] memory)
{
uint256 totalScores = boardScores[boardName].length;
if (offset >= totalScores) {
return new ScoreEntry[](0);
}
uint256 end = offset + limit;
if (end > totalScores) {
end = totalScores;
}
uint256 resultLength = end - offset;
ScoreEntry[] memory result = new ScoreEntry[](resultLength);
for (uint256 i = 0; i < resultLength; i++) {
result[i] = boardScores[boardName][offset + i];
}
return result;
}
/**
* @dev Get the total number of scores on a leaderboard
* @param boardName The name of the leaderboard
* @return The number of score entries
*/
function getBoardScoreCount(string memory boardName) external view returns (uint256) {
return boardScores[boardName].length;
}
/**
* @dev Get a specific score entry by index
* @param boardName The name of the leaderboard
* @param index The index of the score entry
* @return The score entry
*/
function getScoreByIndex(string memory boardName, uint256 index) external view returns (ScoreEntry memory) {
require(index < boardScores[boardName].length, "Index out of bounds");
return boardScores[boardName][index];
}
/**
* @dev Get the latest score for a specific player on a board
* @param boardName The name of the leaderboard
* @param player The player's address
* @return The latest score entry for the player
*/
function getPlayerLatestScore(string memory boardName, address player)
external
view
returns (ScoreEntry memory)
{
require(playerHasScore[boardName][player], "Player has no score on this board");
uint256 index = playerLatestScoreIndex[boardName][player];
return boardScores[boardName][index];
}
/**
* @dev Get metadata for a specific player on a board
* @param boardName The name of the leaderboard
* @param player The player's address
* @return The player's metadata as bytes (use abi.decode to unpack)
*/
function getPlayerMetadata(string memory boardName, address player) external view returns (bytes memory) {
return playerMetadata[boardName][player];
}
/**
* @dev Check if a player has a score on a board
* @param boardName The name of the leaderboard
* @param player The player's address
* @return True if player has submitted a score
*/
function hasPlayerScore(string memory boardName, address player) external view returns (bool) {
return playerHasScore[boardName][player];
}
/**
* @dev Get a player's rank on the leaderboard (1-indexed)
* @param boardName The name of the leaderboard
* @param player The player's address
* @return rank The player's rank (1 = highest score), 0 if not on board
* NOTE: O(n) operation - may be gas-expensive for very large boards
*/
function getPlayerRank(string memory boardName, address player) external view returns (uint256 rank) {
if (!playerHasScore[boardName][player]) {
return 0;
}
uint256 playerScore = boardScores[boardName][playerLatestScoreIndex[boardName][player]].score;
uint256 betterScores = 0;
uint256 length = boardScores[boardName].length;
// Count how many players have a better score
for (uint256 i = 0; i < length; i++) {
if (boardScores[boardName][i].score > playerScore) {
betterScores++;
}
}
return betterScores + 1; // 1-indexed rank
}
/**
* @dev Remove a player's score from a leaderboard (for handling cheaters/errors)
* @param boardName The name of the leaderboard
* @param player The player's address
*/
function removePlayerScore(string memory boardName, address player) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(playerHasScore[boardName][player], "Player has no score");
uint256 indexToRemove = playerLatestScoreIndex[boardName][player];
uint256 lastIndex = boardScores[boardName].length - 1;
// Move last element to the removed position (if not already last)
if (indexToRemove != lastIndex) {
boardScores[boardName][indexToRemove] = boardScores[boardName][lastIndex];
// Update the moved player's index
address movedPlayer = boardScores[boardName][indexToRemove].player;
playerLatestScoreIndex[boardName][movedPlayer] = indexToRemove;
}
// Remove last element
boardScores[boardName].pop();
// Clear player's data
delete playerHasScore[boardName][player];
delete playerLatestScoreIndex[boardName][player];
delete playerMetadata[boardName][player];
emit ScoreRemoved(boardName, player);
}
/**
* @dev Clear all scores from a leaderboard (for new seasons/competitions)
* @param boardName The name of the leaderboard to clear
*/
function clearBoard(string memory boardName) external onlyRole(DEFAULT_ADMIN_ROLE) {
uint256 count = boardScores[boardName].length;
// Clear all player mappings
for (uint256 i = 0; i < count; i++) {
address player = boardScores[boardName][i].player;
delete playerHasScore[boardName][player];
delete playerLatestScoreIndex[boardName][player];
delete playerMetadata[boardName][player];
}
// Clear the scores array
delete boardScores[boardName];
emit BoardCleared(boardName, count);
}
/**
* @dev Set maximum score for a specific board (overrides global default)
* @param boardName The name of the leaderboard
* @param maxScore Maximum allowed score (0 = use global default)
*/
function setBoardMaxScore(string memory boardName, uint256 maxScore) external onlyRole(DEFAULT_ADMIN_ROLE) {
require(bytes(boardName).length > 0, "Board name required");
boardMaxScore[boardName] = maxScore;
emit BoardMaxScoreSet(boardName, maxScore);
}
/**
* @dev Get maximum score for a specific board
* @param boardName The name of the leaderboard
* @return Maximum allowed score (returns global default if board-specific not set)
*/
function getBoardMaxScore(string memory boardName) external view returns (uint256) {
uint256 boardLimit = boardMaxScore[boardName];
return boardLimit > 0 ? boardLimit : MAX_REASONABLE_SCORE;
}
/**
* @dev Pause the contract
*/
function pause() external onlyRole(PAUSER_ROLE) {
_pause();
}
/**
* @dev Unpause the contract
*/
function unpause() external onlyRole(PAUSER_ROLE) {
_unpause();
}
/**
* @dev Grant updater role to an address
* @param account The address to grant the role to
*/
function grantUpdaterRole(address account) external onlyRole(DEFAULT_ADMIN_ROLE) {
grantRole(UPDATER_ROLE, account);
emit UpdaterRoleGranted(account, msg.sender);
}
/**
* @dev Revoke updater role from an address
* @param account The address to revoke the role from
*/
function revokeUpdaterRole(address account) external onlyRole(DEFAULT_ADMIN_ROLE) {
revokeRole(UPDATER_ROLE, account);
emit UpdaterRoleRevoked(account, msg.sender);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (access/AccessControl.sol)
pragma solidity ^0.8.20;
import {IAccessControl} from "./IAccessControl.sol";
import {Context} from "../utils/Context.sol";
import {ERC165} from "../utils/introspection/ERC165.sol";
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address account => bool) hasRole;
bytes32 adminRole;
}
mapping(bytes32 role => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with an {AccessControlUnauthorizedAccount} error including the required role.
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual returns (bool) {
return _roles[role].hasRole[account];
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `_msgSender()`
* is missing `role`. Overriding this function changes the behavior of the {onlyRole} modifier.
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Reverts with an {AccessControlUnauthorizedAccount} error if `account`
* is missing `role`.
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert AccessControlUnauthorizedAccount(account, role);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address callerConfirmation) public virtual {
if (callerConfirmation != _msgSender()) {
revert AccessControlBadConfirmation();
}
_revokeRole(role, callerConfirmation);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Attempts to grant `role` to `account` and returns a boolean indicating if `role` was granted.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual returns (bool) {
if (!hasRole(role, account)) {
_roles[role].hasRole[account] = true;
emit RoleGranted(role, account, _msgSender());
return true;
} else {
return false;
}
}
/**
* @dev Attempts to revoke `role` from `account` and returns a boolean indicating if `role` was revoked.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual returns (bool) {
if (hasRole(role, account)) {
_roles[role].hasRole[account] = false;
emit RoleRevoked(role, account, _msgSender());
return true;
} else {
return false;
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (access/IAccessControl.sol)
pragma solidity ^0.8.20;
/**
* @dev External interface of AccessControl declared to support ERC-165 detection.
*/
interface IAccessControl {
/**
* @dev The `account` is missing a role.
*/
error AccessControlUnauthorizedAccount(address account, bytes32 neededRole);
/**
* @dev The caller of a function is not the expected one.
*
* NOTE: Don't confuse with {AccessControlUnauthorizedAccount}.
*/
error AccessControlBadConfirmation();
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted to signal this.
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call. This account bears the admin role (for the granted role).
* Expected in cases where the role was granted using the internal {AccessControl-_grantRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `callerConfirmation`.
*/
function renounceRole(bytes32 role, address callerConfirmation) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)
pragma solidity ^0.8.20;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.3.0) (utils/Pausable.sol)
pragma solidity ^0.8.20;
import {Context} from "../utils/Context.sol";
/**
* @dev Contract module which allows children to implement an emergency stop
* mechanism that can be triggered by an authorized account.
*
* This module is used through inheritance. It will make available the
* modifiers `whenNotPaused` and `whenPaused`, which can be applied to
* the functions of your contract. Note that they will not be pausable by
* simply including this module, only once the modifiers are put in place.
*/
abstract contract Pausable is Context {
bool private _paused;
/**
* @dev Emitted when the pause is triggered by `account`.
*/
event Paused(address account);
/**
* @dev Emitted when the pause is lifted by `account`.
*/
event Unpaused(address account);
/**
* @dev The operation failed because the contract is paused.
*/
error EnforcedPause();
/**
* @dev The operation failed because the contract is not paused.
*/
error ExpectedPause();
/**
* @dev Modifier to make a function callable only when the contract is not paused.
*
* Requirements:
*
* - The contract must not be paused.
*/
modifier whenNotPaused() {
_requireNotPaused();
_;
}
/**
* @dev Modifier to make a function callable only when the contract is paused.
*
* Requirements:
*
* - The contract must be paused.
*/
modifier whenPaused() {
_requirePaused();
_;
}
/**
* @dev Returns true if the contract is paused, and false otherwise.
*/
function paused() public view virtual returns (bool) {
return _paused;
}
/**
* @dev Throws if the contract is paused.
*/
function _requireNotPaused() internal view virtual {
if (paused()) {
revert EnforcedPause();
}
}
/**
* @dev Throws if the contract is not paused.
*/
function _requirePaused() internal view virtual {
if (!paused()) {
revert ExpectedPause();
}
}
/**
* @dev Triggers stopped state.
*
* Requirements:
*
* - The contract must not be paused.
*/
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
/**
* @dev Returns to normal state.
*
* Requirements:
*
* - The contract must be paused.
*/
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": false,
"runs": 200
},
"metadata": {
"bytecodeHash": "ipfs"
},
"evmVersion": "cancun",
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AccessControlBadConfirmation","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bytes32","name":"neededRole","type":"bytes32"}],"name":"AccessControlUnauthorizedAccount","type":"error"},{"inputs":[],"name":"EnforcedPause","type":"error"},{"inputs":[],"name":"ExpectedPause","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"boardName","type":"string"},{"indexed":false,"internalType":"uint256","name":"entriesRemoved","type":"uint256"}],"name":"BoardCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"boardName","type":"string"},{"indexed":false,"internalType":"uint256","name":"maxScore","type":"uint256"}],"name":"BoardMaxScoreSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"boardName","type":"string"},{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"bytes","name":"metadata","type":"bytes"}],"name":"MetadataUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"boardName","type":"string"},{"indexed":true,"internalType":"address","name":"player","type":"address"}],"name":"ScoreRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"boardName","type":"string"},{"indexed":true,"internalType":"address","name":"player","type":"address"},{"indexed":false,"internalType":"uint256","name":"score","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isAccumulative","type":"bool"}],"name":"ScoreSubmitted","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"granter","type":"address"}],"name":"UpdaterRoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"revoker","type":"address"}],"name":"UpdaterRoleRevoked","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REASONABLE_SCORE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"UPDATER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"}],"name":"clearBoard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"}],"name":"getBoardMaxScore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"}],"name":"getBoardScoreCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"}],"name":"getBoardScores","outputs":[{"components":[{"internalType":"address","name":"player","type":"address"},{"internalType":"uint256","name":"score","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"internalType":"struct Leaderboards.ScoreEntry[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"},{"internalType":"uint256","name":"offset","type":"uint256"},{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"getBoardScoresPaginated","outputs":[{"components":[{"internalType":"address","name":"player","type":"address"},{"internalType":"uint256","name":"score","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"internalType":"struct Leaderboards.ScoreEntry[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"},{"internalType":"address","name":"player","type":"address"}],"name":"getPlayerLatestScore","outputs":[{"components":[{"internalType":"address","name":"player","type":"address"},{"internalType":"uint256","name":"score","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"internalType":"struct Leaderboards.ScoreEntry","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"},{"internalType":"address","name":"player","type":"address"}],"name":"getPlayerMetadata","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"},{"internalType":"address","name":"player","type":"address"}],"name":"getPlayerRank","outputs":[{"internalType":"uint256","name":"rank","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getScoreByIndex","outputs":[{"components":[{"internalType":"address","name":"player","type":"address"},{"internalType":"uint256","name":"score","type":"uint256"},{"internalType":"uint256","name":"timestamp","type":"uint256"}],"internalType":"struct Leaderboards.ScoreEntry","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"grantUpdaterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"},{"internalType":"address","name":"player","type":"address"}],"name":"hasPlayerScore","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"},{"internalType":"address","name":"player","type":"address"}],"name":"removePlayerScore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"callerConfirmation","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeUpdaterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"},{"internalType":"uint256","name":"maxScore","type":"uint256"}],"name":"setBoardMaxScore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"boardName","type":"string"},{"internalType":"address","name":"player","type":"address"},{"internalType":"uint256","name":"score","type":"uint256"},{"internalType":"bytes","name":"metadata","type":"bytes"},{"internalType":"bool","name":"isAccumulative","type":"bool"}],"name":"submitScore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
608060405234801561000f575f5ffd5b506100225f5f1b3361008a60201b60201c565b506100537f73e573f9566d61418a34d5de3ff49360f9c51fec37f7486551670290f6285dab3361008a60201b60201c565b506100847f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a3361008a60201b60201c565b506101e9565b5f61009b838361017f60201b60201c565b6101755760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506101126101e260201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050610179565b5f90505b92915050565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f33905090565b6136e1806101f65f395ff3fe608060405234801561000f575f5ffd5b50600436106101c2575f3560e01c806391d14854116100f7578063b163917911610095578063df2b041f1161006f578063df2b041f14610512578063e1ee04b11461052e578063e63ab1e91461055e578063f27ed0331461057c576101c2565b8063b1639179146104aa578063cf9277c3146104da578063d547741f146104f6576101c2565b8063a5d2b22e116100d1578063a5d2b22e14610426578063a919a55c14610456578063ab6bd0e914610472578063ad4e0c281461048e576101c2565b806391d14854146103a8578063a217fddf146103d8578063a580c162146103f6576101c2565b806356dcd99a11610164578063617335851161013e578063617335851461030e578063743a78701461033e5780638456cb591461036e578063864aa41e14610378576101c2565b806356dcd99a146102a25780635c975abb146102c05780635e6509d7146102de576101c2565b806336568abe116101a057806336568abe146102425780633f4ba83a1461025e57806347e633801461026857806350882f6d14610286576101c2565b806301ffc9a7146101c6578063248a9ca3146101f65780632f2ff15d14610226575b5f5ffd5b6101e060048036038101906101db919061270c565b6105ac565b6040516101ed9190612751565b60405180910390f35b610210600480360381019061020b919061279d565b610625565b60405161021d91906127d7565b60405180910390f35b610240600480360381019061023b919061284a565b610641565b005b61025c6004803603810190610257919061284a565b610663565b005b6102666106de565b005b610270610713565b60405161027d91906127d7565b60405180910390f35b6102a0600480360381019061029b9190612888565b610737565b005b6102aa6107cb565b6040516102b791906128cb565b60405180910390f35b6102c86107d7565b6040516102d59190612751565b60405180910390f35b6102f860048036038101906102f39190612a20565b6107ec565b6040516103059190612b6d565b60405180910390f35b61032860048036038101906103239190612b8d565b6108ce565b6040516103359190612c27565b60405180910390f35b61035860048036038101906103539190612a20565b610a90565b60405161036591906128cb565b60405180910390f35b610376610ad2565b005b610392600480360381019061038d9190612c6a565b610b07565b60405161039f9190612c27565b60405180910390f35b6103c260048036038101906103bd919061284a565b610c29565b6040516103cf9190612751565b60405180910390f35b6103e0610c8c565b6040516103ed91906127d7565b60405180910390f35b610410600480360381019061040b9190612b8d565b610c92565b60405161041d9190612751565b60405180910390f35b610440600480360381019061043b9190612a20565b610d01565b60405161044d91906128cb565b60405180910390f35b610470600480360381019061046b9190612c6a565b610d2b565b005b61048c60048036038101906104879190612a20565b610def565b005b6104a860048036038101906104a39190612888565b611040565b005b6104c460048036038101906104bf9190612cc4565b6110d4565b6040516104d19190612b6d565b60405180910390f35b6104f460048036038101906104ef9190612df8565b6112e1565b005b610510600480360381019061050b919061284a565b6119da565b005b61052c60048036038101906105279190612b8d565b6119fc565b005b61054860048036038101906105439190612b8d565b611ef5565b6040516105559190612f07565b60405180910390f35b610566611fdf565b60405161057391906127d7565b60405180910390f35b61059660048036038101906105919190612b8d565b612003565b6040516105a391906128cb565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061061e575061061d826121c5565b5b9050919050565b5f5f5f8381526020019081526020015f20600101549050919050565b61064a82610625565b6106538161222e565b61065d8383612242565b50505050565b61066b61232b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106cf576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106d98282612332565b505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6107088161222e565b61071061241b565b50565b7f73e573f9566d61418a34d5de3ff49360f9c51fec37f7486551670290f6285dab81565b5f5f1b6107438161222e565b61076d7f73e573f9566d61418a34d5de3ff49360f9c51fec37f7486551670290f6285dab83610641565b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fc3cbb017b6134dcff925256e44f1a24ffe478aa45a5657e635ad4a7d2d013cde60405160405180910390a35050565b670de0b6b3a764000081565b5f60015f9054906101000a900460ff16905090565b60606002826040516107fe9190612f6b565b9081526020016040518091039020805480602002602001604051908101604052809291908181526020015f905b828210156108c3578382905f5260205f2090600302016040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820154815250508152602001906001019061082b565b505050509050919050565b6108d66125af565b6004836040516108e69190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1661097b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097290613001565b60405180910390fd5b5f60038460405161098c9190612f6b565b90815260200160405180910390205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490506002846040516109e89190612f6b565b90815260200160405180910390208181548110610a0857610a0761301f565b5b905f5260205f2090600302016040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201548152505091505092915050565b5f5f600683604051610aa29190612f6b565b90815260200160405180910390205490505f8111610ac857670de0b6b3a7640000610aca565b805b915050919050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610afc8161222e565b610b0461247c565b50565b610b0f6125af565b600283604051610b1f9190612f6b565b9081526020016040518091039020805490508210610b72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6990613096565b60405180910390fd5b600283604051610b829190612f6b565b90815260200160405180910390208281548110610ba257610ba161301f565b5b905f5260205f2090600302016040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481525050905092915050565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f1b81565b5f600483604051610ca39190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f600282604051610d129190612f6b565b9081526020016040518091039020805490509050919050565b5f5f1b610d378161222e565b5f835111610d7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d71906130fe565b60405180910390fd5b81600684604051610d8b9190612f6b565b90815260200160405180910390208190555082604051610dab9190612f6b565b60405180910390207f0beb791a4486d346f3ac5cf09377be95630f12f891f254e933bad3c4cc5bc11e83604051610de291906128cb565b60405180910390a2505050565b5f5f1b610dfb8161222e565b5f600283604051610e0c9190612f6b565b90815260200160405180910390208054905090505f5f90505b81811015610fc4575f600285604051610e3e9190612f6b565b90815260200160405180910390208281548110610e5e57610e5d61301f565b5b905f5260205f2090600302015f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600485604051610e9e9190612f6b565b90815260200160405180910390205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81549060ff0219169055600385604051610f069190612f6b565b90815260200160405180910390205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9055600585604051610f629190612f6b565b90815260200160405180910390205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f610fb691906125e3565b508080600101915050610e25565b50600283604051610fd59190612f6b565b90815260200160405180910390205f610fee9190612620565b82604051610ffc9190612f6b565b60405180910390207f0b9e2912189bfc009af9c7a5fdfdcc8af9ce4a0755861c78f7a45b523723a75f8260405161103391906128cb565b60405180910390a2505050565b5f5f1b61104c8161222e565b6110767f73e573f9566d61418a34d5de3ff49360f9c51fec37f7486551670290f6285dab836119da565b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f510f1d58f21e243cdcaf7e37531313418b45ad9b00187c8ca729702abf43665260405160405180910390a35050565b60605f6002856040516110e79190612f6b565b908152602001604051809103902080549050905080841061115e575f67ffffffffffffffff81111561111c5761111b6128fc565b5b60405190808252806020026020018201604052801561115557816020015b6111426125af565b81526020019060019003908161113a5790505b509150506112da565b5f838561116b9190613149565b905081811115611179578190505b5f8582611186919061317c565b90505f8167ffffffffffffffff8111156111a3576111a26128fc565b5b6040519080825280602002602001820160405280156111dc57816020015b6111c96125af565b8152602001906001900390816111c15790505b5090505f5f90505b828110156112d1576002896040516111fc9190612f6b565b908152602001604051809103902081896112169190613149565b815481106112275761122661301f565b5b905f5260205f2090600302016040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820154815250508282815181106112b9576112b861301f565b5b602002602001018190525080806001019150506111e4565b50809450505050505b9392505050565b7f73e573f9566d61418a34d5de3ff49360f9c51fec37f7486551670290f6285dab61130b8161222e565b6113136124dd565b5f865111611356576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134d906130fe565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bb906131f9565b60405180910390fd5b5f6006876040516113d59190612f6b565b90815260200160405180910390205490505f81036113f957670de0b6b3a764000090505b8085111561143c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143390613261565b60405180910390fd5b5f8590506004886040516114509190612f6b565b90815260200160405180910390205f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16156116bd575f6003896040516114bc9190612f6b565b90815260200160405180910390205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508415611584575f60028a60405161151f9190612f6b565b9081526020016040518091039020828154811061153f5761153e61301f565b5b905f5260205f209060030201600101549050878101925080831015611582577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92505b505b828211156115c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115be90613261565b60405180910390fd5b8160028a6040516115d89190612f6b565b908152602001604051809103902082815481106115f8576115f761301f565b5b905f5260205f209060030201600101819055504260028a60405161161c9190612f6b565b9081526020016040518091039020828154811061163c5761163b61301f565b5b905f5260205f209060030201600201819055508773ffffffffffffffffffffffffffffffffffffffff16896040516116749190612f6b565b60405180910390207f304f6e2b73672507ea3f0219d9d4504c2a187f6eb2303e4a10b0f97f46891a2e8442896040516116af9392919061327f565b60405180910390a3506118fb565b5f60405180606001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018381526020014281525090506002896040516117019190612f6b565b908152602001604051809103902081908060018154018082558091505060019003905f5260205f2090600302015f909190919091505f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002015550505f600160028b6040516117a39190612f6b565b9081526020016040518091039020805490506117bf919061317c565b90508060038b6040516117d29190612f6b565b90815260200160405180910390205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550600160048b6040516118319190612f6b565b90815260200160405180910390205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508873ffffffffffffffffffffffffffffffffffffffff168a6040516118b59190612f6b565b60405180910390207f304f6e2b73672507ea3f0219d9d4504c2a187f6eb2303e4a10b0f97f46891a2e85428a6040516118f09392919061327f565b60405180910390a350505b5f855111156119d057846005896040516119159190612f6b565b90815260200160405180910390205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20908161196a91906134b1565b508673ffffffffffffffffffffffffffffffffffffffff16886040516119909190612f6b565b60405180910390207fe3e72c4649c4f4b43b1d8834d53e0ef00e833cd98a2efce1157cdd3fb14541fa876040516119c79190612f07565b60405180910390a35b5050505050505050565b6119e382610625565b6119ec8161222e565b6119f68383612332565b50505050565b5f5f1b611a088161222e565b600483604051611a189190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611aad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa4906135ca565b60405180910390fd5b5f600384604051611abe9190612f6b565b90815260200160405180910390205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f6001600286604051611b1d9190612f6b565b908152602001604051809103902080549050611b39919061317c565b9050808214611cf557600285604051611b529190612f6b565b90815260200160405180910390208181548110611b7257611b7161301f565b5b905f5260205f209060030201600286604051611b8e9190612f6b565b90815260200160405180910390208381548110611bae57611bad61301f565b5b905f5260205f2090600302015f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018201548160010155600282015481600201559050505f600286604051611c459190612f6b565b90815260200160405180910390208381548110611c6557611c6461301f565b5b905f5260205f2090600302015f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600387604051611ca69190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b600285604051611d059190612f6b565b9081526020016040518091039020805480611d2357611d226135e8565b5b600190038181905f5260205f2090600302015f5f82015f6101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182015f9055600282015f905550509055600485604051611d7d9190612f6b565b90815260200160405180910390205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81549060ff0219169055600385604051611de59190612f6b565b90815260200160405180910390205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9055600585604051611e419190612f6b565b90815260200160405180910390205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f611e9591906125e3565b8373ffffffffffffffffffffffffffffffffffffffff1685604051611eba9190612f6b565b60405180910390207f96b5569f36a620f7dee2dddecfcc1fcc39b8fa7ee7331f05b9c0cc6122bae43060405160405180910390a35050505050565b6060600583604051611f079190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208054611f5b906132e1565b80601f0160208091040260200160405190810160405280929190818152602001828054611f87906132e1565b8015611fd25780601f10611fa957610100808354040283529160200191611fd2565b820191905f5260205f20905b815481529060010190602001808311611fb557829003601f168201915b5050505050905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b5f6004836040516120149190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16612076575f90506121bf565b5f6002846040516120879190612f6b565b90815260200160405180910390206003856040516120a59190612f6b565b90815260200160405180910390205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205481548110612100576120ff61301f565b5b905f5260205f2090600302016001015490505f5f90505f6002866040516121279190612f6b565b90815260200160405180910390208054905090505f5f90505b818110156121ab57836002886040516121599190612f6b565b908152602001604051809103902082815481106121795761217861301f565b5b905f5260205f20906003020160010154111561219e57828061219a90613615565b9350505b8080600101915050612140565b506001826121b99190613149565b93505050505b92915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61223f8161223a61232b565b61251e565b50565b5f61224d8383610c29565b6123215760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506122be61232b565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050612325565b5f90505b92915050565b5f33905090565b5f61233d8383610c29565b15612411575f5f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506123ae61232b565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050612415565b5f90505b92915050565b61242361256f565b5f60015f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61246561232b565b604051612472919061366b565b60405180910390a1565b6124846124dd565b6001805f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586124c661232b565b6040516124d3919061366b565b60405180910390a1565b6124e56107d7565b1561251c576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6125288282610c29565b61256b5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401612562929190613684565b60405180910390fd5b5050565b6125776107d7565b6125ad576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60405180606001604052805f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81526020015f81525090565b5080546125ef906132e1565b5f825580601f10612600575061261d565b601f0160209004905f5260205f209081019061261c9190612641565b5b50565b5080545f8255600302905f5260205f209081019061263e919061265c565b50565b5b80821115612658575f815f905550600101612642565b5090565b5b808211156126a2575f5f82015f6101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182015f9055600282015f90555060030161265d565b5090565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6126eb816126b7565b81146126f5575f5ffd5b50565b5f81359050612706816126e2565b92915050565b5f60208284031215612721576127206126af565b5b5f61272e848285016126f8565b91505092915050565b5f8115159050919050565b61274b81612737565b82525050565b5f6020820190506127645f830184612742565b92915050565b5f819050919050565b61277c8161276a565b8114612786575f5ffd5b50565b5f8135905061279781612773565b92915050565b5f602082840312156127b2576127b16126af565b5b5f6127bf84828501612789565b91505092915050565b6127d18161276a565b82525050565b5f6020820190506127ea5f8301846127c8565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612819826127f0565b9050919050565b6128298161280f565b8114612833575f5ffd5b50565b5f8135905061284481612820565b92915050565b5f5f604083850312156128605761285f6126af565b5b5f61286d85828601612789565b925050602061287e85828601612836565b9150509250929050565b5f6020828403121561289d5761289c6126af565b5b5f6128aa84828501612836565b91505092915050565b5f819050919050565b6128c5816128b3565b82525050565b5f6020820190506128de5f8301846128bc565b92915050565b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612932826128ec565b810181811067ffffffffffffffff82111715612951576129506128fc565b5b80604052505050565b5f6129636126a6565b905061296f8282612929565b919050565b5f67ffffffffffffffff82111561298e5761298d6128fc565b5b612997826128ec565b9050602081019050919050565b828183375f83830152505050565b5f6129c46129bf84612974565b61295a565b9050828152602081018484840111156129e0576129df6128e8565b5b6129eb8482856129a4565b509392505050565b5f82601f830112612a0757612a066128e4565b5b8135612a178482602086016129b2565b91505092915050565b5f60208284031215612a3557612a346126af565b5b5f82013567ffffffffffffffff811115612a5257612a516126b3565b5b612a5e848285016129f3565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b612a998161280f565b82525050565b612aa8816128b3565b82525050565b606082015f820151612ac25f850182612a90565b506020820151612ad56020850182612a9f565b506040820151612ae86040850182612a9f565b50505050565b5f612af98383612aae565b60608301905092915050565b5f602082019050919050565b5f612b1b82612a67565b612b258185612a71565b9350612b3083612a81565b805f5b83811015612b60578151612b478882612aee565b9750612b5283612b05565b925050600181019050612b33565b5085935050505092915050565b5f6020820190508181035f830152612b858184612b11565b905092915050565b5f5f60408385031215612ba357612ba26126af565b5b5f83013567ffffffffffffffff811115612bc057612bbf6126b3565b5b612bcc858286016129f3565b9250506020612bdd85828601612836565b9150509250929050565b606082015f820151612bfb5f850182612a90565b506020820151612c0e6020850182612a9f565b506040820151612c216040850182612a9f565b50505050565b5f606082019050612c3a5f830184612be7565b92915050565b612c49816128b3565b8114612c53575f5ffd5b50565b5f81359050612c6481612c40565b92915050565b5f5f60408385031215612c8057612c7f6126af565b5b5f83013567ffffffffffffffff811115612c9d57612c9c6126b3565b5b612ca9858286016129f3565b9250506020612cba85828601612c56565b9150509250929050565b5f5f5f60608486031215612cdb57612cda6126af565b5b5f84013567ffffffffffffffff811115612cf857612cf76126b3565b5b612d04868287016129f3565b9350506020612d1586828701612c56565b9250506040612d2686828701612c56565b9150509250925092565b5f67ffffffffffffffff821115612d4a57612d496128fc565b5b612d53826128ec565b9050602081019050919050565b5f612d72612d6d84612d30565b61295a565b905082815260208101848484011115612d8e57612d8d6128e8565b5b612d998482856129a4565b509392505050565b5f82601f830112612db557612db46128e4565b5b8135612dc5848260208601612d60565b91505092915050565b612dd781612737565b8114612de1575f5ffd5b50565b5f81359050612df281612dce565b92915050565b5f5f5f5f5f60a08688031215612e1157612e106126af565b5b5f86013567ffffffffffffffff811115612e2e57612e2d6126b3565b5b612e3a888289016129f3565b9550506020612e4b88828901612836565b9450506040612e5c88828901612c56565b935050606086013567ffffffffffffffff811115612e7d57612e7c6126b3565b5b612e8988828901612da1565b9250506080612e9a88828901612de4565b9150509295509295909350565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f612ed982612ea7565b612ee38185612eb1565b9350612ef3818560208601612ec1565b612efc816128ec565b840191505092915050565b5f6020820190508181035f830152612f1f8184612ecf565b905092915050565b5f81519050919050565b5f81905092915050565b5f612f4582612f27565b612f4f8185612f31565b9350612f5f818560208601612ec1565b80840191505092915050565b5f612f768284612f3b565b915081905092915050565b5f82825260208201905092915050565b7f506c6179657220686173206e6f2073636f7265206f6e207468697320626f61725f8201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b5f612feb602183612f81565b9150612ff682612f91565b604082019050919050565b5f6020820190508181035f83015261301881612fdf565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f496e646578206f7574206f6620626f756e6473000000000000000000000000005f82015250565b5f613080601383612f81565b915061308b8261304c565b602082019050919050565b5f6020820190508181035f8301526130ad81613074565b9050919050565b7f426f617264206e616d65207265717569726564000000000000000000000000005f82015250565b5f6130e8601383612f81565b91506130f3826130b4565b602082019050919050565b5f6020820190508181035f830152613115816130dc565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f613153826128b3565b915061315e836128b3565b92508282019050808211156131765761317561311c565b5b92915050565b5f613186826128b3565b9150613191836128b3565b92508282039050818111156131a9576131a861311c565b5b92915050565b7f496e76616c696420706c617965722061646472657373000000000000000000005f82015250565b5f6131e3601683612f81565b91506131ee826131af565b602082019050919050565b5f6020820190508181035f830152613210816131d7565b9050919050565b7f53636f72652065786365656473206d6178696d756d00000000000000000000005f82015250565b5f61324b601583612f81565b915061325682613217565b602082019050919050565b5f6020820190508181035f8301526132788161323f565b9050919050565b5f6060820190506132925f8301866128bc565b61329f60208301856128bc565b6132ac6040830184612742565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806132f857607f821691505b60208210810361330b5761330a6132b4565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261336d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613332565b6133778683613332565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6133b26133ad6133a8846128b3565b61338f565b6128b3565b9050919050565b5f819050919050565b6133cb83613398565b6133df6133d7826133b9565b84845461333e565b825550505050565b5f5f905090565b6133f66133e7565b6134018184846133c2565b505050565b5b81811015613424576134195f826133ee565b600181019050613407565b5050565b601f8211156134695761343a81613311565b61344384613323565b81016020851015613452578190505b61346661345e85613323565b830182613406565b50505b505050565b5f82821c905092915050565b5f6134895f198460080261346e565b1980831691505092915050565b5f6134a1838361347a565b9150826002028217905092915050565b6134ba82612ea7565b67ffffffffffffffff8111156134d3576134d26128fc565b5b6134dd82546132e1565b6134e8828285613428565b5f60209050601f831160018114613519575f8415613507578287015190505b6135118582613496565b865550613578565b601f19841661352786613311565b5f5b8281101561354e57848901518255600182019150602085019450602081019050613529565b8683101561356b5784890151613567601f89168261347a565b8355505b6001600288020188555050505b505050505050565b7f506c6179657220686173206e6f2073636f7265000000000000000000000000005f82015250565b5f6135b4601383612f81565b91506135bf82613580565b602082019050919050565b5f6020820190508181035f8301526135e1816135a8565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b5f61361f826128b3565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036136515761365061311c565b5b600182019050919050565b6136658161280f565b82525050565b5f60208201905061367e5f83018461365c565b92915050565b5f6040820190506136975f83018561365c565b6136a460208301846127c8565b939250505056fea2646970667358221220d8ead57e4750739320384d307d869f5b3b9f0948572fe5629a3394f7a839942a64736f6c634300081c0033
Deployed Bytecode
0x608060405234801561000f575f5ffd5b50600436106101c2575f3560e01c806391d14854116100f7578063b163917911610095578063df2b041f1161006f578063df2b041f14610512578063e1ee04b11461052e578063e63ab1e91461055e578063f27ed0331461057c576101c2565b8063b1639179146104aa578063cf9277c3146104da578063d547741f146104f6576101c2565b8063a5d2b22e116100d1578063a5d2b22e14610426578063a919a55c14610456578063ab6bd0e914610472578063ad4e0c281461048e576101c2565b806391d14854146103a8578063a217fddf146103d8578063a580c162146103f6576101c2565b806356dcd99a11610164578063617335851161013e578063617335851461030e578063743a78701461033e5780638456cb591461036e578063864aa41e14610378576101c2565b806356dcd99a146102a25780635c975abb146102c05780635e6509d7146102de576101c2565b806336568abe116101a057806336568abe146102425780633f4ba83a1461025e57806347e633801461026857806350882f6d14610286576101c2565b806301ffc9a7146101c6578063248a9ca3146101f65780632f2ff15d14610226575b5f5ffd5b6101e060048036038101906101db919061270c565b6105ac565b6040516101ed9190612751565b60405180910390f35b610210600480360381019061020b919061279d565b610625565b60405161021d91906127d7565b60405180910390f35b610240600480360381019061023b919061284a565b610641565b005b61025c6004803603810190610257919061284a565b610663565b005b6102666106de565b005b610270610713565b60405161027d91906127d7565b60405180910390f35b6102a0600480360381019061029b9190612888565b610737565b005b6102aa6107cb565b6040516102b791906128cb565b60405180910390f35b6102c86107d7565b6040516102d59190612751565b60405180910390f35b6102f860048036038101906102f39190612a20565b6107ec565b6040516103059190612b6d565b60405180910390f35b61032860048036038101906103239190612b8d565b6108ce565b6040516103359190612c27565b60405180910390f35b61035860048036038101906103539190612a20565b610a90565b60405161036591906128cb565b60405180910390f35b610376610ad2565b005b610392600480360381019061038d9190612c6a565b610b07565b60405161039f9190612c27565b60405180910390f35b6103c260048036038101906103bd919061284a565b610c29565b6040516103cf9190612751565b60405180910390f35b6103e0610c8c565b6040516103ed91906127d7565b60405180910390f35b610410600480360381019061040b9190612b8d565b610c92565b60405161041d9190612751565b60405180910390f35b610440600480360381019061043b9190612a20565b610d01565b60405161044d91906128cb565b60405180910390f35b610470600480360381019061046b9190612c6a565b610d2b565b005b61048c60048036038101906104879190612a20565b610def565b005b6104a860048036038101906104a39190612888565b611040565b005b6104c460048036038101906104bf9190612cc4565b6110d4565b6040516104d19190612b6d565b60405180910390f35b6104f460048036038101906104ef9190612df8565b6112e1565b005b610510600480360381019061050b919061284a565b6119da565b005b61052c60048036038101906105279190612b8d565b6119fc565b005b61054860048036038101906105439190612b8d565b611ef5565b6040516105559190612f07565b60405180910390f35b610566611fdf565b60405161057391906127d7565b60405180910390f35b61059660048036038101906105919190612b8d565b612003565b6040516105a391906128cb565b60405180910390f35b5f7f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061061e575061061d826121c5565b5b9050919050565b5f5f5f8381526020019081526020015f20600101549050919050565b61064a82610625565b6106538161222e565b61065d8383612242565b50505050565b61066b61232b565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146106cf576040517f6697b23200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106d98282612332565b505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6107088161222e565b61071061241b565b50565b7f73e573f9566d61418a34d5de3ff49360f9c51fec37f7486551670290f6285dab81565b5f5f1b6107438161222e565b61076d7f73e573f9566d61418a34d5de3ff49360f9c51fec37f7486551670290f6285dab83610641565b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fc3cbb017b6134dcff925256e44f1a24ffe478aa45a5657e635ad4a7d2d013cde60405160405180910390a35050565b670de0b6b3a764000081565b5f60015f9054906101000a900460ff16905090565b60606002826040516107fe9190612f6b565b9081526020016040518091039020805480602002602001604051908101604052809291908181526020015f905b828210156108c3578382905f5260205f2090600302016040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820154815250508152602001906001019061082b565b505050509050919050565b6108d66125af565b6004836040516108e69190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff1661097b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161097290613001565b60405180910390fd5b5f60038460405161098c9190612f6b565b90815260200160405180910390205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490506002846040516109e89190612f6b565b90815260200160405180910390208181548110610a0857610a0761301f565b5b905f5260205f2090600302016040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016001820154815260200160028201548152505091505092915050565b5f5f600683604051610aa29190612f6b565b90815260200160405180910390205490505f8111610ac857670de0b6b3a7640000610aca565b805b915050919050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a610afc8161222e565b610b0461247c565b50565b610b0f6125af565b600283604051610b1f9190612f6b565b9081526020016040518091039020805490508210610b72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b6990613096565b60405180910390fd5b600283604051610b829190612f6b565b90815260200160405180910390208281548110610ba257610ba161301f565b5b905f5260205f2090600302016040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200160018201548152602001600282015481525050905092915050565b5f5f5f8481526020019081526020015f205f015f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f5f1b81565b5f600483604051610ca39190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16905092915050565b5f600282604051610d129190612f6b565b9081526020016040518091039020805490509050919050565b5f5f1b610d378161222e565b5f835111610d7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d71906130fe565b60405180910390fd5b81600684604051610d8b9190612f6b565b90815260200160405180910390208190555082604051610dab9190612f6b565b60405180910390207f0beb791a4486d346f3ac5cf09377be95630f12f891f254e933bad3c4cc5bc11e83604051610de291906128cb565b60405180910390a2505050565b5f5f1b610dfb8161222e565b5f600283604051610e0c9190612f6b565b90815260200160405180910390208054905090505f5f90505b81811015610fc4575f600285604051610e3e9190612f6b565b90815260200160405180910390208281548110610e5e57610e5d61301f565b5b905f5260205f2090600302015f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600485604051610e9e9190612f6b565b90815260200160405180910390205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81549060ff0219169055600385604051610f069190612f6b565b90815260200160405180910390205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9055600585604051610f629190612f6b565b90815260200160405180910390205f8273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f610fb691906125e3565b508080600101915050610e25565b50600283604051610fd59190612f6b565b90815260200160405180910390205f610fee9190612620565b82604051610ffc9190612f6b565b60405180910390207f0b9e2912189bfc009af9c7a5fdfdcc8af9ce4a0755861c78f7a45b523723a75f8260405161103391906128cb565b60405180910390a2505050565b5f5f1b61104c8161222e565b6110767f73e573f9566d61418a34d5de3ff49360f9c51fec37f7486551670290f6285dab836119da565b3373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f510f1d58f21e243cdcaf7e37531313418b45ad9b00187c8ca729702abf43665260405160405180910390a35050565b60605f6002856040516110e79190612f6b565b908152602001604051809103902080549050905080841061115e575f67ffffffffffffffff81111561111c5761111b6128fc565b5b60405190808252806020026020018201604052801561115557816020015b6111426125af565b81526020019060019003908161113a5790505b509150506112da565b5f838561116b9190613149565b905081811115611179578190505b5f8582611186919061317c565b90505f8167ffffffffffffffff8111156111a3576111a26128fc565b5b6040519080825280602002602001820160405280156111dc57816020015b6111c96125af565b8152602001906001900390816111c15790505b5090505f5f90505b828110156112d1576002896040516111fc9190612f6b565b908152602001604051809103902081896112169190613149565b815481106112275761122661301f565b5b905f5260205f2090600302016040518060600160405290815f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001600182015481526020016002820154815250508282815181106112b9576112b861301f565b5b602002602001018190525080806001019150506111e4565b50809450505050505b9392505050565b7f73e573f9566d61418a34d5de3ff49360f9c51fec37f7486551670290f6285dab61130b8161222e565b6113136124dd565b5f865111611356576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161134d906130fe565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036113c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113bb906131f9565b60405180910390fd5b5f6006876040516113d59190612f6b565b90815260200160405180910390205490505f81036113f957670de0b6b3a764000090505b8085111561143c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143390613261565b60405180910390fd5b5f8590506004886040516114509190612f6b565b90815260200160405180910390205f8873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16156116bd575f6003896040516114bc9190612f6b565b90815260200160405180910390205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508415611584575f60028a60405161151f9190612f6b565b9081526020016040518091039020828154811061153f5761153e61301f565b5b905f5260205f209060030201600101549050878101925080831015611582577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff92505b505b828211156115c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115be90613261565b60405180910390fd5b8160028a6040516115d89190612f6b565b908152602001604051809103902082815481106115f8576115f761301f565b5b905f5260205f209060030201600101819055504260028a60405161161c9190612f6b565b9081526020016040518091039020828154811061163c5761163b61301f565b5b905f5260205f209060030201600201819055508773ffffffffffffffffffffffffffffffffffffffff16896040516116749190612f6b565b60405180910390207f304f6e2b73672507ea3f0219d9d4504c2a187f6eb2303e4a10b0f97f46891a2e8442896040516116af9392919061327f565b60405180910390a3506118fb565b5f60405180606001604052808973ffffffffffffffffffffffffffffffffffffffff1681526020018381526020014281525090506002896040516117019190612f6b565b908152602001604051809103902081908060018154018082558091505060019003905f5260205f2090600302015f909190919091505f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101556040820151816002015550505f600160028b6040516117a39190612f6b565b9081526020016040518091039020805490506117bf919061317c565b90508060038b6040516117d29190612f6b565b90815260200160405180910390205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550600160048b6040516118319190612f6b565b90815260200160405180910390205f8b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508873ffffffffffffffffffffffffffffffffffffffff168a6040516118b59190612f6b565b60405180910390207f304f6e2b73672507ea3f0219d9d4504c2a187f6eb2303e4a10b0f97f46891a2e85428a6040516118f09392919061327f565b60405180910390a350505b5f855111156119d057846005896040516119159190612f6b565b90815260200160405180910390205f8973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20908161196a91906134b1565b508673ffffffffffffffffffffffffffffffffffffffff16886040516119909190612f6b565b60405180910390207fe3e72c4649c4f4b43b1d8834d53e0ef00e833cd98a2efce1157cdd3fb14541fa876040516119c79190612f07565b60405180910390a35b5050505050505050565b6119e382610625565b6119ec8161222e565b6119f68383612332565b50505050565b5f5f1b611a088161222e565b600483604051611a189190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16611aad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611aa4906135ca565b60405180910390fd5b5f600384604051611abe9190612f6b565b90815260200160405180910390205f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490505f6001600286604051611b1d9190612f6b565b908152602001604051809103902080549050611b39919061317c565b9050808214611cf557600285604051611b529190612f6b565b90815260200160405180910390208181548110611b7257611b7161301f565b5b905f5260205f209060030201600286604051611b8e9190612f6b565b90815260200160405180910390208381548110611bae57611bad61301f565b5b905f5260205f2090600302015f82015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060018201548160010155600282015481600201559050505f600286604051611c459190612f6b565b90815260200160405180910390208381548110611c6557611c6461301f565b5b905f5260205f2090600302015f015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905082600387604051611ca69190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b600285604051611d059190612f6b565b9081526020016040518091039020805480611d2357611d226135e8565b5b600190038181905f5260205f2090600302015f5f82015f6101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182015f9055600282015f905550509055600485604051611d7d9190612f6b565b90815260200160405180910390205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81549060ff0219169055600385604051611de59190612f6b565b90815260200160405180910390205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9055600585604051611e419190612f6b565b90815260200160405180910390205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f611e9591906125e3565b8373ffffffffffffffffffffffffffffffffffffffff1685604051611eba9190612f6b565b60405180910390207f96b5569f36a620f7dee2dddecfcc1fcc39b8fa7ee7331f05b9c0cc6122bae43060405160405180910390a35050505050565b6060600583604051611f079190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208054611f5b906132e1565b80601f0160208091040260200160405190810160405280929190818152602001828054611f87906132e1565b8015611fd25780601f10611fa957610100808354040283529160200191611fd2565b820191905f5260205f20905b815481529060010190602001808311611fb557829003601f168201915b5050505050905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b5f6004836040516120149190612f6b565b90815260200160405180910390205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff16612076575f90506121bf565b5f6002846040516120879190612f6b565b90815260200160405180910390206003856040516120a59190612f6b565b90815260200160405180910390205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205481548110612100576120ff61301f565b5b905f5260205f2090600302016001015490505f5f90505f6002866040516121279190612f6b565b90815260200160405180910390208054905090505f5f90505b818110156121ab57836002886040516121599190612f6b565b908152602001604051809103902082815481106121795761217861301f565b5b905f5260205f20906003020160010154111561219e57828061219a90613615565b9350505b8080600101915050612140565b506001826121b99190613149565b93505050505b92915050565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61223f8161223a61232b565b61251e565b50565b5f61224d8383610c29565b6123215760015f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506122be61232b565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a460019050612325565b5f90505b92915050565b5f33905090565b5f61233d8383610c29565b15612411575f5f5f8581526020019081526020015f205f015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055506123ae61232b565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16847ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a460019050612415565b5f90505b92915050565b61242361256f565b5f60015f6101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61246561232b565b604051612472919061366b565b60405180910390a1565b6124846124dd565b6001805f6101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586124c661232b565b6040516124d3919061366b565b60405180910390a1565b6124e56107d7565b1561251c576040517fd93c066500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b6125288282610c29565b61256b5780826040517fe2517d3f000000000000000000000000000000000000000000000000000000008152600401612562929190613684565b60405180910390fd5b5050565b6125776107d7565b6125ad576040517f8dfc202b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b60405180606001604052805f73ffffffffffffffffffffffffffffffffffffffff1681526020015f81526020015f81525090565b5080546125ef906132e1565b5f825580601f10612600575061261d565b601f0160209004905f5260205f209081019061261c9190612641565b5b50565b5080545f8255600302905f5260205f209081019061263e919061265c565b50565b5b80821115612658575f815f905550600101612642565b5090565b5b808211156126a2575f5f82015f6101000a81549073ffffffffffffffffffffffffffffffffffffffff0219169055600182015f9055600282015f90555060030161265d565b5090565b5f604051905090565b5f5ffd5b5f5ffd5b5f7fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6126eb816126b7565b81146126f5575f5ffd5b50565b5f81359050612706816126e2565b92915050565b5f60208284031215612721576127206126af565b5b5f61272e848285016126f8565b91505092915050565b5f8115159050919050565b61274b81612737565b82525050565b5f6020820190506127645f830184612742565b92915050565b5f819050919050565b61277c8161276a565b8114612786575f5ffd5b50565b5f8135905061279781612773565b92915050565b5f602082840312156127b2576127b16126af565b5b5f6127bf84828501612789565b91505092915050565b6127d18161276a565b82525050565b5f6020820190506127ea5f8301846127c8565b92915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f612819826127f0565b9050919050565b6128298161280f565b8114612833575f5ffd5b50565b5f8135905061284481612820565b92915050565b5f5f604083850312156128605761285f6126af565b5b5f61286d85828601612789565b925050602061287e85828601612836565b9150509250929050565b5f6020828403121561289d5761289c6126af565b5b5f6128aa84828501612836565b91505092915050565b5f819050919050565b6128c5816128b3565b82525050565b5f6020820190506128de5f8301846128bc565b92915050565b5f5ffd5b5f5ffd5b5f601f19601f8301169050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b612932826128ec565b810181811067ffffffffffffffff82111715612951576129506128fc565b5b80604052505050565b5f6129636126a6565b905061296f8282612929565b919050565b5f67ffffffffffffffff82111561298e5761298d6128fc565b5b612997826128ec565b9050602081019050919050565b828183375f83830152505050565b5f6129c46129bf84612974565b61295a565b9050828152602081018484840111156129e0576129df6128e8565b5b6129eb8482856129a4565b509392505050565b5f82601f830112612a0757612a066128e4565b5b8135612a178482602086016129b2565b91505092915050565b5f60208284031215612a3557612a346126af565b5b5f82013567ffffffffffffffff811115612a5257612a516126b3565b5b612a5e848285016129f3565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b612a998161280f565b82525050565b612aa8816128b3565b82525050565b606082015f820151612ac25f850182612a90565b506020820151612ad56020850182612a9f565b506040820151612ae86040850182612a9f565b50505050565b5f612af98383612aae565b60608301905092915050565b5f602082019050919050565b5f612b1b82612a67565b612b258185612a71565b9350612b3083612a81565b805f5b83811015612b60578151612b478882612aee565b9750612b5283612b05565b925050600181019050612b33565b5085935050505092915050565b5f6020820190508181035f830152612b858184612b11565b905092915050565b5f5f60408385031215612ba357612ba26126af565b5b5f83013567ffffffffffffffff811115612bc057612bbf6126b3565b5b612bcc858286016129f3565b9250506020612bdd85828601612836565b9150509250929050565b606082015f820151612bfb5f850182612a90565b506020820151612c0e6020850182612a9f565b506040820151612c216040850182612a9f565b50505050565b5f606082019050612c3a5f830184612be7565b92915050565b612c49816128b3565b8114612c53575f5ffd5b50565b5f81359050612c6481612c40565b92915050565b5f5f60408385031215612c8057612c7f6126af565b5b5f83013567ffffffffffffffff811115612c9d57612c9c6126b3565b5b612ca9858286016129f3565b9250506020612cba85828601612c56565b9150509250929050565b5f5f5f60608486031215612cdb57612cda6126af565b5b5f84013567ffffffffffffffff811115612cf857612cf76126b3565b5b612d04868287016129f3565b9350506020612d1586828701612c56565b9250506040612d2686828701612c56565b9150509250925092565b5f67ffffffffffffffff821115612d4a57612d496128fc565b5b612d53826128ec565b9050602081019050919050565b5f612d72612d6d84612d30565b61295a565b905082815260208101848484011115612d8e57612d8d6128e8565b5b612d998482856129a4565b509392505050565b5f82601f830112612db557612db46128e4565b5b8135612dc5848260208601612d60565b91505092915050565b612dd781612737565b8114612de1575f5ffd5b50565b5f81359050612df281612dce565b92915050565b5f5f5f5f5f60a08688031215612e1157612e106126af565b5b5f86013567ffffffffffffffff811115612e2e57612e2d6126b3565b5b612e3a888289016129f3565b9550506020612e4b88828901612836565b9450506040612e5c88828901612c56565b935050606086013567ffffffffffffffff811115612e7d57612e7c6126b3565b5b612e8988828901612da1565b9250506080612e9a88828901612de4565b9150509295509295909350565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f612ed982612ea7565b612ee38185612eb1565b9350612ef3818560208601612ec1565b612efc816128ec565b840191505092915050565b5f6020820190508181035f830152612f1f8184612ecf565b905092915050565b5f81519050919050565b5f81905092915050565b5f612f4582612f27565b612f4f8185612f31565b9350612f5f818560208601612ec1565b80840191505092915050565b5f612f768284612f3b565b915081905092915050565b5f82825260208201905092915050565b7f506c6179657220686173206e6f2073636f7265206f6e207468697320626f61725f8201527f6400000000000000000000000000000000000000000000000000000000000000602082015250565b5f612feb602183612f81565b9150612ff682612f91565b604082019050919050565b5f6020820190508181035f83015261301881612fdf565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f496e646578206f7574206f6620626f756e6473000000000000000000000000005f82015250565b5f613080601383612f81565b915061308b8261304c565b602082019050919050565b5f6020820190508181035f8301526130ad81613074565b9050919050565b7f426f617264206e616d65207265717569726564000000000000000000000000005f82015250565b5f6130e8601383612f81565b91506130f3826130b4565b602082019050919050565b5f6020820190508181035f830152613115816130dc565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f613153826128b3565b915061315e836128b3565b92508282019050808211156131765761317561311c565b5b92915050565b5f613186826128b3565b9150613191836128b3565b92508282039050818111156131a9576131a861311c565b5b92915050565b7f496e76616c696420706c617965722061646472657373000000000000000000005f82015250565b5f6131e3601683612f81565b91506131ee826131af565b602082019050919050565b5f6020820190508181035f830152613210816131d7565b9050919050565b7f53636f72652065786365656473206d6178696d756d00000000000000000000005f82015250565b5f61324b601583612f81565b915061325682613217565b602082019050919050565b5f6020820190508181035f8301526132788161323f565b9050919050565b5f6060820190506132925f8301866128bc565b61329f60208301856128bc565b6132ac6040830184612742565b949350505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806132f857607f821691505b60208210810361330b5761330a6132b4565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f6008830261336d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82613332565b6133778683613332565b95508019841693508086168417925050509392505050565b5f819050919050565b5f6133b26133ad6133a8846128b3565b61338f565b6128b3565b9050919050565b5f819050919050565b6133cb83613398565b6133df6133d7826133b9565b84845461333e565b825550505050565b5f5f905090565b6133f66133e7565b6134018184846133c2565b505050565b5b81811015613424576134195f826133ee565b600181019050613407565b5050565b601f8211156134695761343a81613311565b61344384613323565b81016020851015613452578190505b61346661345e85613323565b830182613406565b50505b505050565b5f82821c905092915050565b5f6134895f198460080261346e565b1980831691505092915050565b5f6134a1838361347a565b9150826002028217905092915050565b6134ba82612ea7565b67ffffffffffffffff8111156134d3576134d26128fc565b5b6134dd82546132e1565b6134e8828285613428565b5f60209050601f831160018114613519575f8415613507578287015190505b6135118582613496565b865550613578565b601f19841661352786613311565b5f5b8281101561354e57848901518255600182019150602085019450602081019050613529565b8683101561356b5784890151613567601f89168261347a565b8355505b6001600288020188555050505b505050505050565b7f506c6179657220686173206e6f2073636f7265000000000000000000000000005f82015250565b5f6135b4601383612f81565b91506135bf82613580565b602082019050919050565b5f6020820190508181035f8301526135e1816135a8565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffd5b5f61361f826128b3565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036136515761365061311c565b5b600182019050919050565b6136658161280f565b82525050565b5f60208201905061367e5f83018461365c565b92915050565b5f6040820190506136975f83018561365c565b6136a460208301846127c8565b939250505056fea2646970667358221220d8ead57e4750739320384d307d869f5b3b9f0948572fe5629a3394f7a839942a64736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in GLMR
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.