Overview
S Balance
0 S
S Value
-More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
AccessControlFacet
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /************************************************************************* ___ ___ | \/ | ___ | . . | _____ _____ ___ _ _ .-' '-. | |\/| |/ _ \ \ /\ / / __|/ _ \ (.)(.)/ \ | | | | (_) \ V V /\__ \ __/ /@@ ; \_| |_/\___/ \_/\_/ |___/\___| o_\\-mm-......-mm`~~~~~~~~~~~~~~~~` /*************************************************************************/ import "@solidstate/contracts/access/access_control/AccessControl.sol"; import {AccessControlStorage} from "@solidstate/contracts/access/access_control/AccessControlStorage.sol"; import {LibDiamond} from "../libraries/LibDiamond.sol"; import {MOWSE_MINTER_ROLE, MOWSEWEAR_MINTER_ROLE, MOWSE_ADMIN_ROLE, MOWSEWEAR_ADMIN_ROLE, MOWSEGAME_ADMIN_ROLE, MOWSELOOTBOX_MINTER_ROLE, MOWSEJOB_ADMIN_ROLE} from "../libraries/LibStorage.sol"; import "./../libraries/LibStorage.sol"; contract AccessControlFacet is AccessControl { GameStorage internal gs; error MissingAdminRole(string); modifier onlyAdminOrCore() { require( msg.sender == gs.diamondAddress || msg.sender == LibDiamond.contractOwner(), "Only the Core or Admin addresses can perform this action" ); _; } modifier onlyAccessControlAdmin() { if (!_hasRole(AccessControlStorage.DEFAULT_ADMIN_ROLE, msg.sender)) revert MissingAdminRole("Missing Admin role"); _; } function hasAdminRole(address account) external view returns (bool) { return _hasRole(AccessControlStorage.DEFAULT_ADMIN_ROLE, account); } // MowseAdminRole is responsible for facet-to-facet communication function hasMowseAdminRole(address account) external view returns (bool) { return _hasRole(MOWSE_ADMIN_ROLE, account); } function hasMowseMinterRole(address account) external view returns (bool) { return _hasRole(MOWSE_MINTER_ROLE, account); } function hasMowseWearMinterRole(address account) external view returns (bool) { return _hasRole(MOWSEWEAR_MINTER_ROLE, account); } function hasMowseWearAdminRole(address account) external view returns (bool) { return _hasRole(MOWSEWEAR_ADMIN_ROLE, account); } function hasMowseGameAdminRole(address account) external view returns (bool) { return _hasRole(MOWSEGAME_ADMIN_ROLE, account); } function hasMowseLootboxMinterRole(address account) external view returns (bool) { return _hasRole(MOWSELOOTBOX_MINTER_ROLE, account); } function hasMowseJobAdminRole(address account) external view returns (bool) { return _hasRole(MOWSEJOB_ADMIN_ROLE, account); } // Grant function addAccountToAdminRole(address account) external onlyAdminOrCore { _grantRole(AccessControlStorage.DEFAULT_ADMIN_ROLE, account); } function addAccountToMowseAdminRole(address account) external onlyAccessControlAdmin { _grantRole(MOWSE_ADMIN_ROLE, account); } function addAccountToMowseMinterRole(address account) external onlyAccessControlAdmin { _grantRole(MOWSE_MINTER_ROLE, account); } function addAccountToMowseWearMinterRole(address account) external onlyAccessControlAdmin { _grantRole(MOWSEWEAR_MINTER_ROLE, account); } function addAccountToMowseWearAdminRole(address account) external onlyAccessControlAdmin { _grantRole(MOWSEWEAR_ADMIN_ROLE, account); } function addAccountToMowseGameAdminRole(address account) external onlyAccessControlAdmin { _grantRole(MOWSEGAME_ADMIN_ROLE, account); } function addAccountToMowseLootboxMinterRole(address account) external onlyAccessControlAdmin { _grantRole(MOWSELOOTBOX_MINTER_ROLE, account); } function addAccountToMowseJobAdminRole(address account) external onlyAccessControlAdmin { _grantRole(MOWSEJOB_ADMIN_ROLE, account); } // Revoke function revokeAccountToMowseAdminRole(address account) external onlyAccessControlAdmin { _revokeRole(MOWSE_ADMIN_ROLE, account); } function revokeAccountToMowseMinterRole(address account) external onlyAccessControlAdmin { _revokeRole(MOWSE_MINTER_ROLE, account); } function revokeAccountToMowseWearMinterRole(address account) external onlyAccessControlAdmin { _revokeRole(MOWSEWEAR_MINTER_ROLE, account); } function revokeAccountToMowseWearAdminRole(address account) external onlyAccessControlAdmin { _revokeRole(MOWSEWEAR_ADMIN_ROLE, account); } function revokeAccountToMowseGameAdminRole(address account) external onlyAccessControlAdmin { _revokeRole(MOWSEGAME_ADMIN_ROLE, account); } function revokeAccountToMowseLootboxMinterRole(address account) external onlyAccessControlAdmin { _revokeRole(MOWSELOOTBOX_MINTER_ROLE, account); } function revokeAccountToMowseJobAdminRole(address account) external onlyAccessControlAdmin { _revokeRole(MOWSEJOB_ADMIN_ROLE, account); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAccessControl } from './IAccessControl.sol'; import { AccessControlInternal } from './AccessControlInternal.sol'; /** * @title Role-based access control system * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license) */ abstract contract AccessControl is IAccessControl, AccessControlInternal { /** * @inheritdoc IAccessControl */ function grantRole( bytes32 role, address account ) external onlyRole(_getRoleAdmin(role)) { _grantRole(role, account); } /** * @inheritdoc IAccessControl */ function hasRole( bytes32 role, address account ) external view returns (bool) { return _hasRole(role, account); } /** * @inheritdoc IAccessControl */ function getRoleAdmin(bytes32 role) external view returns (bytes32) { return _getRoleAdmin(role); } /** * @inheritdoc IAccessControl */ function revokeRole( bytes32 role, address account ) external onlyRole(_getRoleAdmin(role)) { _revokeRole(role, account); } /** * @inheritdoc IAccessControl */ function renounceRole(bytes32 role) external { _renounceRole(role); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { EnumerableSet } from '../../data/EnumerableSet.sol'; import { AddressUtils } from '../../utils/AddressUtils.sol'; import { UintUtils } from '../../utils/UintUtils.sol'; import { IAccessControlInternal } from './IAccessControlInternal.sol'; import { AccessControlStorage } from './AccessControlStorage.sol'; /** * @title Role-based access control system * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license) */ abstract contract AccessControlInternal is IAccessControlInternal { using AddressUtils for address; using EnumerableSet for EnumerableSet.AddressSet; using UintUtils for uint256; modifier onlyRole(bytes32 role) { _checkRole(role); _; } /* * @notice query whether role is assigned to account * @param role role to query * @param account account to query * @return whether role is assigned to account */ function _hasRole( bytes32 role, address account ) internal view virtual returns (bool) { return AccessControlStorage.layout().roles[role].members.contains(account); } /** * @notice revert if sender does not have given role * @param role role to query */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, msg.sender); } /** * @notice revert if given account does not have given role * @param role role to query * @param account to query */ function _checkRole(bytes32 role, address account) internal view virtual { if (!_hasRole(role, account)) { revert( string( abi.encodePacked( 'AccessControl: account ', account.toString(), ' is missing role ', uint256(role).toHexString(32) ) ) ); } } /* * @notice query admin role for given role * @param role role to query * @return admin role */ function _getRoleAdmin( bytes32 role ) internal view virtual returns (bytes32) { return AccessControlStorage.layout().roles[role].adminRole; } /** * @notice set role as admin role * @param role role to set * @param adminRole admin role to set */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = _getRoleAdmin(role); AccessControlStorage.layout().roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /* * @notice assign role to given account * @param role role to assign * @param account recipient of role assignment */ function _grantRole(bytes32 role, address account) internal virtual { AccessControlStorage.layout().roles[role].members.add(account); emit RoleGranted(role, account, msg.sender); } /* * @notice unassign role from given account * @param role role to unassign * @parm account */ function _revokeRole(bytes32 role, address account) internal virtual { AccessControlStorage.layout().roles[role].members.remove(account); emit RoleRevoked(role, account, msg.sender); } /** * @notice relinquish role * @param role role to relinquish */ function _renounceRole(bytes32 role) internal virtual { _revokeRole(role, msg.sender); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { EnumerableSet } from '../../data/EnumerableSet.sol'; library AccessControlStorage { struct RoleData { EnumerableSet.AddressSet members; bytes32 adminRole; } struct Layout { mapping(bytes32 => RoleData) roles; } bytes32 internal constant DEFAULT_ADMIN_ROLE = 0x00; bytes32 internal constant STORAGE_SLOT = keccak256('solidstate.contracts.storage.AccessControl'); function layout() internal pure returns (Layout storage l) { bytes32 slot = STORAGE_SLOT; assembly { l.slot := slot } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IAccessControlInternal } from './IAccessControlInternal.sol'; /** * @title AccessControl interface */ interface IAccessControl is IAccessControlInternal { /* * @notice query whether role is assigned to account * @param role role to query * @param account account to query * @return whether role is assigned to account */ function hasRole( bytes32 role, address account ) external view returns (bool); /* * @notice query admin role for given role * @param role role to query * @return admin role */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /* * @notice assign role to given account * @param role role to assign * @param account recipient of role assignment */ function grantRole(bytes32 role, address account) external; /* * @notice unassign role from given account * @param role role to unassign * @parm account */ function revokeRole(bytes32 role, address account) external; /** * @notice relinquish role * @param role role to relinquish */ function renounceRole(bytes32 role) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Partial AccessControl interface needed by internal functions */ interface IAccessControlInternal { event RoleAdminChanged( bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole ); event RoleGranted( bytes32 indexed role, address indexed account, address indexed sender ); event RoleRevoked( bytes32 indexed role, address indexed account, address indexed sender ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title Set implementation with enumeration functions * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts (MIT license) */ library EnumerableSet { error EnumerableSet__IndexOutOfBounds(); struct Set { bytes32[] _values; // 1-indexed to allow 0 to signify nonexistence mapping(bytes32 => uint256) _indexes; } struct Bytes32Set { Set _inner; } struct AddressSet { Set _inner; } struct UintSet { Set _inner; } function at( Bytes32Set storage set, uint256 index ) internal view returns (bytes32) { return _at(set._inner, index); } function at( AddressSet storage set, uint256 index ) internal view returns (address) { return address(uint160(uint256(_at(set._inner, index)))); } function at( UintSet storage set, uint256 index ) internal view returns (uint256) { return uint256(_at(set._inner, index)); } function contains( Bytes32Set storage set, bytes32 value ) internal view returns (bool) { return _contains(set._inner, value); } function contains( AddressSet storage set, address value ) internal view returns (bool) { return _contains(set._inner, bytes32(uint256(uint160(value)))); } function contains( UintSet storage set, uint256 value ) internal view returns (bool) { return _contains(set._inner, bytes32(value)); } function indexOf( Bytes32Set storage set, bytes32 value ) internal view returns (uint256) { return _indexOf(set._inner, value); } function indexOf( AddressSet storage set, address value ) internal view returns (uint256) { return _indexOf(set._inner, bytes32(uint256(uint160(value)))); } function indexOf( UintSet storage set, uint256 value ) internal view returns (uint256) { return _indexOf(set._inner, bytes32(value)); } function length(Bytes32Set storage set) internal view returns (uint256) { return _length(set._inner); } function length(AddressSet storage set) internal view returns (uint256) { return _length(set._inner); } function length(UintSet storage set) internal view returns (uint256) { return _length(set._inner); } function add( Bytes32Set storage set, bytes32 value ) internal returns (bool) { return _add(set._inner, value); } function add( AddressSet storage set, address value ) internal returns (bool) { return _add(set._inner, bytes32(uint256(uint160(value)))); } function add(UintSet storage set, uint256 value) internal returns (bool) { return _add(set._inner, bytes32(value)); } function remove( Bytes32Set storage set, bytes32 value ) internal returns (bool) { return _remove(set._inner, value); } function remove( AddressSet storage set, address value ) internal returns (bool) { return _remove(set._inner, bytes32(uint256(uint160(value)))); } function remove( UintSet storage set, uint256 value ) internal returns (bool) { return _remove(set._inner, bytes32(value)); } function toArray( Bytes32Set storage set ) internal view returns (bytes32[] memory) { return set._inner._values; } function toArray( AddressSet storage set ) internal view returns (address[] memory) { bytes32[] storage values = set._inner._values; address[] storage array; assembly { array.slot := values.slot } return array; } function toArray( UintSet storage set ) internal view returns (uint256[] memory) { bytes32[] storage values = set._inner._values; uint256[] storage array; assembly { array.slot := values.slot } return array; } function _at( Set storage set, uint256 index ) private view returns (bytes32) { if (index >= set._values.length) revert EnumerableSet__IndexOutOfBounds(); return set._values[index]; } function _contains( Set storage set, bytes32 value ) private view returns (bool) { return set._indexes[value] != 0; } function _indexOf( Set storage set, bytes32 value ) private view returns (uint256) { unchecked { return set._indexes[value] - 1; } } function _length(Set storage set) private view returns (uint256) { return set._values.length; } function _add( Set storage set, bytes32 value ) private returns (bool status) { if (!_contains(set, value)) { set._values.push(value); set._indexes[value] = set._values.length; status = true; } } function _remove( Set storage set, bytes32 value ) private returns (bool status) { uint256 valueIndex = set._indexes[value]; if (valueIndex != 0) { unchecked { bytes32 last = set._values[set._values.length - 1]; // move last value to now-vacant index set._values[valueIndex - 1] = last; set._indexes[last] = valueIndex; } // clear last index set._values.pop(); delete set._indexes[value]; status = true; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; import { UintUtils } from './UintUtils.sol'; library AddressUtils { using UintUtils for uint256; error AddressUtils__InsufficientBalance(); error AddressUtils__NotContract(); error AddressUtils__SendValueFailed(); function toString(address account) internal pure returns (string memory) { return uint256(uint160(account)).toHexString(20); } function isContract(address account) internal view returns (bool) { uint256 size; assembly { size := extcodesize(account) } return size > 0; } function sendValue(address payable account, uint256 amount) internal { (bool success, ) = account.call{ value: amount }(''); if (!success) revert AddressUtils__SendValueFailed(); } function functionCall( address target, bytes memory data ) internal returns (bytes memory) { return functionCall(target, data, 'AddressUtils: failed low-level call'); } function functionCall( address target, bytes memory data, string memory error ) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, error); } function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue( target, data, value, 'AddressUtils: failed low-level call with value' ); } function functionCallWithValue( address target, bytes memory data, uint256 value, string memory error ) internal returns (bytes memory) { if (value > address(this).balance) revert AddressUtils__InsufficientBalance(); return _functionCallWithValue(target, data, value, error); } /** * @notice execute arbitrary external call with limited gas usage and amount of copied return data * @dev derived from https://github.com/nomad-xyz/ExcessivelySafeCall (MIT License) * @param target recipient of call * @param gasAmount gas allowance for call * @param value native token value to include in call * @param maxCopy maximum number of bytes to copy from return data * @param data encoded call data * @return success whether call is successful * @return returnData copied return data */ function excessivelySafeCall( address target, uint256 gasAmount, uint256 value, uint16 maxCopy, bytes memory data ) internal returns (bool success, bytes memory returnData) { returnData = new bytes(maxCopy); assembly { // execute external call via assembly to avoid automatic copying of return data success := call( gasAmount, target, value, add(data, 0x20), mload(data), 0, 0 ) // determine whether to limit amount of data to copy let toCopy := returndatasize() if gt(toCopy, maxCopy) { toCopy := maxCopy } // store the length of the copied bytes mstore(returnData, toCopy) // copy the bytes from returndata[0:toCopy] returndatacopy(add(returnData, 0x20), 0, toCopy) } } function _functionCallWithValue( address target, bytes memory data, uint256 value, string memory error ) private returns (bytes memory) { if (!isContract(target)) revert AddressUtils__NotContract(); (bool success, bytes memory returnData) = target.call{ value: value }( data ); if (success) { return returnData; } else if (returnData.length > 0) { assembly { let returnData_size := mload(returnData) revert(add(32, returnData), returnData_size) } } else { revert(error); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.8; /** * @title utility functions for uint256 operations * @dev derived from https://github.com/OpenZeppelin/openzeppelin-contracts/ (MIT license) */ library UintUtils { error UintUtils__InsufficientHexLength(); bytes16 private constant HEX_SYMBOLS = '0123456789abcdef'; function add(uint256 a, int256 b) internal pure returns (uint256) { return b < 0 ? sub(a, -b) : a + uint256(b); } function sub(uint256 a, int256 b) internal pure returns (uint256) { return b < 0 ? add(a, -b) : a - uint256(b); } function toString(uint256 value) internal pure returns (string memory) { if (value == 0) { return '0'; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return '0x00'; } uint256 length = 0; for (uint256 temp = value; temp != 0; temp >>= 8) { unchecked { length++; } } return toHexString(value, length); } function toHexString( uint256 value, uint256 length ) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = '0'; buffer[1] = 'x'; unchecked { for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = HEX_SYMBOLS[value & 0xf]; value >>= 4; } } if (value != 0) revert UintUtils__InsufficientHexLength(); return string(buffer); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ interface IDiamondCut { enum FacetCutAction {Add, Replace, Remove} // Add=0, Replace=1, Remove=2 struct FacetCut { address facetAddress; FacetCutAction action; bytes4[] functionSelectors; } /// @notice Add/replace/remove any number of functions and optionally execute /// a function with delegatecall /// @param _diamondCut Contains the facet addresses and function selectors /// @param _init The address of the contract or facet to execute _calldata /// @param _calldata A function call, including function selector and arguments /// _calldata is executed with delegatecall on _init function diamondCut( FacetCut[] calldata _diamondCut, address _init, bytes calldata _calldata ) external; event DiamondCut(FacetCut[] _diamondCut, address _init, bytes _calldata); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /******************************************************************************\ * Author: Nick Mudge <[email protected]> (https://twitter.com/mudgen) * EIP-2535 Diamonds: https://eips.ethereum.org/EIPS/eip-2535 /******************************************************************************/ import { IDiamondCut } from "../interfaces/IDiamondCut.sol"; // Remember to add the loupe functions from DiamondLoupeFacet to the diamond. // The loupe functions are required by the EIP2535 Diamonds standard error InitializationFunctionReverted(address _initializationContractAddress, bytes _calldata); library LibDiamond { bytes32 constant DIAMOND_STORAGE_POSITION = keccak256("diamond.standard.diamond.storage"); struct FacetAddressAndPosition { address facetAddress; uint96 functionSelectorPosition; // position in facetFunctionSelectors.functionSelectors array } struct FacetFunctionSelectors { bytes4[] functionSelectors; uint256 facetAddressPosition; // position of facetAddress in facetAddresses array } struct DiamondStorage { // maps function selector to the facet address and // the position of the selector in the facetFunctionSelectors.selectors array mapping(bytes4 => FacetAddressAndPosition) selectorToFacetAndPosition; // maps facet addresses to function selectors mapping(address => FacetFunctionSelectors) facetFunctionSelectors; // facet addresses address[] facetAddresses; // Used to query if a contract implements an interface. // Used to implement ERC-165. mapping(bytes4 => bool) supportedInterfaces; // owner of the contract address contractOwner; } function diamondStorage() internal pure returns (DiamondStorage storage ds) { bytes32 position = DIAMOND_STORAGE_POSITION; assembly { ds.slot := position } } event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function setContractOwner(address _newOwner) internal { DiamondStorage storage ds = diamondStorage(); address previousOwner = ds.contractOwner; ds.contractOwner = _newOwner; emit OwnershipTransferred(previousOwner, _newOwner); } function contractOwner() internal view returns (address contractOwner_) { contractOwner_ = diamondStorage().contractOwner; } function enforceIsContractOwner() internal view { require(msg.sender == diamondStorage().contractOwner, "LibDiamond: Must be contract owner"); } event DiamondCut(IDiamondCut.FacetCut[] _diamondCut, address _init, bytes _calldata); // Internal function version of diamondCut function diamondCut( IDiamondCut.FacetCut[] memory _diamondCut, address _init, bytes memory _calldata ) internal { for (uint256 facetIndex; facetIndex < _diamondCut.length; facetIndex++) { IDiamondCut.FacetCutAction action = _diamondCut[facetIndex].action; if (action == IDiamondCut.FacetCutAction.Add) { addFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else if (action == IDiamondCut.FacetCutAction.Replace) { replaceFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else if (action == IDiamondCut.FacetCutAction.Remove) { removeFunctions(_diamondCut[facetIndex].facetAddress, _diamondCut[facetIndex].functionSelectors); } else { revert("LibDiamondCut: Incorrect FacetCutAction"); } } emit DiamondCut(_diamondCut, _init, _calldata); initializeDiamondCut(_init, _calldata); } function addFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); DiamondStorage storage ds = diamondStorage(); require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)"); uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length); // add new facet address if it does not exist if (selectorPosition == 0) { addFacet(ds, _facetAddress); } for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress; require(oldFacetAddress == address(0), "LibDiamondCut: Can't add function that already exists"); addFunction(ds, selector, selectorPosition, _facetAddress); selectorPosition++; } } function replaceFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); DiamondStorage storage ds = diamondStorage(); require(_facetAddress != address(0), "LibDiamondCut: Add facet can't be address(0)"); uint96 selectorPosition = uint96(ds.facetFunctionSelectors[_facetAddress].functionSelectors.length); // add new facet address if it does not exist if (selectorPosition == 0) { addFacet(ds, _facetAddress); } for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress; require(oldFacetAddress != _facetAddress, "LibDiamondCut: Can't replace function with same function"); removeFunction(ds, oldFacetAddress, selector); addFunction(ds, selector, selectorPosition, _facetAddress); selectorPosition++; } } function removeFunctions(address _facetAddress, bytes4[] memory _functionSelectors) internal { require(_functionSelectors.length > 0, "LibDiamondCut: No selectors in facet to cut"); DiamondStorage storage ds = diamondStorage(); // if function does not exist then do nothing and return require(_facetAddress == address(0), "LibDiamondCut: Remove facet address must be address(0)"); for (uint256 selectorIndex; selectorIndex < _functionSelectors.length; selectorIndex++) { bytes4 selector = _functionSelectors[selectorIndex]; address oldFacetAddress = ds.selectorToFacetAndPosition[selector].facetAddress; removeFunction(ds, oldFacetAddress, selector); } } function addFacet(DiamondStorage storage ds, address _facetAddress) internal { enforceHasContractCode(_facetAddress, "LibDiamondCut: New facet has no code"); ds.facetFunctionSelectors[_facetAddress].facetAddressPosition = ds.facetAddresses.length; ds.facetAddresses.push(_facetAddress); } function addFunction(DiamondStorage storage ds, bytes4 _selector, uint96 _selectorPosition, address _facetAddress) internal { ds.selectorToFacetAndPosition[_selector].functionSelectorPosition = _selectorPosition; ds.facetFunctionSelectors[_facetAddress].functionSelectors.push(_selector); ds.selectorToFacetAndPosition[_selector].facetAddress = _facetAddress; } function removeFunction(DiamondStorage storage ds, address _facetAddress, bytes4 _selector) internal { require(_facetAddress != address(0), "LibDiamondCut: Can't remove function that doesn't exist"); // an immutable function is a function defined directly in a diamond require(_facetAddress != address(this), "LibDiamondCut: Can't remove immutable function"); // replace selector with last selector, then delete last selector uint256 selectorPosition = ds.selectorToFacetAndPosition[_selector].functionSelectorPosition; uint256 lastSelectorPosition = ds.facetFunctionSelectors[_facetAddress].functionSelectors.length - 1; // if not the same then replace _selector with lastSelector if (selectorPosition != lastSelectorPosition) { bytes4 lastSelector = ds.facetFunctionSelectors[_facetAddress].functionSelectors[lastSelectorPosition]; ds.facetFunctionSelectors[_facetAddress].functionSelectors[selectorPosition] = lastSelector; ds.selectorToFacetAndPosition[lastSelector].functionSelectorPosition = uint96(selectorPosition); } // delete the last selector ds.facetFunctionSelectors[_facetAddress].functionSelectors.pop(); delete ds.selectorToFacetAndPosition[_selector]; // if no more selectors for facet address then delete the facet address if (lastSelectorPosition == 0) { // replace facet address with last facet address and delete last facet address uint256 lastFacetAddressPosition = ds.facetAddresses.length - 1; uint256 facetAddressPosition = ds.facetFunctionSelectors[_facetAddress].facetAddressPosition; if (facetAddressPosition != lastFacetAddressPosition) { address lastFacetAddress = ds.facetAddresses[lastFacetAddressPosition]; ds.facetAddresses[facetAddressPosition] = lastFacetAddress; ds.facetFunctionSelectors[lastFacetAddress].facetAddressPosition = facetAddressPosition; } ds.facetAddresses.pop(); delete ds.facetFunctionSelectors[_facetAddress].facetAddressPosition; } } function initializeDiamondCut(address _init, bytes memory _calldata) internal { if (_init == address(0)) { return; } enforceHasContractCode(_init, "LibDiamondCut: _init address has no code"); (bool success, bytes memory error) = _init.delegatecall(_calldata); if (!success) { if (error.length > 0) { // bubble up error /// @solidity memory-safe-assembly assembly { let returndata_size := mload(error) revert(add(32, error), returndata_size) } } else { revert InitializationFunctionReverted(_init, _calldata); } } } function enforceHasContractCode(address _contract, string memory _errorMessage) internal view { uint256 contractSize; assembly { contractSize := extcodesize(_contract) } require(contractSize > 0, _errorMessage); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { LibDiamond } from "./LibDiamond.sol"; uint256 constant SKILL_TYPE_NUM = 7; uint256 constant STAT_CHARISMA = 0; uint256 constant STAT_CONSTITUTION = 1; uint256 constant STAT_DEXTERITY = 2; uint256 constant STAT_INTELLIGENCE = 3; uint256 constant STAT_LUCK = 4; uint256 constant STAT_STRENGTH = 5; uint256 constant STAT_WISDOM = 6; uint256 constant EQUIPPED_WEARABLE_SLOTS = 12; bytes32 constant MOWSE_ADMIN_ROLE = keccak256('MOWSE_ADMIN_ROLE'); bytes32 constant MOWSEWEAR_MINTER_ROLE = keccak256('MOWSEWEAR_MINTER_ROLE'); bytes32 constant MOWSE_MINTER_ROLE = keccak256('MOWSE_MINTER_ROLE'); bytes32 constant MOWSEWEAR_ADMIN_ROLE = keccak256('MOWSEWEAR_ADMIN_ROLE'); bytes32 constant MOWSEGAME_ADMIN_ROLE = keccak256('MOWSEGAME_ADMIN_ROLE'); bytes32 constant MOWSEBANK_CREATE2_SALT = keccak256('MOWSEBANK_CREATE2_SALT'); bytes32 constant MOWSELOOTBOX_MINTER_ROLE = keccak256('MOWSELOOTBOX_MINTER_ROLE'); bytes32 constant MOWSEJOB_ADMIN_ROLE = keccak256('MOWSEJOB_ADMIN_ROLE'); struct GameStorage { address diamondAddress; address mowseAvatarContractAddress; address mowseGoldContractAddress; address mowseBankContractAddress; address mowseLootboxContractAddress; bool paused; // Mowse = id > 10,000 uint256 mowseMintPrice; uint256 mowseTokenIdCounter; // Current tokenId of Mowse for minting purposes uint256 mowseWearTotalCount; // Total Count of MowseWear minted uint256 mowseWearTokenIdCounter; // Current tokenId of MowseWear for minting purposes mapping(address => bool) isMowse; // maps Mowse address to bool if it is a mowse address or not mapping(address => uint256) mainMowse; // map address to mowseTokenId mapping(uint256 => Mowse) mowses; // map mowseAvatar tokenId to Mowse struct mapping(uint256 => MowseWear) mowsewears; // map mowsewear tokenId to MowseWear struct // mapping(uint256 => MowseLineage) mowselineages; mapping(uint8 => mapping(uint16 => MowseWearMetadata)) mowseWearDictionary; // map equippable wearable slot index to dictionary index to get unique mowsewear mapping(uint256 => MowseWearMetadata) mowseWearDictionaryByDictionaryIndex; // map dictionary index to mowsewear (for lootbox) uint256 mowseWearDictionaryCount; // Counts how many items are in the mowseWearDictionary (for lootbox) uint16[EQUIPPED_WEARABLE_SLOTS] mowseWearDictionaryTraitCount; // count of each trait (11 shirts, 10 eyeWear, etc), used for incrementing next traitIndex mapping(uint8 => mapping(uint16 => uint256)) mowseWearCountByTraitIndex; // Counts how many mowsewear are minted per traitIndex (3 Blue Headbands) mapping(uint8 => uint256) mowseWearCountByTraitType; // Counts how many shirts were minted mapping(uint16 => string) possibleTraitTypes; // mapping of all possible traitTypes to strings string[] initTraitNames; // used in DiamondInit // MowseWear uint256 mowseWearHemPrice; // Initial merkel MGOLD aidrop // mapping(address => uint256) initialMowseGoldClaimList; // Used for merkel airdrop // MowseLootbox // lootbox index is the loot pool index; [0-11] are trait type specific, [12] is general pool, 13+ are any other specific pools (weekly chests or seasonal chests) mapping(uint64 => MowseLootboxPool) mowselootboxes; // map lootbox index (traitType + a few more) to MowseLootbox // count of current lootbox index uint64 mowseLootboxIndexCount; // Current tokenId of MowseLootbox for minting purposes uint256 mowseLootboxTokenIdCounter; // map tokenId to LootboxIndex to get the lootbox data mapping(uint256 => uint64) mowseLootboxIndexByTokenId; // large prime used for VDF uint256 mowseLootboxPrime; // iterations for VDF uint256 mowseLootboxIterations; // nonce for VDF uint256 mowseLootboxNonce; // mapping to get seed from tokenId if minted through mowseLootbox mapping(uint256 => uint256) mowseLootboxTokenIdToSeed; // random seed for pseudo-rng uint256 mowsePrngSeed; uint256 mowseJobPrngSeed; uint256 mowseWearPrngSeed; uint256 prngNonce; // DonationTree uint256 totalWishCount; uint256 donationTreePrime; uint256 donationTreeIterations; uint256 donationTreeNonce; mapping(uint256 => uint256) donationTreeWishCountToSeed; mapping(uint256 => uint256) mowseNextWish; mapping(address => uint256) nextWish; mapping(address => uint256) wishCount; // MowseGame mapping(uint256 => MowseGames) mowsegames; uint256 mowseGamesCount; uint256 activeMowseGamesCount; // Needed mapping(string => uint256) getMowseGameByName; uint8 maxFreeGameSubmits; // Normal base token payout uint256 baseGamePayout; // Pay for users' gas but it ain't free yo. After x number of submits, purchase MowseGold to continue forever mapping(address => uint256) freeMowseGameSubmits; mapping(address => bool) hasPurchasedMowseGold; // For suspicious gaming activity, temporary ban mapping(address => bool) mowseGameUserBanned; // MowseBank and MowseWallet address mowseBankWalletImplementation; mapping(address => uint256) mowseBankBalances; mapping(address => uint256) mowseBankTokenIdForWallet; // Withdrawal address payable devRoyaltyAddress; address payable teamAddress; address payable backendAddress; address payable treasuryAddress; uint256 devRoyaltyTaxBasisPoints; uint256 teamTaxBasisPoints; uint256 backendTaxBasisPoints; uint256 developerTaxBasisPoints; // For testnet purposes and rewarding testers uint256 testPatchCount; mapping(uint256 => TestPatch) testPatches; // Maps patchVersion to testPatch // GatherAndGarnishFacet uint256 gatherGarnishPrngSeed; uint256 gatherGarnishSeasonStart; uint256 gatherGarnishSeasonEnd; uint256 gatherGarnishSeasonCount; // Maps season count -> season reward (mowse wear dictionary index) mapping(uint256 => uint256) gatherGarnishSeasonReward; // MowseWearDictionaryIndex // Maps player address -> season count -> stats mapping(address => mapping(uint256 => GatherAndGarnishPlayerStats)) gatherGarnishPlayerStats; // What day index did the first winner win uint256 gatherGarnishDayOfFirstWinner; // Maps season count -> first winners count index -> player address for season first winners mapping(uint256 => mapping(uint256 => address)) gatherGarnishSeasonFirstWinners; uint256 gatherGarnishSeasonFirstWinnersCount; // Maps season count -> winners count index -> player address for season winners mapping(uint256 => mapping(uint256 => address)) gatherGarnishSeasonWinners; uint256 gatherGarnishSeasonWinnersCount; // Maps season count -> winners address -> bool if they have won and claimed their rewards mapping(uint256 => mapping(address => bool)) gatherGarnishClaimedRewards; // Maps season count -> mainMowseId -> bool if the mowseId has received rewards for this season (to prevent transferring main mowse and claiming multiple exp rewards) mapping(uint256 => mapping(uint256 => bool)) gatherGarnishMainMowseClaimedRewards; // Maps season count -> winners address -> bool if they have won mapping(uint256 => mapping(address => bool)) gatherGarnishHasPlayerWon; // Maps season count -> day index -> scavenge hunt count mapping(uint256 => mapping(uint256 => GatherAndGarnishScavenge)) gatherGarnishScavenge; // Maps season count -> day index -> resource type [1-4, wood/rock/gem/food] mapping(uint256 => mapping(uint256 => uint256)) gatherGarnishDailyResource; // Maps season count -> day index -> investment resource type [1-4] mapping(uint256 => mapping(uint256 => uint256)) gatherGarnishInvestmentResource; // Maps season count -> pointsStructureCost mapping(uint256 => uint256[4]) gatherGarnishFirstPointsStructureCost; mapping(uint256 => uint256[4]) gatherGarnishSecondPointsStructureCost; mapping(uint256 => uint256[4]) gatherGarnishThirdPointsStructureCost; // MowseDungeonFacet uint256 statusEffectCount; // VDF for initial dungeon hash uint256 mowseDungeonPrime; uint256 mowseDungeonIterations; uint256 mowseDungeonNonce; // pRNG for smaller pseudo random actions uint256 mowseDungeonPrngSeed; // Maps mowseTokenId -> dungeonRunCount -> MowseDungeon mapping(uint256 => mapping(uint256 => MowseDungeon)) mowsedungeons; // Maps monsterIdCount -> mapping of statusEffects mapping(uint256 => mapping(MowseDungeonStatusEffectEnum => uint256)) mowseDungeonMonsterStatusEffects; // Count of Monster Ids // uint256 mowseDungeonMonsterIdCount; // Maps roomId -> MowseDungeonRoom // mapping(uint256 => MowseDungeonRoom) mowseDungeonRoom; // Count of rooms // uint256 mowseDungeonRoomCount; // Maps mowseTokenId -> Current Player stats mapping(uint256 => MowseDungeonPlayer) mowseDungeonPlayer; // Maps mowseTokenId -> AchievementEnum -> threshold mapping(uint256 => mapping(MowseDungeonAchievementsEnum => uint256)) mowseDungeonAchievementProgress; // Maps mowseTokenId -> Companion Enum -> Companion mapping(uint256 => mapping(MowseDungeonCompanionEnum => MowseDungeonCompanion)) mowseDungeonPlayerCompanion; // Maps mowseTokenId -> dungeonRunCount -> DungeonRewards mapping(uint256 => mapping(uint256 => MowseDungeonDungeonRewards)) mowseDungeonDungeonRewards; // Maps Monster Enum -> Monster for default values mapping(MowseDungeonMonsterEnum => MowseDungeonMonsterAttributes) mowseDungeonMonsterDefaults; uint256 mowseDungeonMonsterDefaultsCount; // Maps Room Enum -> Room for default values mapping(MowseDungeonRoomEnum => MowseDungeonRoom) mowseDungeonRoomDefaults; uint256 mowseDungeonRoomDefaultsCount; mapping(MowseDungeonTrinketEnum => MowseDungeonTrinket) mowseDungeonTrinketDefaults; // Keeps track of number of different trinkets exist uint256 mowseDungeonTrinketDefaultsCount; // Maps mowseTokenId to dungeon run count to vdf seed mapping(uint256 => mapping(uint256 => uint256)) mowseDungeonRunCountToSeed; // Maps mowseTokenId to dungeon run count mapping(uint256 => uint256) mowseDungeonRunCount; // RandomFortuneFacet mapping(address => uint256) randomFortuneCount; // large prime used for VDF uint256 randomFortunePrime; // iterations for VDF uint256 randomFortuneIterations; // nonce for VDF uint256 randomFortuneNonce; // mapping to get seed from timestamp mapping(address => mapping(uint256 => uint256)) randomFortuneTimestampToSeed; // MowseSpin // uint256 mowseSpinPrime; // uint256 mowseSpinIterations; // uint256 mowseSpinNonce; // // Maps mowseTokenId to current mowse spin game // mapping(uint256 => MowseSpinStorage) mowseSpinStorage; // // Maps mowseTokenId to player stats // mapping(uint256 => MowseSpinPlayer) mowseSpinPlayer; } // MowseSpin // struct MowseSpinStorage { // uint256 mowseId; // uint256 stageCount; // uint256 spinCount; // uint256 mowseSpinId; // uint256 seed; // uint256 recountTokens; // uint256 trashTokens; // uint256 coins; // MowseSpinSimplePlayer player; // MowseSpinPlayerAchievementsProgress achievementProgress; // MowseSpinLog[] spinLog; // uint256 spinLogCount; // uint256 grid; // } // struct MowseSpinPlayer { // uint256 mowseId; // // Number of times a player has created a game // uint256 spinRunCount; // // MowseDungeonSimplePlayerAchievementsUnlocked achievements; // // // Used for quickly checking if an achievement is unlocked // // mapping(MowseDungeonAchievementsEnum => bool) achievementsUnlocked; // // mapping(MowseDungeonAchievementsEnum => bool) achievementsClaimed; // // MowseDungeonSimplePlayerAchievementsProgress achievementsProgress; // } enum MowseDungeonStatusEffectEnum { NONE, BLIND, // 1/2 chance of missing attack EAGLE_EYE, // double chance of hitting atttack POISON, // Damage per turn, pre attack BURN, // Damage per turn, post attack BLEED, // Damage per turn, post attack CURSE, // % Damage per turn, pre attack STUN, // Skip damage step SILENCE, // Disable special ability FREEZE, // Skip damage step, +50% damage taken from fire damage STRENGTHEN, // Damage Up WEAKEN, // Damage Down BULK, // Defense Up FRAIL, // Defense Down THORNS, // Return damage on hit REGEN, // Heal, pre attack SLEEP, // Skip damage step, +150% damage taken, wakes up after damage taken DEATH, // Kill player after x turns INVINCIBLE, // Player does not receive damage LAST_HOPE, // If player would die, set health to 1 DODGE, // Increase dodge chance HEAL_BLOCK, // Disable healing CHARM, // Skip damage step COUNTER, // Basic attack after getting hit by a basic/special attack PIERCE, // Attack through shield CLEAVE, // Every attack hits all monsters REVIVE, // After dying, revive with full health UNSTOPPABLE,// Debuffs cannot be applied (existing ones still damage) PETRIFY, // Skip damage step, can't receive damage from enemy attack FIRE_RESIST, // Resist application of burn POISON_RESIST, FREEZE_RESIST, STUN_RESIST, SLEEP_RESIST, CHARGED, // Used for boss abilities that take wind up time DOUBLE_UP, // Apply double status effects RAMPAGE, // Increase monster damage per turn LONE_SURVIVOR,// If all other monsters are dead, increase damage ROYAL_DECREE,// Cannot be directly targeted until all other monsters are dead WRATHFUL_REPRISAL// Counter attack based off player attack } enum MowseDungeonSpecialAbilityEnum { DEFEND, // Apply thorns/counter/shield+5 to self POISON_GAS, // Apply poison to enemy BOULDER_TOSS, // Charge up and deal 3x damage + stun RAGE, // Apply STRENGTHEN to self SUMMON_CLUCKO, // Summon a Clucko in an empty monster slot THIN_STICK, // 80% dodge chance BADMOUTH, // Apply SILENCE, WEAKEN, FRAIL to enemy SUMMON_PUNK, // Summon up to 2 WRAT_PUNK in empty monster slots CURSED_SLIME, // Apply CURSE to enemy BLEEDING_SLIME, // Apply BLEED to enemy IRON_GRASP, // Charge up and double shield. Next turn add shield to damage IRON_PRAYER, // Grant shield to monsters other than self JESTER_DANCE, // Apply CURSE/BLEED/BURN/POISON/STUN/SLEEP/CHARM/freeze to enemy KNIGHTS_HONOR, // Apply STRENGTHEN to self and shield to self QUEENS_GRACE, // Apply REGEN,STRENGTHEN,BULK to all monsters KINGS_AUTHORITY, // Apply stun and charge up 2 turns, at end, deal damage equal to players coins ROYAL_DECREE, // Summon up to 2 copper squire, then charge for 2 turns HOARDERS_STASH, // Steal 25% of player's coins, add amount to current & max health WRATHFUL_REPRISAL,// Apply WRATHFUL_REPRISAL to self DESTRUCTIVE_ENVY,// Charge up 1 turn, copy player's attack SEDUCTIVE_GAZE, // Apply CHARM +2 to player INSATIABLE_FEAST,// Charge 1 turn, Consume all debuffs from self and all buffs from player, heal for 10% per debuff ANTI_SONIC_SPEED,// Apply SLEEP to all players for 2 turns NONE } enum MowseDungeonCompanionEnum { NONE, DIAMOND_BACK, DEVILISH, // Get Copper Squire Achievement WONDER_CHILD, // Get Novice Achievement INVALID_COMPANION } enum MowseDungeonTrinketEnum { DAGGER, // +10% attack SLINGSHOT, // increase damage when enemy at max health PENDANT_OF_LIFE, // +5 health pre attack LEECH, // +10% lifesteal per stack POISON_DAB, // +1 apply poison stack after attack KINDLE, // +1 burn stack BLOOD_LETTER, // +1 bleed stack CURSED_RING, // +1 curse stack STUN_ROD, // chance to apply +1 stun stack SILENCE_BELL, // chance to apply +1 silence stack STRENGTH_BELT, // +1 strengthen stack (2x damage) WEAKENED_CHAIN, // +1 weaken stack (1/2 damage) EMBLEM_OF_INITIATIVE, // +1 action GOLD_RING, // increase coin drop 10% + 10% per stack NONE } enum MowseDungeonRoomEnum { MERCHANT, // Merchant COIN_LOOT_ROOM, TRINKET_LOOT_ROOM, FOREST_SLIME_1, // 1 Green Slime FOREST_SLIME_2, // 2 Green Slime FOREST_SLIME_3, // 3 Green Slime FOREST_MUSHY, // 2 Red Mushy FOREST_PEBBLE, // 1 Pebble Golem 1 DUCKY FOREST_TOAD, // 3 Spiny Toad FOREST_ROOSTA, // 1 Roosta 2 Clucko FOREST_STICK, // 3 Stick Bug FOREST_WRAT_PUNK, // 2 WRAT_PUNK FOREST_WRAT_GANG_LEADER, // 1 Wrat Gang Leader RAIN_OF_FROGS, // 3 Spiny Toad STICKY_SITUATION, // 2 Green Slime 1 Stick Bug MEDIEVAL_SLIME_INTRO, // 1 Helmet Slime MEDIEVAL_SQUIRE_INTRO, // 1 Copper Squire MEDIEVAL_PRIEST_INTRO, // 2 Iron Priest MEDIEVAL_SLIME, // 3 Helmet Slime MEDIEVAL_SQUIRE, // 2 Copper Squire MEDIEVAL_JESTER, // 2 Pyrite Jester MEDIEVAL_KNIGHT, // 2 Steel Knight MEDIEVAL_KNIGHT_PRIEST, // 1 Steel Knight 1 Iron Priest MEDIEVAL_KNIGHT_SQUIRE, // 1 Steel Knight 1 CopperSquire MEDIEVAL_MAIDEN, // 1 Iron Maiden 2 Iron Priest MEDIEVAL_QUEEN, // 1 Silver Queen 1 SteelKnight MEDIEVAL_KING, // 1 Gold King 1 SteelKnight MEDIEVAL_ROYAL, // 1 Silver Queen 1 Gold King BOSS_LIONS_PRIDE, BOSS_GOBLINS_GREED, BOSS_LICHS_WRATH, BOSS_WRATS_ENVY, BOSS_LUSTFUL_HEIRESS, BOSS_GLUTTONOUS_PIG, BOSS_SLOTHFUL_HEDGEHOG } enum MowseDungeonMonsterEnum { // Forest SPINY_TOAD, GREEN_SLIME, RED_MUSHY, PEBBLE_GOLEM, CLUCKO, ROOSTA, STICK_BUG, DUCKY, WRAT_PUNK, WRAT_GANG_LEADER, BLUE_SLIME, RED_SLIME, // Metal Medieval theme HELMET_SLIME, COPPER_SQUIRE, IRON_MAIDEN, IRON_PRIEST, PYRITE_JESTER, STEEL_KNIGHT, SILVER_QUEEN, GOLD_KING, // Bosses // 7 Deadly Sins LIONS_PRIDE, GOBLINS_GREED, LICHS_WRATH, WRATS_ENVY, LUSTFUL_HEIRESS, GLUTTONOUS_PIG, SLOTHFUL_HEDGEHOG, NONE } enum MowseDungeonClassEnum { // Base Classes WARRIOR, // Basic 100% damage Special ability whirlwind (apply cleave to self) MAGE, // Basic 60% Special ability fireball (2x base attack, apply burn to enemy) ARCHER, // Basic 80% damage, Special ability Hawkshot (apply eagle eye, deal damage x # of times) ROGUE, // Basic 50% x 2 apply poison Special ability backstab (apply dodge 2x) // Advanced Classes PALADIN, // Basic 70% damage, Special ability Judgement Of Light (heal 30% max health + 1% per 10 int + 1% per 10 str) GUARDIAN, // Basic 50% damage, gain shield Special ability shieldbash (gain extra shield, damage equal to shield) BERSERKER,// Basic 120% Special ability rage (deal basic attack damage, apply strengthen, lastHope, silence to self) CLERIC, // Basic 40% Special ability heal (apply regen to self) NECROMANCER,// Basic 55% Special ability life tap (deal basic attack damage, if monster dies, permanently gain 10% attack) BARD, // Basic 60% Special ability charm (apply charm to enemy) // T2 Classes INVALID_CLASS } enum MowseDungeonRoomTypeEnum { MONSTER, COIN_LOOT, TRINKET_LOOT, BOSS, MERCHANT, INVALID_ROOM } // Complete Achievements to unlock Companions enum MowseDungeonAchievementsEnum { NOVICE, // Complete the forest-0 dungeon FOREST_MASTER, // Complete the forest-10 dungeon COPPER_SQUIRE, // Complete the medieval-0 dungeon IRON_MAIDEN, // Complete the medieval-3 dungeon STEEL_KNIGHT, // Complete the medieval-6 dungeon GOLD_KING, // Complete the medieval-9 dungeon MASTER_OF_DEADLY_SINS,// Complete the medieval-10 dungeon UNTOUCHABLE, // Defeat a boss without taking damage POISON_MASTER, // Apply 99 stacks of poison in one dungeon LOOT_GOBLIN, // Steal successfully more than 5 times in a single run COIN_GOBLIN, // Have at least 500 coins in inventory ONE_MAN_ARMY, // Deal 1000 damage in a single run LEARN_THE_ROPES, // Complete any dungeon with all 4 base classes WARRIOR, // Complete any dungeon with Warrior MAGE, // Complete any dungeon with Mage ARCHER, // Complete any dungeon with Archer ROGUE, // Complete any dungeon with Rogue PALADIN, // Complete any dungeon with Paladin GUARDIAN, // Complete any dungeon with Guardian BERSERKER, // Complete any dungeon with Berserker CLERIC, // Complete any dungeon with Cleric NECROMANCER, // Complete any dungeon with Necromancer BARD, // Complete any dungeon with Bard INVALID_ACHIEVEMENT } enum MowseDungeonActionTypeEnum { BASIC_ATTACK, SPECIAL_ABILITY, STEAL, DEFEND, INVALID_ACTION } enum MowseDungeonBattleStatusEnum { VICTORY, DEFEAT, ONGOING } enum MowseDungeonDungeonTypeEnum { FOREST, MEDIEVAL } enum MowseDungeonBattleLogTypeEnum { INVALID_LOG_TYPE, DAMAGE, APPLY_STATUS_EFFECT, HEAL, SUMMON, STEAL_SUCCESS, STEAL_FAILURE } enum MowseDungeonBattleLogSourceEnum { PLAYER, MONSTER_1, MONSTER_2, MONSTER_3, TARGET_INDEX_MONSTER, // Target a Monster according to targetIndex COMPANION, TRINKET_PENDANT_OF_LIFE, TRINKET_LEECH, STATUS_EFFECT_BLIND, STATUS_EFFECT_EAGLE_EYE, STATUS_EFFECT_POISON, STATUS_EFFECT_BURN, STATUS_EFFECT_BLEED, STATUS_EFFECT_CURSE, STATUS_EFFECT_STUN, STATUS_EFFECT_SILENCE, STATUS_EFFECT_FREEZE, STATUS_EFFECT_STRENGTHEN, STATUS_EFFECT_WEAKEN, STATUS_EFFECT_BULK, STATUS_EFFECT_FRAIL, STATUS_EFFECT_THORNS, STATUS_EFFECT_REGEN, STATUS_EFFECT_SLEEP, STATUS_EFFECT_DEATH, STATUS_EFFECT_INVINCIBLE, STATUS_EFFECT_LAST_HOPE, STATUS_EFFECT_DODGE, STATUS_EFFECT_HEAL_BLOCK, STATUS_EFFECT_CHARM, STATUS_EFFECT_COUNTER, STATUS_EFFECT_PIERCE, STATUS_EFFECT_CLEAVE, STATUS_EFFECT_REVIVE, STATUS_EFFECT_UNSTOPPABLE, STATUS_EFFECT_PETRIFY, STATUS_EFFECT_FIRE_RESIST, STATUS_EFFECT_POISON_RESIST, STATUS_EFFECT_FREEZE_RESIST, STATUS_EFFECT_STUN_RESIST, STATUS_EFFECT_SLEEP_RESIST, STATUS_EFFECT_CHARGED, STATUS_EFFECT_DOUBLE_UP, STATUS_EFFECT_RAMPAGE, STATUS_EFFECT_LONE_SURVIVOR, STATUS_EFFECT_ROYAL_DECREE, STATUS_EFFECT_WRATHFUL_REPRISAL } struct MowseDungeonSimpleTrinkets { uint256 dagger; uint256 slingshot; uint256 pendantOfLife; uint256 leech; uint256 poisonDab; uint256 kindle; uint256 bloodLetter; uint256 cursedRing; uint256 stunRod; uint256 silenceBell; uint256 strengthBelt; uint256 weakenedChain; uint256 emblemOfInitiative; uint256 goldRing; } struct MowseDungeonSimpleStatusEffect { uint256 blind; uint256 eagleEye; uint256 poison; uint256 burn; uint256 bleed; uint256 curse; uint256 stun; uint256 silence; uint256 freeze; uint256 strengthen; uint256 weaken; uint256 bulk; uint256 frail; uint256 thorns; uint256 regen; uint256 sleep; uint256 death; uint256 invincible; uint256 lastHope; uint256 dodge; uint256 healBlock; uint256 charm; uint256 counter; uint256 pierce; uint256 cleave; uint256 revive; uint256 unstoppable; uint256 petrify; uint256 fireResist; uint256 poisonResist; uint256 freezeResist; uint256 stunResist; uint256 sleepResist; uint256 charged; uint256 doubleUp; uint256 rampage; uint256 loneSurvivor; uint256 royalDecree; uint256 wrathfulReprisal; } struct MowseDungeonSimplePlayerAchievementsUnlocked { bool novice; bool forestMaster; bool copperSquire; bool ironMaiden; bool steelKnight; bool goldKing; bool masterOfDeadlySins; bool untouchable; bool poisonMaster; bool lootGoblin; bool coinGoblin; bool oneManArmy; bool learnTheRopes; bool warrior; bool mage; bool archer; bool rogue; bool paladin; bool guardian; bool berserker; bool cleric; bool necromancer; bool bard; } struct MowseDungeonSimplePlayerAchievementsProgress { uint256 damageDealt; uint256 damageTaken; uint256 healthHealed; uint256 burnDamageDealt; uint256 poisonDamageDealt; uint256 bleedDamageDealt; uint256 curseDamageDealt; uint256 trinketsStolen; } struct MowseDungeonBattleLog { MowseDungeonBattleLogTypeEnum logType; MowseDungeonBattleLogSourceEnum source; MowseDungeonBattleLogSourceEnum target; uint256 amount; } struct MowseDungeonBattleSimulation { MowseDungeonSimplePlayer player; MowseDungeonSimpleMonster monster1; MowseDungeonSimpleMonster monster2; MowseDungeonSimpleMonster monster3; uint256 dungeonId; uint256 seed; MowseDungeonActionTypeEnum actionType; uint8 targetIndex; uint256 actionsRun; MowseDungeonTrinketEnum[] stolenTrinkets; uint256 stolenTrinketCount; bool isStealSuccessful; MowseDungeonBattleStatusEnum status; MowseDungeonSimplePlayerAchievementsProgress achievementProgress; uint256 descentLevel; MowseDungeonBattleLog[] battleLog; uint256 battleLogCount; } struct MowseDungeonBattleResults { MowseDungeonBattleSimulation simulation; MowseDungeonPostBattleResults postBattleResults; bytes32 actionsRunHash; bytes32 postBattleResultsHash; } struct MowseDungeonPostBattleResults { uint256 mowseId; uint256 coins; MowseDungeonMonsterEnum monster1; MowseDungeonMonsterEnum monster2; MowseDungeonMonsterEnum monster3; MowseDungeonTrinketEnum[] stolenTrinkets; uint256 stolenTrinketCount; MowseDungeonBattleStatusEnum status; MowseDungeonSimplePlayerAchievementsProgress achievementProgress; uint256 descentLevel; } struct MowseDungeonDungeonRewards { bool hasRewards; uint256 mgoldMintAmount; uint256 xpGainedAmount; uint256 companionXpGained; uint256 completionPercentage; uint256 additionalFactor; } // Used for _performAction to calculate damage struct MowseDungeonSimplePlayer { uint256 mowseId; int32[SKILL_TYPE_NUM] stats; uint256 maxHealth; uint256 currentHealth; uint256 shield; uint256 attack; bool canHit; uint256 accuracy; uint256 tempAttack; uint256 damageMultiplier; uint256 action; uint256 numberOfHits; MowseDungeonClassEnum class; MowseDungeonSimpleStatusEffect statusEffects; MowseDungeonSimpleTrinkets trinkets; MowseDungeonCompanion companion; MowseDungeonDescentLevel descentLevel; // MowseDungeonSimplePlayerAchievementsUnlocked achievements; uint256 coins; uint256 currentDungeonRunCount; uint256 currentRoomIndex; } struct MowseDungeonPlayer { uint256 mowseId; int32[SKILL_TYPE_NUM] stats; uint256 maxHealth; uint256 currentHealth; uint256 shield; uint256 attack; // uint256 maxAction; // Special Ability points uint256 action; // Maps StatusEffect to statusEffect value (ex: 1 (poison) => 2 is equal to 2 stacks of poison) mapping(MowseDungeonStatusEffectEnum => uint256) statusEffects; // Maps trinketIndex to MowseDungeonTrinketEnum mapping(MowseDungeonTrinketEnum => MowseDungeonTrinket) trinkets; // uint256 trinketCount; mapping(MowseDungeonCompanionEnum => MowseDungeonCompanion) companions; MowseDungeonCompanion currentCompanion; uint256 coins; MowseDungeonClassEnum class; // Number of times a player has run a dungeon uint256 dungeonRunCount; MowseDungeonSimplePlayerAchievementsUnlocked achievements; // Used for quickly checking if an achievement is unlocked mapping(MowseDungeonAchievementsEnum => bool) achievementsUnlocked; mapping(MowseDungeonAchievementsEnum => bool) achievementsClaimed; MowseDungeonSimplePlayerAchievementsProgress achievementsProgress; MowseDungeonDescentLevel descentLevel; } struct MowseDungeonPerformAction { MowseDungeonActionTypeEnum actionType; uint256 targetIndex; } // Used for _performAction to calculate damage struct MowseDungeonSimpleMonster { MowseDungeonMonsterEnum monsterType; uint256 monsterId; uint256 maxHealth; uint256 currentHealth; uint256 shield; uint256 attack; bool canHit; uint256 accuracy; uint256 tempAttack; uint256 damageMultiplier; MowseDungeonSpecialAbilityEnum specialAbility; bool isBoss; bool hasBeenStolen; bool usedSpecialAbility; MowseDungeonSimpleStatusEffect statusEffects; string image; } // Used for setting default monster values struct MowseDungeonMonsterAttributes { bool isActive; MowseDungeonMonsterEnum monsterType; uint256 monsterId; uint256 maxHealth; uint256 shield; uint256 attack; MowseDungeonSpecialAbilityEnum specialAbility; MowseDungeonSimpleStatusEffect statusEffects; bool isBoss; uint256 coins; string name; string image; } struct MowseDungeonMonster { MowseDungeonMonsterEnum monsterType; uint256 monsterId; uint256 maxHealth; uint256 currentHealth; uint256 shield; uint256 attack; MowseDungeonSpecialAbilityEnum specialAbility; mapping(MowseDungeonStatusEffectEnum => uint256) statusEffects; // Bosses cannot be stunned, slept, etc. bool isBoss; // Maps monsterDropIndex to MowseDungeonTrinket mapping(uint256 => MowseDungeonTrinket) monsterDrops; uint256 monsterDropCount; uint256 coins; // Players can only use steal once per monster bool hasBeenStolen; string name; } // Trinkets are passive boosts to the player they can select after battle // Trinkets do not carry over between dungeon run, however, you can enhance trinkets so they are stronger the next run // Use MowseDungeonTrinketEnum id to conditionally apply statusEffects struct MowseDungeonTrinket { MowseDungeonTrinketEnum trinketId; uint256 level; // mapping(MowseDungeonStatusEffectEnum => uint256) statusEffects; uint256 health; uint256 shield; uint256 attack; } // Should always have 5 items struct MowseDungeonMerchantRoom { MowseDungeonMerchantItem[] items; } struct MowseDungeonMerchantItem { MowseDungeonTrinketEnum trinketId; MowseDungeonTrinket trinket; uint256 cost; bool hasPurchased; } // Unlike Trinkets, Companions carry over between dungeon runs // Companions can level up before a dungeon run struct MowseDungeonCompanion { MowseDungeonCompanionEnum companionId; bool isUnlocked; uint256 level; uint256 experience; } struct MowseDungeonRoom { MowseDungeonRoomEnum id; MowseDungeonRoomTypeEnum roomType; MowseDungeonMonsterEnum[] monsters; } struct MowseDungeon { uint256 id; // Should be the VDF hash MowseDungeonRoom[] rooms; uint256 currentRoomIndex; bool active; MowseDungeonDungeonTypeEnum dungeonType; MowseDungeonMerchantRoom merchantRoom; uint256 descentLevel; } // 0 - normal // 1 - +25% hp/shield // 2 - +25% attack // 3 - +25% attack, -25% coin // 4 - +25% attack/hp/shield // 5 - +25% attack/hp/shield, items cost 10% more // 6 - +25% attack, +50% hp/shield // 7 - +25% attack, +50% hp/shield, -25% coins // 8 - +25% attack, +50% hp/shield, -25% coins, items cost 10% more // 9 - +100% hp/shield, rampage // 10 - +100% hp/shield, rampage, -25% coins, items cost 10% more struct MowseDungeonDescentLevel { uint256 forestDungeon; uint256 medievalDungeon; } // Gather and Garnish struct GatherAndGarnishScavenge { uint256 woodCount; uint256 rockCount; uint256 gemCount; uint256 foodCount; } struct GatherAndGarnishPlayerStats { // Maps season day index -> action index taken [1 - gather, 2 - predict, 3 - build, 4 - invest] mapping(uint256 => uint256) dailyAction; uint256 woodStorage; uint256 woodStorageLevel; uint256 rockStorage; uint256 rockStorageLevel; uint256 gemStorage; uint256 gemStorageLevel; uint256 foodStorage; uint256 foodStorageLevel; uint256 investmentCount; // Maps whether the player has built the first/second/third points structure mapping(uint256 => bool) hasBuiltPointsStructure; // Maps season day index -> resource type prediction [1-4, wood/rock/gem/food] mapping(uint256 => uint256) prediction; uint256 latestPredictionDay; uint256 seasonFirstWinnerIndex; } struct TestPatch { uint256 testPatchVersion; uint256 uniqueInteractionCount; // Unique address interactions address[] interactedAddresses; // Addresses that interacted mapping(address => uint256) numberOfInteractions; // maps addresses -> number of times interacted } struct Mowse { uint256 tokenId; // Mowse asset tokenId counter, also used to check if exists address ownerAddress; // Owner Address // BaseTraits required on all Mowse uint16 generation; MowseWearMetadata baseBackgroundColor; // Index 0 MowseWearMetadata baseSkinColor; // Index 2 MowseWearMetadata baseEarType; // Index 3 MowseWearMetadata baseBodyType; // Index 5 MowseWearMetadata baseMouth; // Index 6 MowseWearMetadata baseEyeType; // Index 8 // MowseJob int32[SKILL_TYPE_NUM] skillLevelBoosts; // Additional Skill LEVEL modifiers int32[SKILL_TYPE_NUM] skillLevel; // Base Skill LEVEL, increases as ExperiencePoints caps [charisma, constitution, dexterity, intelligence, luck, strength, wisdom] // uint32[SKILL_TYPE_NUM] skillExperiencePoints; // Skill EXPERIENCE points // uint16[SKILL_TYPE_NUM] skillExperiencePointsBoosts; // Additional Skill EXPERIENCE points boosts uint8 primarySkillType; // Primary skill preference from birth (should be 0-6), cannot change uint8 secondarySkillType; // Secondary skill preference from birth (should be 0-6, can be the same as primary skill), cannot change uint8 profession; // Career (should be 0-7), can change. // 0 = no profession // 1 = Agriculture and Food // 2 = Finance and Marketing // 3 = Art and Manufacturing // 4 = Science and Medicine // 5 = Military // 6 = Politics (Law and Government) // 7 = Nursing and Childcare (Family-focused) // MowseLife uint16 lifeLevel; // LIFE Experience level uint256 lifeExperiencePoints; // Life Experience points (as life level goes up, skill level can be increased) uint256 prngNonce; // Used in Mowse PRNG (level up to randomly distribute stat points and onMint) // MowseWear uint256[EQUIPPED_WEARABLE_SLOTS] equippedMowseWearByTokenIds; // Currently equipped mowsewear tokenIds // [backgroundColor, backgroundFeature, skinColor, earType, shirt, bodyType, mouth, eyeBrow, eyeType, eyeWear, headWear, jewelry] } // 1 Background Color // 2 Background Feature // 3 Skin Color // 4 Ear Type // 5 Shirt // 6 Body Type // 7 Mouth // 8 Eye Brow Type // 9 Eye Type // 10 Eye Wear // 11 Head Wear // 12 Jewelry struct MowseWear { uint256 tokenId; // MowseWear asset tokenId counter, also used to check if exists bool isEquipped; // Quick way to know if a MowseWear is equipped uint256 equippedBy; // track which Mowse tokenId is equipped by uint256 durability; // Durability time after stitching uint256 alterCount; // Number of times a MowseWear has been altered (stitched or hemmed) uint256 maxAlterCount; // Max number of times a MowseWear can be altered (stitched or hemmed) MowseWearMetadata metadata; MowseWearDimensions dimensions; MowseWearBonuses bonuses; } struct MowseWearMetadata { uint8 traitType; // Type of MowseWear (backgroundColor, shirt, eyeWear, etc) (should be 0-11) string traitName; // MowseWear item name ("Blue Headband") uint16 traitIndex; // MowseWear trait index (12th headband) uint256 dictionaryIndex; // MowseWear dictionary index (12th item in dictionary) bool nonTransferrable; // MowseWear can be traded or not (soulbound) string svgFilter; // Any overrides on the svgFilter MowseWearDimensions baseDimensions; // Base SVG Dimensions } struct MowseWearBonuses { uint256 randomness; // Random seed for MowseWear uint256 itemRarityIV; // Item Rarity inherent value (pseudorandom number between 0-4294967294) uint8 itemRarity; // Item Rarity (common, uncommon, rare, epic, legendary, unique) (should be 0-5) int32[SKILL_TYPE_NUM] baseSkillLevelBoosts; // Base Skill LEVEL modifiers from IV int32[SKILL_TYPE_NUM] additionalSkillLevelBoosts; // Additional Skill LEVEL modifiers from other factors (set bonuses?) } struct MowseSkillTypes { int32 charisma; int32 constitution; int32 dexterity; int32 intelligence; int32 luck; int32 strength; int32 wisdom; } struct MowseWearDimensions { uint16 width; uint16 height; string transform; string style; string image; uint16 weight; } struct MowseLootboxPool { bool active; // Is lootbox active and can be minted from? uint256 price; // Price per MowseGold (generic loot pool cheapest -> specific trait type more expensive -> event specific) string name; uint16 width; // Goes with image to create on-chain SVG uint16 height; // Goes with image to create on-chain SVG string image; mapping(uint16 => uint256) lootPool; // TraitTypes & TraitIndexes in the lootPool for minting uint16 itemCount; // Number of items in lootpool uint256 dateAdded; // When the lootbox was added; Ex: Earlier lootboxes might have rarer items uint256 index; // Index of the lootbox } // This struct is used by MowseLootboxFacet.getMowseLootboxData to return the lootPool mapping as well struct MowseLootboxPoolData { bool active; uint256 price; string name; string image; SimpleMowseLootboxPoolItem[] lootPool; uint16 itemCount; uint256 dateAdded; uint64 index; } struct SimpleMowseLootboxPoolItem { uint16 traitType; uint16 traitIndex; string traitName; string image; } struct MowseLineage { uint16 generation; uint256 parent1; uint256 parent2; uint256[] children; } struct MowseBankStruct { address _walletImplementation; mapping(address => uint256) balances; mapping(address => uint256) getTokenIdForWallet; } struct MowseGames { string name; bool active; // Game is active or disabled (disable if game updates or something. idk. Bad developer) bytes32 gameHash; uint256 totalNumberOfSubmits; mapping(address => uint256) uniqueSubmitsByAddress; address[] uniqueAddressesList; uint256 uniqueAddressesCount; mapping(address => uint256[3]) dailySubmits; // Minimum score to pass to get the max payout MGOLD uint256 minScoreForMaxPayout; // For granting additional bonuses for special event days bool rewardBonus; // For paying game developers address payable developerAddress; } library LibStorage { function gameStorage() internal pure returns (GameStorage storage gs) { assembly { gs.slot := 0 } } function skillTypeToString(uint16 x) internal pure returns (string memory skillTypeString) { require(x < SKILL_TYPE_NUM, "LibStorage: Invalid Skill Type"); if (x == 0) return "charisma"; if (x == 1) return "constitution"; if (x == 2) return "dexterity"; if (x == 3) return "intelligence"; if (x == 4) return "luck"; if (x == 5) return "strength"; if (x == 6) return "wisdom"; } function equippableWearableSlotToString(uint8 traitType) internal pure returns (string memory wearableSlotString) { require(traitType < EQUIPPED_WEARABLE_SLOTS, "LibStorage: Invalid Trait Type"); if (traitType == 0) return "backgroundColor"; if (traitType == 1) return "backgroundFeature"; if (traitType == 2) return "skinColor"; if (traitType == 3) return "earType"; if (traitType == 4) return "shirt"; if (traitType == 5) return "bodyType"; if (traitType == 6) return "mouth"; if (traitType == 7) return "eyeBrow"; if (traitType == 8) return "eyeType"; if (traitType == 9) return "eyeWear"; if (traitType == 10) return "headWear"; if (traitType == 11) return "jewelry"; } function itemRarityToString(uint8 itemRarity) internal pure returns (string memory itemRarityString) { if (itemRarity == 0) return "common"; if (itemRarity == 1) return "uncommon"; if (itemRarity == 2) return "rare"; if (itemRarity == 3) return "epic"; if (itemRarity == 4) return "legendary"; if (itemRarity == 5) return "unique"; } } contract WithStorage { function skillTypeToString(uint16 skillType) internal pure returns (string memory) { return LibStorage.skillTypeToString(skillType); } function equippedWearableSlotToString(uint8 traitType) internal pure returns (string memory) { return LibStorage.equippableWearableSlotToString(traitType); } function itemRarityToString(uint8 itemRarity) internal pure returns (string memory) { return LibStorage.itemRarityToString(itemRarity); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"MissingAdminRole","type":"error"},{"inputs":[],"name":"UintUtils__InsufficientHexLength","type":"error"},{"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"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAccountToAdminRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAccountToMowseAdminRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAccountToMowseGameAdminRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAccountToMowseJobAdminRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAccountToMowseLootboxMinterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAccountToMowseMinterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAccountToMowseWearAdminRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addAccountToMowseWearMinterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"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":"hasAdminRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"hasMowseAdminRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"hasMowseGameAdminRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"hasMowseJobAdminRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"hasMowseLootboxMinterRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"hasMowseMinterRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"hasMowseWearAdminRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"hasMowseWearMinterRole","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":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeAccountToMowseAdminRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeAccountToMowseGameAdminRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeAccountToMowseJobAdminRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeAccountToMowseLootboxMinterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeAccountToMowseMinterRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeAccountToMowseWearAdminRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"revokeAccountToMowseWearMinterRole","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"}]
Contract Creation Code
608060405234801561001057600080fd5b5061117d806100206000396000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80639a43843b116100f9578063c395fcb311610097578063d4583e6911610071578063d4583e69146103b6578063d547741f146103c9578063f9b00087146103dc578063ff82ec6f146103ef57600080fd5b8063c395fcb31461037d578063c7df7d4514610390578063d0d6805a146103a357600080fd5b8063ab93fea8116100d3578063ab93fea814610331578063ad3cb18814610344578063ae20b6ad14610357578063b36404951461036a57600080fd5b80639a43843b146102f85780639cbdb4ee1461030b578063ab34511c1461031e57600080fd5b80633a2c1e84116101665780636623fce0116101405780636623fce0146102ac5780637854cde6146102bf5780638bb9c5bf146102d257806391d14854146102e557600080fd5b80633a2c1e84146102735780633b1e98cc146102865780634cf6e1b61461029957600080fd5b8063248a9ca3116101a2578063248a9ca3146102195780632cd96f5d1461023a5780632f2ff15d1461024d57806333b584261461026057600080fd5b806308532098146101c95780631b163500146101de57806320db841c14610206575b600080fd5b6101dc6101d7366004610f4d565b610402565b005b6101f16101ec366004610f4d565b610460565b60405190151581526020015b60405180910390f35b6101dc610214366004610f4d565b610492565b61022c610227366004610f68565b6104e4565b6040519081526020016101fd565b6101f1610248366004610f4d565b6104ef565b6101dc61025b366004610f81565b61051b565b6101f161026e366004610f4d565b61053c565b6101dc610281366004610f4d565b610568565b6101dc610294366004610f4d565b6105ba565b6101dc6102a7366004610f4d565b61060c565b6101dc6102ba366004610f4d565b61065e565b6101f16102cd366004610f4d565b6106b0565b6101dc6102e0366004610f68565b6106dc565b6101f16102f3366004610f81565b6106e5565b6101f1610306366004610f4d565b6106f8565b6101f1610319366004610f4d565b610724565b6101f161032c366004610f4d565b610750565b6101dc61033f366004610f4d565b61077c565b6101dc610352366004610f4d565b6107ce565b6101dc610365366004610f4d565b610820565b6101dc610378366004610f4d565b6108df565b6101f161038b366004610f4d565b610931565b6101dc61039e366004610f4d565b61093d565b6101dc6103b1366004610f4d565b61098f565b6101dc6103c4366004610f4d565b6109e1565b6101dc6103d7366004610f81565b610a33565b6101dc6103ea366004610f4d565b610a4f565b6101dc6103fd366004610f4d565b610aa1565b61040d600033610af3565b6104335760405163718f3c1960e01b815260040161042a90610fad565b60405180910390fd5b61045d7f681fc3427f35d07a7e8f32411a9c73eb9a7c775b21304295d3642c7e1ffcec5682610b18565b50565b600061048c7f29f5d4666b2401c0d104d670520d4606c59dd0e016408664cf8a916d7478a53583610af3565b92915050565b61049d600033610af3565b6104ba5760405163718f3c1960e01b815260040161042a90610fad565b61045d7f662420d246ea12e5a0cc2c6dcd98a50901d4e6786e1231d6c369fae71fab319682610b7a565b600061048c82610bdc565b600061048c7feb9016f1764e8ed2343b16f47d19fd5b1ca61130739f7a7b102e9b52b19ffaa283610af3565b61052482610bdc565b61052d81610bfe565b6105378383610b18565b505050565b600061048c7f662420d246ea12e5a0cc2c6dcd98a50901d4e6786e1231d6c369fae71fab319683610af3565b610573600033610af3565b6105905760405163718f3c1960e01b815260040161042a90610fad565b61045d7f880b8ae22dc6aed34818c7b353a987a192fefc7a80ee10d6706c3c44f78cccb782610b18565b6105c5600033610af3565b6105e25760405163718f3c1960e01b815260040161042a90610fad565b61045d7f681fc3427f35d07a7e8f32411a9c73eb9a7c775b21304295d3642c7e1ffcec5682610b7a565b610617600033610af3565b6106345760405163718f3c1960e01b815260040161042a90610fad565b61045d7fce77fe32b14dd62688f50405e3d2910441dc633918a3d9f8ab6f2efe893a402d82610b7a565b610669600033610af3565b6106865760405163718f3c1960e01b815260040161042a90610fad565b61045d7feb9016f1764e8ed2343b16f47d19fd5b1ca61130739f7a7b102e9b52b19ffaa282610b7a565b600061048c7f880b8ae22dc6aed34818c7b353a987a192fefc7a80ee10d6706c3c44f78cccb783610af3565b61045d81610c08565b60006106f18383610af3565b9392505050565b600061048c7f524ccf3c577a7e1d7fd62d728b13ea3399aa9c2181684384fbcffa670f0ff62183610af3565b600061048c7f681fc3427f35d07a7e8f32411a9c73eb9a7c775b21304295d3642c7e1ffcec5683610af3565b600061048c7fce77fe32b14dd62688f50405e3d2910441dc633918a3d9f8ab6f2efe893a402d83610af3565b610787600033610af3565b6107a45760405163718f3c1960e01b815260040161042a90610fad565b61045d7feb9016f1764e8ed2343b16f47d19fd5b1ca61130739f7a7b102e9b52b19ffaa282610b18565b6107d9600033610af3565b6107f65760405163718f3c1960e01b815260040161042a90610fad565b61045d7f524ccf3c577a7e1d7fd62d728b13ea3399aa9c2181684384fbcffa670f0ff62182610b7a565b6000546001600160a01b031633148061086257507fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320546001600160a01b031633145b6108d45760405162461bcd60e51b815260206004820152603860248201527f4f6e6c792074686520436f7265206f722041646d696e2061646472657373657360448201527f2063616e20706572666f726d207468697320616374696f6e0000000000000000606482015260840161042a565b61045d600082610b18565b6108ea600033610af3565b6109075760405163718f3c1960e01b815260040161042a90610fad565b61045d7f29f5d4666b2401c0d104d670520d4606c59dd0e016408664cf8a916d7478a53582610b7a565b600061048c8183610af3565b610948600033610af3565b6109655760405163718f3c1960e01b815260040161042a90610fad565b61045d7f662420d246ea12e5a0cc2c6dcd98a50901d4e6786e1231d6c369fae71fab319682610b18565b61099a600033610af3565b6109b75760405163718f3c1960e01b815260040161042a90610fad565b61045d7f880b8ae22dc6aed34818c7b353a987a192fefc7a80ee10d6706c3c44f78cccb782610b7a565b6109ec600033610af3565b610a095760405163718f3c1960e01b815260040161042a90610fad565b61045d7f524ccf3c577a7e1d7fd62d728b13ea3399aa9c2181684384fbcffa670f0ff62182610b18565b610a3c82610bdc565b610a4581610bfe565b6105378383610b7a565b610a5a600033610af3565b610a775760405163718f3c1960e01b815260040161042a90610fad565b61045d7f29f5d4666b2401c0d104d670520d4606c59dd0e016408664cf8a916d7478a53582610b18565b610aac600033610af3565b610ac95760405163718f3c1960e01b815260040161042a90610fad565b61045d7fce77fe32b14dd62688f50405e3d2910441dc633918a3d9f8ab6f2efe893a402d82610b18565b6000828152600080516020611128833981519152602052604081206106f19083610c12565b600082815260008051602061112883398151915260205260409020610b3d9082610c34565b5060405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b600082815260008051602061112883398151915260205260409020610b9f9082610c49565b5060405133906001600160a01b0383169084907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b90600090a45050565b6000908152600080516020611128833981519152602052604090206002015490565b61045d8133610c5e565b61045d8133610b7a565b6001600160a01b038116600090815260018301602052604081205415156106f1565b60006106f1836001600160a01b038416610cc4565b60006106f1836001600160a01b038416610d07565b610c688282610af3565b610cc057610c7e816001600160a01b0316610dcc565b610c89836020610dde565b604051602001610c9a929190610ffd565b60408051601f198184030181529082905262461bcd60e51b825261042a91600401611072565b5050565b600081815260018301602052604081205461048c575081546001808201845560008481526020808220909301849055845493815293810190915260409092205590565b60008181526001830160205260408120548015610dc557835460009085906000198101908110610d3957610d396110a5565b9060005260206000200154905080856000016001840381548110610d5f57610d5f6110a5565b6000918252602080832090910192909255918252600186019052604090208190558354849080610d9157610d916110bb565b6001900381819060005260206000200160009055905583600101600084815260200190815260200160002060009055600191505b5092915050565b606061048c6001600160a01b03831660145b60606000610ded8360026110e7565b610df89060026110fe565b67ffffffffffffffff811115610e1057610e10611111565b6040519080825280601f01601f191660200182016040528015610e3a576020820181803683370190505b509050600360fc1b81600081518110610e5557610e556110a5565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110610e8457610e846110a5565b60200101906001600160f81b031916908160001a905350600160028402015b6001811115610f11576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110610ed457610ed46110a5565b1a60f81b828281518110610eea57610eea6110a5565b60200101906001600160f81b031916908160001a90535060049490941c9360001901610ea3565b5083156106f15760405163c913478560e01b815260040160405180910390fd5b80356001600160a01b0381168114610f4857600080fd5b919050565b600060208284031215610f5f57600080fd5b6106f182610f31565b600060208284031215610f7a57600080fd5b5035919050565b60008060408385031215610f9457600080fd5b82359150610fa460208401610f31565b90509250929050565b6020808252601290820152714d697373696e672041646d696e20726f6c6560701b604082015260600190565b60005b83811015610ff4578181015183820152602001610fdc565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611035816017850160208801610fd9565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611066816028840160208801610fd9565b01602801949350505050565b6020815260008251806020840152611091816040850160208701610fd9565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761048c5761048c6110d1565b8082018082111561048c5761048c6110d1565b634e487b7160e01b600052604160045260246000fdfed3889cc5458b268d0544e5534672df1296288ca3f93cbd39bd6f497a5c622811a2646970667358221220d2eca1442d60bd37f3eeece2cd092ee2fdbdc68a79b16ff254b71c1455f10a1864736f6c63430008130033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80639a43843b116100f9578063c395fcb311610097578063d4583e6911610071578063d4583e69146103b6578063d547741f146103c9578063f9b00087146103dc578063ff82ec6f146103ef57600080fd5b8063c395fcb31461037d578063c7df7d4514610390578063d0d6805a146103a357600080fd5b8063ab93fea8116100d3578063ab93fea814610331578063ad3cb18814610344578063ae20b6ad14610357578063b36404951461036a57600080fd5b80639a43843b146102f85780639cbdb4ee1461030b578063ab34511c1461031e57600080fd5b80633a2c1e84116101665780636623fce0116101405780636623fce0146102ac5780637854cde6146102bf5780638bb9c5bf146102d257806391d14854146102e557600080fd5b80633a2c1e84146102735780633b1e98cc146102865780634cf6e1b61461029957600080fd5b8063248a9ca3116101a2578063248a9ca3146102195780632cd96f5d1461023a5780632f2ff15d1461024d57806333b584261461026057600080fd5b806308532098146101c95780631b163500146101de57806320db841c14610206575b600080fd5b6101dc6101d7366004610f4d565b610402565b005b6101f16101ec366004610f4d565b610460565b60405190151581526020015b60405180910390f35b6101dc610214366004610f4d565b610492565b61022c610227366004610f68565b6104e4565b6040519081526020016101fd565b6101f1610248366004610f4d565b6104ef565b6101dc61025b366004610f81565b61051b565b6101f161026e366004610f4d565b61053c565b6101dc610281366004610f4d565b610568565b6101dc610294366004610f4d565b6105ba565b6101dc6102a7366004610f4d565b61060c565b6101dc6102ba366004610f4d565b61065e565b6101f16102cd366004610f4d565b6106b0565b6101dc6102e0366004610f68565b6106dc565b6101f16102f3366004610f81565b6106e5565b6101f1610306366004610f4d565b6106f8565b6101f1610319366004610f4d565b610724565b6101f161032c366004610f4d565b610750565b6101dc61033f366004610f4d565b61077c565b6101dc610352366004610f4d565b6107ce565b6101dc610365366004610f4d565b610820565b6101dc610378366004610f4d565b6108df565b6101f161038b366004610f4d565b610931565b6101dc61039e366004610f4d565b61093d565b6101dc6103b1366004610f4d565b61098f565b6101dc6103c4366004610f4d565b6109e1565b6101dc6103d7366004610f81565b610a33565b6101dc6103ea366004610f4d565b610a4f565b6101dc6103fd366004610f4d565b610aa1565b61040d600033610af3565b6104335760405163718f3c1960e01b815260040161042a90610fad565b60405180910390fd5b61045d7f681fc3427f35d07a7e8f32411a9c73eb9a7c775b21304295d3642c7e1ffcec5682610b18565b50565b600061048c7f29f5d4666b2401c0d104d670520d4606c59dd0e016408664cf8a916d7478a53583610af3565b92915050565b61049d600033610af3565b6104ba5760405163718f3c1960e01b815260040161042a90610fad565b61045d7f662420d246ea12e5a0cc2c6dcd98a50901d4e6786e1231d6c369fae71fab319682610b7a565b600061048c82610bdc565b600061048c7feb9016f1764e8ed2343b16f47d19fd5b1ca61130739f7a7b102e9b52b19ffaa283610af3565b61052482610bdc565b61052d81610bfe565b6105378383610b18565b505050565b600061048c7f662420d246ea12e5a0cc2c6dcd98a50901d4e6786e1231d6c369fae71fab319683610af3565b610573600033610af3565b6105905760405163718f3c1960e01b815260040161042a90610fad565b61045d7f880b8ae22dc6aed34818c7b353a987a192fefc7a80ee10d6706c3c44f78cccb782610b18565b6105c5600033610af3565b6105e25760405163718f3c1960e01b815260040161042a90610fad565b61045d7f681fc3427f35d07a7e8f32411a9c73eb9a7c775b21304295d3642c7e1ffcec5682610b7a565b610617600033610af3565b6106345760405163718f3c1960e01b815260040161042a90610fad565b61045d7fce77fe32b14dd62688f50405e3d2910441dc633918a3d9f8ab6f2efe893a402d82610b7a565b610669600033610af3565b6106865760405163718f3c1960e01b815260040161042a90610fad565b61045d7feb9016f1764e8ed2343b16f47d19fd5b1ca61130739f7a7b102e9b52b19ffaa282610b7a565b600061048c7f880b8ae22dc6aed34818c7b353a987a192fefc7a80ee10d6706c3c44f78cccb783610af3565b61045d81610c08565b60006106f18383610af3565b9392505050565b600061048c7f524ccf3c577a7e1d7fd62d728b13ea3399aa9c2181684384fbcffa670f0ff62183610af3565b600061048c7f681fc3427f35d07a7e8f32411a9c73eb9a7c775b21304295d3642c7e1ffcec5683610af3565b600061048c7fce77fe32b14dd62688f50405e3d2910441dc633918a3d9f8ab6f2efe893a402d83610af3565b610787600033610af3565b6107a45760405163718f3c1960e01b815260040161042a90610fad565b61045d7feb9016f1764e8ed2343b16f47d19fd5b1ca61130739f7a7b102e9b52b19ffaa282610b18565b6107d9600033610af3565b6107f65760405163718f3c1960e01b815260040161042a90610fad565b61045d7f524ccf3c577a7e1d7fd62d728b13ea3399aa9c2181684384fbcffa670f0ff62182610b7a565b6000546001600160a01b031633148061086257507fc8fcad8db84d3cc18b4c41d551ea0ee66dd599cde068d998e57d5e09332c1320546001600160a01b031633145b6108d45760405162461bcd60e51b815260206004820152603860248201527f4f6e6c792074686520436f7265206f722041646d696e2061646472657373657360448201527f2063616e20706572666f726d207468697320616374696f6e0000000000000000606482015260840161042a565b61045d600082610b18565b6108ea600033610af3565b6109075760405163718f3c1960e01b815260040161042a90610fad565b61045d7f29f5d4666b2401c0d104d670520d4606c59dd0e016408664cf8a916d7478a53582610b7a565b600061048c8183610af3565b610948600033610af3565b6109655760405163718f3c1960e01b815260040161042a90610fad565b61045d7f662420d246ea12e5a0cc2c6dcd98a50901d4e6786e1231d6c369fae71fab319682610b18565b61099a600033610af3565b6109b75760405163718f3c1960e01b815260040161042a90610fad565b61045d7f880b8ae22dc6aed34818c7b353a987a192fefc7a80ee10d6706c3c44f78cccb782610b7a565b6109ec600033610af3565b610a095760405163718f3c1960e01b815260040161042a90610fad565b61045d7f524ccf3c577a7e1d7fd62d728b13ea3399aa9c2181684384fbcffa670f0ff62182610b18565b610a3c82610bdc565b610a4581610bfe565b6105378383610b7a565b610a5a600033610af3565b610a775760405163718f3c1960e01b815260040161042a90610fad565b61045d7f29f5d4666b2401c0d104d670520d4606c59dd0e016408664cf8a916d7478a53582610b18565b610aac600033610af3565b610ac95760405163718f3c1960e01b815260040161042a90610fad565b61045d7fce77fe32b14dd62688f50405e3d2910441dc633918a3d9f8ab6f2efe893a402d82610b18565b6000828152600080516020611128833981519152602052604081206106f19083610c12565b600082815260008051602061112883398151915260205260409020610b3d9082610c34565b5060405133906001600160a01b0383169084907f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d90600090a45050565b600082815260008051602061112883398151915260205260409020610b9f9082610c49565b5060405133906001600160a01b0383169084907ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b90600090a45050565b6000908152600080516020611128833981519152602052604090206002015490565b61045d8133610c5e565b61045d8133610b7a565b6001600160a01b038116600090815260018301602052604081205415156106f1565b60006106f1836001600160a01b038416610cc4565b60006106f1836001600160a01b038416610d07565b610c688282610af3565b610cc057610c7e816001600160a01b0316610dcc565b610c89836020610dde565b604051602001610c9a929190610ffd565b60408051601f198184030181529082905262461bcd60e51b825261042a91600401611072565b5050565b600081815260018301602052604081205461048c575081546001808201845560008481526020808220909301849055845493815293810190915260409092205590565b60008181526001830160205260408120548015610dc557835460009085906000198101908110610d3957610d396110a5565b9060005260206000200154905080856000016001840381548110610d5f57610d5f6110a5565b6000918252602080832090910192909255918252600186019052604090208190558354849080610d9157610d916110bb565b6001900381819060005260206000200160009055905583600101600084815260200190815260200160002060009055600191505b5092915050565b606061048c6001600160a01b03831660145b60606000610ded8360026110e7565b610df89060026110fe565b67ffffffffffffffff811115610e1057610e10611111565b6040519080825280601f01601f191660200182016040528015610e3a576020820181803683370190505b509050600360fc1b81600081518110610e5557610e556110a5565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110610e8457610e846110a5565b60200101906001600160f81b031916908160001a905350600160028402015b6001811115610f11576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110610ed457610ed46110a5565b1a60f81b828281518110610eea57610eea6110a5565b60200101906001600160f81b031916908160001a90535060049490941c9360001901610ea3565b5083156106f15760405163c913478560e01b815260040160405180910390fd5b80356001600160a01b0381168114610f4857600080fd5b919050565b600060208284031215610f5f57600080fd5b6106f182610f31565b600060208284031215610f7a57600080fd5b5035919050565b60008060408385031215610f9457600080fd5b82359150610fa460208401610f31565b90509250929050565b6020808252601290820152714d697373696e672041646d696e20726f6c6560701b604082015260600190565b60005b83811015610ff4578181015183820152602001610fdc565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351611035816017850160208801610fd9565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351611066816028840160208801610fd9565b01602801949350505050565b6020815260008251806020840152611091816040850160208701610fd9565b601f01601f19169190910160400192915050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761048c5761048c6110d1565b8082018082111561048c5761048c6110d1565b634e487b7160e01b600052604160045260246000fdfed3889cc5458b268d0544e5534672df1296288ca3f93cbd39bd6f497a5c622811a2646970667358221220d2eca1442d60bd37f3eeece2cd092ee2fdbdc68a79b16ff254b71c1455f10a1864736f6c63430008130033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.