Overview
S Balance
0 S
S Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
MowseDungeonGettersFacet
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: UNLICENSED pragma solidity ^0.8.12; /************************************************************************* ___ ___ | \/ | ___ | . . | _____ _____ ___ _ _ .-' '-. | |\/| |/ _ \ \ /\ / / __|/ _ \ (.)(.)/ \ | | | | (_) \ V V /\__ \ __/ /@@ ; \_| |_/\___/ \_/\_/ |___/\___| o_\\-mm-......-mm`~~~~~~~~~~~~~~~~` /*************************************************************************/ import "@openzeppelin/contracts/utils/Strings.sol"; import {LibDiamond} from "../../libraries/LibDiamond.sol"; import "../../libraries/Base64.sol"; import "../../libraries/SlothVerifiableDelay.sol"; import { WithStorage, GameStorage, MowseDungeonMonsterEnum, MowseDungeonMonsterAttributes, MowseDungeonRoom, MowseDungeonRoomTypeEnum, MowseDungeonPlayer, MowseDungeon, MowseDungeonRoomEnum, MowseDungeonDungeonRewards, MowseDungeonSimpleMonster } from "../../libraries/LibStorage.sol"; import {AccessControlFacet} from "../AccessControlFacet.sol"; contract MowseDungeonGettersFacet is WithStorage { using Strings for uint256; GameStorage internal gs; error MissingAdminRole(string); error NoActiveDungeon(); error MonsterDoesNotExist(string); error DungeonIsStillActive(); error InvalidDungeonRunNonce(uint256 mowseTokenId, uint256 dungeonRunCount); modifier onlyAdmin() { if (!AccessControlFacet(gs.diamondAddress).hasMowseAdminRole(msg.sender)) revert MissingAdminRole("Must have Admin Role"); _; } function getMonsterDefaults(uint256 monsterId) external view returns (MowseDungeonMonsterAttributes memory) { if (gs.mowseDungeonMonsterDefaultsCount <= monsterId) revert MonsterDoesNotExist("Monster does not exist"); return gs.mowseDungeonMonsterDefaults[MowseDungeonMonsterEnum(monsterId)]; } function getCurrentRoomType(uint256 tokenId) external view returns (MowseDungeonRoomTypeEnum) { MowseDungeonPlayer storage player = gs.mowseDungeonPlayer[tokenId]; MowseDungeon storage dungeon = gs.mowsedungeons[tokenId][player.dungeonRunCount]; if (!dungeon.active) { return MowseDungeonRoomTypeEnum.INVALID_ROOM; } return dungeon.rooms[dungeon.currentRoomIndex].roomType; } function getDungeonRewards(uint256 tokenId, uint256 dungeonRunCount) external view returns (MowseDungeonDungeonRewards memory) { return gs.mowseDungeonDungeonRewards[tokenId][dungeonRunCount]; } function updateMonsterDefaultImage(MowseDungeonMonsterEnum monsterType, string memory image) external onlyAdmin { gs.mowseDungeonMonsterDefaults[monsterType].image = image; } function updateMonsterDefault(MowseDungeonMonsterEnum monsterType, uint256 maxHealth, uint256 shield, uint256 attack, uint256 coins) external onlyAdmin { gs.mowseDungeonMonsterDefaults[monsterType].maxHealth = maxHealth; gs.mowseDungeonMonsterDefaults[monsterType].shield = shield; gs.mowseDungeonMonsterDefaults[monsterType].attack = attack; gs.mowseDungeonMonsterDefaults[monsterType].coins = coins; } function getMonsterDefaultAttributes(MowseDungeonMonsterEnum monsterType) external view returns (MowseDungeonMonsterAttributes memory) { return gs.mowseDungeonMonsterDefaults[monsterType]; } function getMonsterRoomDefault(MowseDungeonRoomEnum roomType) external view returns (MowseDungeonRoom memory) { return gs.mowseDungeonRoomDefaults[roomType]; } function getCurrentRoom(uint256 tokenId) external view returns (MowseDungeonRoom memory) { MowseDungeonPlayer storage player = gs.mowseDungeonPlayer[tokenId]; MowseDungeon storage dungeon = gs.mowsedungeons[tokenId][player.dungeonRunCount]; if (!dungeon.active) { revert NoActiveDungeon(); } return dungeon.rooms[dungeon.currentRoomIndex]; } function getDungeonRooms(uint256 tokenId) external view returns (MowseDungeonRoom[] memory) { MowseDungeonPlayer storage player = gs.mowseDungeonPlayer[tokenId]; MowseDungeon storage dungeon = gs.mowsedungeons[tokenId][player.dungeonRunCount]; if (!dungeon.active) { revert NoActiveDungeon(); } return dungeon.rooms; } function getMowseDungeonVDFSeed(uint256 tokenId, uint256 dungeonRunCount) external view returns (uint256) { MowseDungeon storage dungeon = gs.mowsedungeons[tokenId][dungeonRunCount]; if (!dungeon.active) { revert DungeonIsStillActive(); } return gs.mowseDungeonRunCountToSeed[tokenId][dungeonRunCount]; } function proveMowseDungeonById(uint256 mowseTokenId, uint256 dungeonRunCount, uint256 proof) external view returns (bool) { if (gs.mowseDungeonRunCountToSeed[mowseTokenId][dungeonRunCount] == 0) revert InvalidDungeonRunNonce(mowseTokenId, dungeonRunCount); if (_prove(proof, gs.mowseDungeonRunCountToSeed[mowseTokenId][dungeonRunCount])) { return true; } else { return false; } } function getMowseDungeonProofById(uint256 mowseTokenId, uint256 dungeonRunCount) external view returns (uint256) { if (gs.mowseDungeonRunCountToSeed[mowseTokenId][dungeonRunCount] == 0) revert InvalidDungeonRunNonce(mowseTokenId, dungeonRunCount); return SlothVerifiableDelay.compute( gs.mowseDungeonRunCountToSeed[mowseTokenId][dungeonRunCount], gs.mowseDungeonPrime, gs.mowseDungeonIterations ); } function _prove(uint256 proof, uint256 seed) internal view returns (bool) { return SlothVerifiableDelay.verify(proof, seed, gs.mowseDungeonPrime, gs.mowseDungeonIterations); } function updateMonsterByDescentLevel( MowseDungeonSimpleMonster memory _monster, uint256 _descentLevel ) external pure returns (MowseDungeonSimpleMonster memory) { if (_descentLevel == 0) { return _monster; } else if (_descentLevel == 1) { // Increase monster health & shield by 25% _monster.maxHealth = (_monster.maxHealth * 125) / 100; _monster.currentHealth = _monster.maxHealth; _monster.shield = (_monster.shield * 125) / 100; } else if (_descentLevel == 2) { // Increase monster attack by 25% _monster.attack = (_monster.attack * 125) / 100; } else if (_descentLevel == 3) { // Increase monster attack by 25%, monster coins -25% _monster.attack = (_monster.attack * 125) / 100; } else if (_descentLevel == 4) { // Increase monster attack by 25%, hp shield by 25% _monster.attack = (_monster.attack * 125) / 100; _monster.shield = (_monster.shield * 125) / 100; _monster.maxHealth = (_monster.maxHealth * 125) / 100; _monster.currentHealth = _monster.maxHealth; } else if (_descentLevel == 5) { // Increase monster attack by 25%, hp shield by 25%, items cost 10% more _monster.attack = (_monster.attack * 125) / 100; _monster.shield = (_monster.shield * 125) / 100; _monster.maxHealth = (_monster.maxHealth * 125) / 100; _monster.currentHealth = _monster.maxHealth; } else if (_descentLevel == 6) { // Increase monster attack by 25%, hp shield by 50% _monster.attack = (_monster.attack * 125) / 100; _monster.shield = (_monster.shield * 150) / 100; _monster.maxHealth = (_monster.maxHealth * 150) / 100; _monster.currentHealth = _monster.maxHealth; } else if (_descentLevel == 7) { // Increase monster attack by 25%, hp shield by 50%, monster coins -25% _monster.attack = (_monster.attack * 125) / 100; _monster.shield = (_monster.shield * 150) / 100; _monster.maxHealth = (_monster.maxHealth * 150) / 100; _monster.currentHealth = _monster.maxHealth; } else if (_descentLevel == 8) { // Increase monster attack by 25%, hp shield by 50%, monster coins -25%, items cost 10% more _monster.attack = (_monster.attack * 125) / 100; _monster.shield = (_monster.shield * 150) / 100; _monster.maxHealth = (_monster.maxHealth * 150) / 100; _monster.currentHealth = _monster.maxHealth; } else if (_descentLevel == 9) { // Increase monster hp shield by 100%, all monsters have rampage _monster.shield = _monster.shield * 2; _monster.maxHealth = _monster.maxHealth * 2; _monster.currentHealth = _monster.maxHealth; _monster.statusEffects.rampage = 1; } else if (_descentLevel == 10) { // Increase monster attack by 25%, hp shield by 100%, all monsters have rampage, monster coins -25%, items cost 10% more _monster.attack = (_monster.attack * 125) / 100; _monster.shield = _monster.shield * 2; _monster.maxHealth = _monster.maxHealth * 2; _monster.currentHealth = _monster.maxHealth; _monster.statusEffects.rampage = 1; } return _monster; } function monsterEnumToSimpleMonster(MowseDungeonMonsterEnum _monsterType) external view returns (MowseDungeonSimpleMonster memory) { MowseDungeonMonsterAttributes memory _monster = gs.mowseDungeonMonsterDefaults[_monsterType]; return MowseDungeonSimpleMonster({ monsterType: _monster.monsterType, monsterId: _monster.monsterId, maxHealth: _monster.maxHealth, currentHealth: _monster.maxHealth, shield: _monster.shield, attack: _monster.attack, canHit: false, accuracy: 100, tempAttack: _monster.attack, damageMultiplier: 100, specialAbility: _monster.specialAbility, isBoss: _monster.isBoss, hasBeenStolen: false, usedSpecialAbility: false, statusEffects: _monster.statusEffects, image: _monster.image }); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a > b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { // Solidity will revert if denominator == 0, unlike the div opcode on its own. // The surrounding unchecked block does not change this fact. // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic. return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1, "Math: mulDiv overflow"); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`. // // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)` // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))` // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)` // // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1 << (log2(a) >> 1); // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = sqrt(a); return result + (rounding == Rounding.Up && result * result < a ? 1 : 0); } } /** * @dev Return the log in base 2, rounded down, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 128; } if (value >> 64 > 0) { value >>= 64; result += 64; } if (value >> 32 > 0) { value >>= 32; result += 32; } if (value >> 16 > 0) { value >>= 16; result += 16; } if (value >> 8 > 0) { value >>= 8; result += 8; } if (value >> 4 > 0) { value >>= 4; result += 4; } if (value >> 2 > 0) { value >>= 2; result += 2; } if (value >> 1 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 2, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log2(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log2(value); return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0); } } /** * @dev Return the log in base 10, rounded down, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >= 10 ** 64) { value /= 10 ** 64; result += 64; } if (value >= 10 ** 32) { value /= 10 ** 32; result += 32; } if (value >= 10 ** 16) { value /= 10 ** 16; result += 16; } if (value >= 10 ** 8) { value /= 10 ** 8; result += 8; } if (value >= 10 ** 4) { value /= 10 ** 4; result += 4; } if (value >= 10 ** 2) { value /= 10 ** 2; result += 2; } if (value >= 10 ** 1) { result += 1; } } return result; } /** * @dev Return the log in base 10, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log10(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log10(value); return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0); } } /** * @dev Return the log in base 256, rounded down, of a positive value. * Returns 0 if given 0. * * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string. */ function log256(uint256 value) internal pure returns (uint256) { uint256 result = 0; unchecked { if (value >> 128 > 0) { value >>= 128; result += 16; } if (value >> 64 > 0) { value >>= 64; result += 8; } if (value >> 32 > 0) { value >>= 32; result += 4; } if (value >> 16 > 0) { value >>= 16; result += 2; } if (value >> 8 > 0) { result += 1; } } return result; } /** * @dev Return the log in base 256, following the selected rounding direction, of a positive value. * Returns 0 if given 0. */ function log256(uint256 value, Rounding rounding) internal pure returns (uint256) { unchecked { uint256 result = log256(value); return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol) pragma solidity ^0.8.0; /** * @dev Standard signed math utilities missing in the Solidity language. */ library SignedMath { /** * @dev Returns the largest of two signed numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a > b ? a : b; } /** * @dev Returns the smallest of two signed numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the average of two signed numbers without overflow. * The result is rounded towards zero. */ function average(int256 a, int256 b) internal pure returns (int256) { // Formula from the book "Hacker's Delight" int256 x = (a & b) + ((a ^ b) >> 1); return x + (int256(uint256(x) >> 255) & (a ^ b)); } /** * @dev Returns the absolute unsigned value of a signed value. */ function abs(int256 n) internal pure returns (uint256) { unchecked { // must be unchecked in order to support `n = type(int256).min` return uint256(n >= 0 ? n : -n); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol) pragma solidity ^0.8.0; import "./math/Math.sol"; import "./math/SignedMath.sol"; /** * @dev String operations. */ library Strings { bytes16 private constant _SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { unchecked { uint256 length = Math.log10(value) + 1; string memory buffer = new string(length); uint256 ptr; /// @solidity memory-safe-assembly assembly { ptr := add(buffer, add(32, length)) } while (true) { ptr--; /// @solidity memory-safe-assembly assembly { mstore8(ptr, byte(mod(value, 10), _SYMBOLS)) } value /= 10; if (value == 0) break; } return buffer; } } /** * @dev Converts a `int256` to its ASCII `string` decimal representation. */ function toString(int256 value) internal pure returns (string memory) { return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value)))); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { unchecked { return toHexString(value, Math.log256(value) + 1); } } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed 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"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } /** * @dev Returns true if the two strings are equal. */ function equal(string memory a, string memory b) internal pure returns (bool) { return keccak256(bytes(a)) == keccak256(bytes(b)); } }
// 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.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; /******************************************************************************\ * 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 // Credit https://github.com/derekchiang/loot-name/blob/main/contracts/LootName.sol pragma solidity ^0.8.12; /// [MIT License] /// @title Base64 /// @notice Provides a function for encoding some bytes in base64 /// @author Brecht Devos <[email protected]> library Base64 { bytes internal constant TABLE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; /// @notice Encodes some bytes to the base64 representation function encode(bytes memory data) internal pure returns (string memory) { uint256 len = data.length; if (len == 0) return ''; // multiply by 4/3 rounded up uint256 encodedLen = 4 * ((len + 2) / 3); // Add some extra buffer at the end bytes memory result = new bytes(encodedLen + 32); bytes memory table = TABLE; assembly { let tablePtr := add(table, 1) let resultPtr := add(result, 32) for { let i := 0 } lt(i, len) { } { i := add(i, 3) let input := and(mload(add(data, i)), 0xffffff) let out := mload(add(tablePtr, and(shr(18, input), 0x3F))) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF)) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF)) out := shl(8, out) out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF)) out := shl(224, out) mstore(resultPtr, out) resultPtr := add(resultPtr, 4) } switch mod(len, 3) case 1 { mstore(sub(resultPtr, 2), shl(240, 0x3d3d)) } case 2 { mstore(sub(resultPtr, 1), shl(248, 0x3d)) } mstore(result, encodedLen) } return string(result); } }
// 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; bytes encodedActionsRun; } struct MowseDungeonBattleResults { MowseDungeonBattleSimulation simulation; MowseDungeonPostBattleResults postBattleResults; bytes encodedBattleSimulation; bytes32 packedEncodedBattleSimulation; // 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; uint256 currentRoomIndex; } 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); } }
// SPDX-License-Identifier: MIT // https://eprint.iacr.org/2015/366.pdf pragma solidity ^0.8.12; // TODO: checking for quadratic residues has been removed, unclear of implications library SlothVerifiableDelay { /// @dev verify sloth result proof, starting from seed, over prime, for iterations /// @param _proof result /// @param _seed seed /// @param _prime prime /// @param _iterations number of iterations /// @return true if y is a quadratic residue modulo p function verify( uint256 _proof, uint256 _seed, uint256 _prime, uint256 _iterations ) internal pure returns (bool) { for (uint256 i; i < _iterations; ++i) { _proof = mulmod(_proof, _proof, _prime); } _seed %= _prime; if (_seed == _proof) return true; if (_prime - _seed == _proof) return true; return false; } /// @dev pow(base, exponent, modulus) /// @param base base /// @param exponent exponent /// @param modulus modulus function bexmod( uint256 base, uint256 exponent, uint256 modulus ) internal pure returns (uint256) { uint256 _result = 1; uint256 _base = base; for (; exponent > 0; exponent >>= 1) { if (exponent & 1 == 1) { _result = mulmod(_result, _base, modulus); } _base = mulmod(_base, _base, modulus); } return _result; } /// @dev compute sloth starting from seed, over prime, for iterations /// @param _seed seed /// @param _prime prime /// @param _iterations number of iterations /// @return sloth result function compute( uint256 _seed, uint256 _prime, uint256 _iterations ) internal pure returns (uint256) { uint256 _exponent = (_prime + 1) >> 2; _seed %= _prime; for (uint256 i; i < _iterations; ++i) { _seed = bexmod(_seed, _exponent, _prime); } return _seed; } }
{ "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":[],"name":"DungeonIsStillActive","type":"error"},{"inputs":[{"internalType":"uint256","name":"mowseTokenId","type":"uint256"},{"internalType":"uint256","name":"dungeonRunCount","type":"uint256"}],"name":"InvalidDungeonRunNonce","type":"error"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"MissingAdminRole","type":"error"},{"inputs":[{"internalType":"string","name":"","type":"string"}],"name":"MonsterDoesNotExist","type":"error"},{"inputs":[],"name":"NoActiveDungeon","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getCurrentRoom","outputs":[{"components":[{"internalType":"enum MowseDungeonRoomEnum","name":"id","type":"uint8"},{"internalType":"enum MowseDungeonRoomTypeEnum","name":"roomType","type":"uint8"},{"internalType":"enum MowseDungeonMonsterEnum[]","name":"monsters","type":"uint8[]"}],"internalType":"struct MowseDungeonRoom","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getCurrentRoomType","outputs":[{"internalType":"enum MowseDungeonRoomTypeEnum","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"dungeonRunCount","type":"uint256"}],"name":"getDungeonRewards","outputs":[{"components":[{"internalType":"bool","name":"hasRewards","type":"bool"},{"internalType":"uint256","name":"mgoldMintAmount","type":"uint256"},{"internalType":"uint256","name":"xpGainedAmount","type":"uint256"},{"internalType":"uint256","name":"companionXpGained","type":"uint256"},{"internalType":"uint256","name":"completionPercentage","type":"uint256"},{"internalType":"uint256","name":"additionalFactor","type":"uint256"}],"internalType":"struct MowseDungeonDungeonRewards","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getDungeonRooms","outputs":[{"components":[{"internalType":"enum MowseDungeonRoomEnum","name":"id","type":"uint8"},{"internalType":"enum MowseDungeonRoomTypeEnum","name":"roomType","type":"uint8"},{"internalType":"enum MowseDungeonMonsterEnum[]","name":"monsters","type":"uint8[]"}],"internalType":"struct MowseDungeonRoom[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"}],"name":"getMonsterDefaultAttributes","outputs":[{"components":[{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"uint256","name":"coins","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonMonsterAttributes","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"monsterId","type":"uint256"}],"name":"getMonsterDefaults","outputs":[{"components":[{"internalType":"bool","name":"isActive","type":"bool"},{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"uint256","name":"coins","type":"uint256"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonMonsterAttributes","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum MowseDungeonRoomEnum","name":"roomType","type":"uint8"}],"name":"getMonsterRoomDefault","outputs":[{"components":[{"internalType":"enum MowseDungeonRoomEnum","name":"id","type":"uint8"},{"internalType":"enum MowseDungeonRoomTypeEnum","name":"roomType","type":"uint8"},{"internalType":"enum MowseDungeonMonsterEnum[]","name":"monsters","type":"uint8[]"}],"internalType":"struct MowseDungeonRoom","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"mowseTokenId","type":"uint256"},{"internalType":"uint256","name":"dungeonRunCount","type":"uint256"}],"name":"getMowseDungeonProofById","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"dungeonRunCount","type":"uint256"}],"name":"getMowseDungeonVDFSeed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"enum MowseDungeonMonsterEnum","name":"_monsterType","type":"uint8"}],"name":"monsterEnumToSimpleMonster","outputs":[{"components":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"bool","name":"hasBeenStolen","type":"bool"},{"internalType":"bool","name":"usedSpecialAbility","type":"bool"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonSimpleMonster","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"mowseTokenId","type":"uint256"},{"internalType":"uint256","name":"dungeonRunCount","type":"uint256"},{"internalType":"uint256","name":"proof","type":"uint256"}],"name":"proveMowseDungeonById","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"bool","name":"hasBeenStolen","type":"bool"},{"internalType":"bool","name":"usedSpecialAbility","type":"bool"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonSimpleMonster","name":"_monster","type":"tuple"},{"internalType":"uint256","name":"_descentLevel","type":"uint256"}],"name":"updateMonsterByDescentLevel","outputs":[{"components":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"monsterId","type":"uint256"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"currentHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"bool","name":"canHit","type":"bool"},{"internalType":"uint256","name":"accuracy","type":"uint256"},{"internalType":"uint256","name":"tempAttack","type":"uint256"},{"internalType":"uint256","name":"damageMultiplier","type":"uint256"},{"internalType":"enum MowseDungeonSpecialAbilityEnum","name":"specialAbility","type":"uint8"},{"internalType":"bool","name":"isBoss","type":"bool"},{"internalType":"bool","name":"hasBeenStolen","type":"bool"},{"internalType":"bool","name":"usedSpecialAbility","type":"bool"},{"components":[{"internalType":"uint256","name":"blind","type":"uint256"},{"internalType":"uint256","name":"eagleEye","type":"uint256"},{"internalType":"uint256","name":"poison","type":"uint256"},{"internalType":"uint256","name":"burn","type":"uint256"},{"internalType":"uint256","name":"bleed","type":"uint256"},{"internalType":"uint256","name":"curse","type":"uint256"},{"internalType":"uint256","name":"stun","type":"uint256"},{"internalType":"uint256","name":"silence","type":"uint256"},{"internalType":"uint256","name":"freeze","type":"uint256"},{"internalType":"uint256","name":"strengthen","type":"uint256"},{"internalType":"uint256","name":"weaken","type":"uint256"},{"internalType":"uint256","name":"bulk","type":"uint256"},{"internalType":"uint256","name":"frail","type":"uint256"},{"internalType":"uint256","name":"thorns","type":"uint256"},{"internalType":"uint256","name":"regen","type":"uint256"},{"internalType":"uint256","name":"sleep","type":"uint256"},{"internalType":"uint256","name":"death","type":"uint256"},{"internalType":"uint256","name":"invincible","type":"uint256"},{"internalType":"uint256","name":"lastHope","type":"uint256"},{"internalType":"uint256","name":"dodge","type":"uint256"},{"internalType":"uint256","name":"healBlock","type":"uint256"},{"internalType":"uint256","name":"charm","type":"uint256"},{"internalType":"uint256","name":"counter","type":"uint256"},{"internalType":"uint256","name":"pierce","type":"uint256"},{"internalType":"uint256","name":"cleave","type":"uint256"},{"internalType":"uint256","name":"revive","type":"uint256"},{"internalType":"uint256","name":"unstoppable","type":"uint256"},{"internalType":"uint256","name":"petrify","type":"uint256"},{"internalType":"uint256","name":"fireResist","type":"uint256"},{"internalType":"uint256","name":"poisonResist","type":"uint256"},{"internalType":"uint256","name":"freezeResist","type":"uint256"},{"internalType":"uint256","name":"stunResist","type":"uint256"},{"internalType":"uint256","name":"sleepResist","type":"uint256"},{"internalType":"uint256","name":"charged","type":"uint256"},{"internalType":"uint256","name":"doubleUp","type":"uint256"},{"internalType":"uint256","name":"rampage","type":"uint256"},{"internalType":"uint256","name":"loneSurvivor","type":"uint256"},{"internalType":"uint256","name":"royalDecree","type":"uint256"},{"internalType":"uint256","name":"wrathfulReprisal","type":"uint256"}],"internalType":"struct MowseDungeonSimpleStatusEffect","name":"statusEffects","type":"tuple"},{"internalType":"string","name":"image","type":"string"}],"internalType":"struct MowseDungeonSimpleMonster","name":"","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"uint256","name":"maxHealth","type":"uint256"},{"internalType":"uint256","name":"shield","type":"uint256"},{"internalType":"uint256","name":"attack","type":"uint256"},{"internalType":"uint256","name":"coins","type":"uint256"}],"name":"updateMonsterDefault","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"enum MowseDungeonMonsterEnum","name":"monsterType","type":"uint8"},{"internalType":"string","name":"image","type":"string"}],"name":"updateMonsterDefaultImage","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506128f3806100206000396000f3fe608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636a6a12981161008c5780638c3458b4116100665780638c3458b414610254578063a667647814610267578063c694facb14610287578063f27dc8651461029a57600080fd5b80636a6a1298146101cb5780637b0b55d2146101e05780637ed541ab146101f357600080fd5b80634e308a15116100c85780634e308a15146101485780635580bfa114610168578063561ed0d81461018857806358f1fe23146101a857600080fd5b806319b2a5cd146100ef5780632b38d81a1461011557806346b12b4214610135575b600080fd5b6101026100fd366004611c20565b6102ad565b6040519081526020015b60405180910390f35b610128610123366004611c56565b610329565b60405161010c9190611e91565b610128610143366004611f66565b6106fa565b61015b610156366004611f7f565b610774565b60405161010c9190612031565b61017b610176366004611f66565b6108ad565b60405161010c9190612044565b61019b610196366004611f66565b610a48565b60405161010c91906120a6565b6101bb6101b63660046120b4565b610abc565b604051901515815260200161010c565b6101de6101d93660046120e0565b610b3c565b005b61015b6101ee366004611f66565b610cef565b610206610201366004611c20565b610e67565b60405161010c9190600060c0820190508251151582526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015292915050565b6101de610262366004612213565b610f07565b61027a61027536600461244f565b611001565b60405161010c9190612596565b610102610295366004611c20565b6112a3565b61027a6102a8366004611c56565b611300565b600082815260656020908152604080832084845290915281205481036102f55760405163bbb6110160e01b815260048101849052602481018390526044015b60405180910390fd5b600083815260656020908152604080832085845290915290205460555460565461032092919061179a565b90505b92915050565b6103316118c6565b605f600083601b81111561034757610347611c71565b601b81111561035857610358611c71565b8152602080820192909252604090810160002081516101808101909252805460ff80821615158452929391929184019161010090910416601b8111156103a0576103a0611c71565b601b8111156103b1576103b1611c71565b815260018201546020820152600282015460408201526003820154606082015260048201546080820152600582015460a09091019060ff1660178111156103fa576103fa611c71565b601781111561040b5761040b611c71565b815260200160068201604051806104e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f820154815260200160108201548152602001601182015481526020016012820154815260200160138201548152602001601482015481526020016015820154815260200160168201548152602001601782015481526020016018820154815260200160198201548152602001601a8201548152602001601b8201548152602001601c8201548152602001601d8201548152602001601e8201548152602001601f82015481526020016020820154815260200160218201548152602001602282015481526020016023820154815260200160248201548152602001602582015481526020016026820154815250508152602001602d820160009054906101000a900460ff16151515158152602001602e8201548152602001602f820180546105df90612698565b80601f016020809104026020016040519081016040528092919081815260200182805461060b90612698565b80156106585780601f1061062d57610100808354040283529160200191610658565b820191906000526020600020905b81548152906001019060200180831161063b57829003601f168201915b5050505050815260200160308201805461067190612698565b80601f016020809104026020016040519081016040528092919081815260200182805461069d90612698565b80156106ea5780601f106106bf576101008083540402835291602001916106ea565b820191906000526020600020905b8154815290600101906020018083116106cd57829003601f168201915b5050505050815250509050919050565b6107026118c6565b606054821061074d57604051630895c61960e01b8152602060048201526016602482015275135bdb9cdd195c88191bd95cc81b9bdd08195e1a5cdd60521b60448201526064016102ec565b605f600083601b81111561076357610763611c71565b601b81111561034757610347611c71565b61077c611a5a565b6061600083602281111561079257610792611c71565b60228111156107a3576107a3611c71565b8152602081019190915260409081016000208151606081019092528054829060ff1660228111156107d6576107d6611c71565b60228111156107e7576107e7611c71565b81528154602090910190610100900460ff16600581111561080a5761080a611c71565b600581111561081b5761081b611c71565b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156106ea57602002820191906000526020600020906000905b82829054906101000a900460ff16601b81111561087c5761087c611c71565b81526020600192830181810494850194909303909202910180841161085d5790505050505050815250509050919050565b6000818152605b6020908152604080832060598352818420600f82015485529092529091206003810154606092919060ff166108fc57604051638792457b60e01b815260040160405180910390fd5b80600101805480602002602001604051908101604052809291908181526020016000905b82821015610a3b576000848152602090206040805160608101909152600284029091018054829060ff16602281111561095b5761095b611c71565b602281111561096c5761096c611c71565b81528154602090910190610100900460ff16600581111561098f5761098f611c71565b60058111156109a0576109a0611c71565b815260200160018201805480602002602001604051908101604052809291908181526020018280548015610a2357602002820191906000526020600020906000905b82829054906101000a900460ff16601b811115610a0157610a01611c71565b8152602060019283018181049485019490930390920291018084116109e25790505b50505050508152505081526020019060010190610920565b5050505092505050919050565b6000818152605b6020908152604080832060598352818420600f82015485529092528220600381015460ff16610a82575060059392505050565b80600101816002015481548110610a9b57610a9b6126d2565b6000918252602090912060029091020154610100900460ff16949350505050565b60008381526065602090815260408083208584529091528120548103610aff5760405163bbb6110160e01b815260048101859052602481018490526044016102ec565b6000848152606560209081526040808320868452909152902054610b249083906117ec565b15610b3157506001610b35565b5060005b9392505050565b600054604051632acd144760e21b81523360048201526001600160a01b039091169063ab34511c90602401602060405180830381865afa158015610b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba891906126e8565b610bec5760405163718f3c1960e01b81526020600482015260146024820152734d75737420686176652041646d696e20526f6c6560601b60448201526064016102ec565b83605f600087601b811115610c0357610c03611c71565b601b811115610c1457610c14611c71565b815260200190815260200160002060020181905550826000605f01600087601b811115610c4357610c43611c71565b601b811115610c5457610c54611c71565b815260200190815260200160002060030181905550816000605f01600087601b811115610c8357610c83611c71565b601b811115610c9457610c94611c71565b815260200190815260200160002060040181905550806000605f01600087601b811115610cc357610cc3611c71565b601b811115610cd457610cd4611c71565b81526020810191909152604001600020602e01555050505050565b610cf7611a5a565b6000828152605b6020908152604080832060598352818420600f8201548552909252909120600381015460ff16610d4157604051638792457b60e01b815260040160405180910390fd5b80600101816002015481548110610d5a57610d5a6126d2565b6000918252602090912060408051606081019091526002909202018054829060ff166022811115610d8d57610d8d611c71565b6022811115610d9e57610d9e611c71565b81528154602090910190610100900460ff166005811115610dc157610dc1611c71565b6005811115610dd257610dd2611c71565b815260200160018201805480602002602001604051908101604052809291908181526020018280548015610e5557602002820191906000526020600020906000905b82829054906101000a900460ff16601b811115610e3357610e33611c71565b815260206001928301818104948501949093039092029101808411610e145790505b50505050508152505092505050919050565b610ea26040518060c0016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081525090565b506000918252605e6020908152604080842092845291815291819020815160c081018352815460ff161515815260018201549381019390935260028101549183019190915260038101546060830152600481015460808301526005015460a082015290565b600054604051632acd144760e21b81523360048201526001600160a01b039091169063ab34511c90602401602060405180830381865afa158015610f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7391906126e8565b610fb75760405163718f3c1960e01b81526020600482015260146024820152734d75737420686176652041646d696e20526f6c6560601b60448201526064016102ec565b80605f600084601b811115610fce57610fce611c71565b601b811115610fdf57610fdf611c71565b81526020019081526020016000206030019081610ffc9190612753565b505050565b611009611a7d565b81600003611018575081610323565b816001036110705760648360400151607d6110339190612829565b61103d9190612856565b604084018190526060840152608083015160649061105c90607d612829565b6110669190612856565b608084015261129c565b8160020361109f5760648360a00151607d61108b9190612829565b6110959190612856565b60a084015261129c565b816003036110ba5760648360a00151607d61108b9190612829565b816004036111345760648360a00151607d6110d59190612829565b6110df9190612856565b60a084015260808301516064906110f790607d612829565b6111019190612856565b6080840152604083015160649061111990607d612829565b6111239190612856565b60408401819052606084015261129c565b8160050361114f5760648360a00151607d6110d59190612829565b816006036111ae5760648360a00151607d61116a9190612829565b6111749190612856565b60a0840152608083015160649061118c906096612829565b6111969190612856565b60808401526040830151606490611119906096612829565b816007036111c95760648360a00151607d61116a9190612829565b816008036111e45760648360a00151607d61116a9190612829565b816009036112315760808301516111fc906002612829565b60808401526040830151611211906002612829565b6040840181905260608401526101c083015160016104609091015261129c565b81600a0361129c5760648360a00151607d61124c9190612829565b6112569190612856565b60a0840152608083015161126b906002612829565b60808401526040830151611280906002612829565b6040840181905260608401526101c08301516001610460909101525b5090919050565b60008281526059602090815260408083208484529091528120600381015460ff166112e15760405163067816a560e01b815260040160405180910390fd5b5050600091825260656020908152604080842092845291905290205490565b611308611a7d565b6000605f8184601b81111561131f5761131f611c71565b601b81111561133057611330611c71565b8152602080820192909252604090810160002081516101808101909252805460ff80821615158452929391929184019161010090910416601b81111561137857611378611c71565b601b81111561138957611389611c71565b815260018201546020820152600282015460408201526003820154606082015260048201546080820152600582015460a09091019060ff1660178111156113d2576113d2611c71565b60178111156113e3576113e3611c71565b815260200160068201604051806104e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f820154815260200160108201548152602001601182015481526020016012820154815260200160138201548152602001601482015481526020016015820154815260200160168201548152602001601782015481526020016018820154815260200160198201548152602001601a8201548152602001601b8201548152602001601c8201548152602001601d8201548152602001601e8201548152602001601f82015481526020016020820154815260200160218201548152602001602282015481526020016023820154815260200160248201548152602001602582015481526020016026820154815250508152602001602d820160009054906101000a900460ff16151515158152602001602e8201548152602001602f820180546115b790612698565b80601f01602080910402602001604051908101604052809291908181526020018280546115e390612698565b80156116305780601f1061160557610100808354040283529160200191611630565b820191906000526020600020905b81548152906001019060200180831161161357829003601f168201915b5050505050815260200160308201805461164990612698565b80601f016020809104026020016040519081016040528092919081815260200182805461167590612698565b80156116c25780601f10611697576101008083540402835291602001916116c2565b820191906000526020600020905b8154815290600101906020018083116116a557829003601f168201915b50505050508152505090506040518061020001604052808260200151601b8111156116ef576116ef611c71565b8152602001826040015181526020018260600151815260200182606001518152602001826080015181526020018260a001518152602001600015158152602001606481526020018260a001518152602001606481526020018260c00151601781111561175d5761175d611c71565b815261010083015115156020820152600060408201819052606082015260e083015160808201526101609092015160a09092019190915292915050565b60008060026117aa85600161286a565b901c90506117b8848661287d565b945060005b838110156117e2576117d0868387611804565b95506117db81612891565b90506117bd565b5093949350505050565b60006103208383600060550154600060560154611857565b60006001845b841561184e578460011660010361182f57838061182957611829612840565b81830991505b838061183d5761183d612840565b8182099050600185901c945061180a565b50949350505050565b6000805b8281101561188657838061187157611871612840565b868709955061187f81612891565b905061185b565b50611891838561287d565b93508484036118a2575060016118be565b846118ad85856128aa565b036118ba575060016118be565b5060005b949350505050565b604080516101808101909152600080825260208201908152602001600081526020016000815260200160008152602001600081526020016000601781111561191057611910611c71565b8152602001611a36604051806104e001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b81526020016000151581526020016000815260200160608152602001606081525090565b6040805160608101909152806000815260200160005b8152602001606081525090565b6040805161020081019091528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160008152602001600081526020016000815260200160006017811115611ae557611ae5611c71565b8152600060208201819052604082018190526060820152608001611a70604051806104e001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60008060408385031215611c3357600080fd5b50508035926020909101359150565b8035601c8110611c5157600080fd5b919050565b600060208284031215611c6857600080fd5b61032082611c42565b634e487b7160e01b600052602160045260246000fd5b601c8110611c9757611c97611c71565b9052565b60188110611c9757611c97611c71565b805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a0808201519083015260c0808201519083015260e08082015190830152610100808201519083015261012080820151908301526101408082015190830152610160808201519083015261018080820151908301526101a080820151908301526101c080820151908301526101e08082015190830152610200808201519083015261022080820151908301526102408082015190830152610260808201519083015261028080820151908301526102a080820151908301526102c080820151908301526102e08082015190830152610300808201519083015261032080820151908301526103408082015190830152610360808201519083015261038080820151908301526103a080820151908301526103c080820151908301526103e08082015190830152610400808201519083015261042080820151908301526104408082015190830152610460808201519083015261048080820151908301526104a080820151908301526104c090810151910152565b6000815180845260005b81811015611e7157602081850181015186830182015201611e55565b506000602082860101526020601f19601f83011685010191505092915050565b60208152611ea460208201835115159052565b60006020830151611eb86040840182611c87565b506040830151606083015260608301516080830152608083015160a083015260a083015160c083015260c0830151611ef360e0840182611c9b565b5060e0830151610100611f0881850183611cab565b84015115156105e0840152506101208301516106008301526101408301516106406106208401819052611f3f610660850183611e4b565b9150610160850151601f198584030182860152611f5c8382611e4b565b9695505050505050565b600060208284031215611f7857600080fd5b5035919050565b600060208284031215611f9157600080fd5b813560238110610b3557600080fd5b60068110611c9757611c97611c71565b600060608301825160238110611fc857611fc8611c71565b8452602083810151611fdc82870182611fa0565b506040840151606060408701528281518085526080880191508383019450600092505b8083101561202657612012828651611c87565b938301936001929092019190830190611fff565b509695505050505050565b6020815260006103206020830184611fb0565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561209957603f19888603018452612087858351611fb0565b9450928501929085019060010161206b565b5092979650505050505050565b602081016103238284611fa0565b6000806000606084860312156120c957600080fd5b505081359360208301359350604090920135919050565b600080600080600060a086880312156120f857600080fd5b61210186611c42565b97602087013597506040870135966060810135965060800135945092505050565b634e487b7160e01b600052604160045260246000fd5b6040516104e0810167ffffffffffffffff8111828210171561215c5761215c612122565b60405290565b604051610200810167ffffffffffffffff8111828210171561215c5761215c612122565b600082601f83011261219757600080fd5b813567ffffffffffffffff808211156121b2576121b2612122565b604051601f8301601f19908116603f011681019082821181831017156121da576121da612122565b816040528381528660208588010111156121f357600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561222657600080fd5b61222f83611c42565b9150602083013567ffffffffffffffff81111561224b57600080fd5b61225785828601612186565b9150509250929050565b801515811461226f57600080fd5b50565b8035611c5181612261565b803560188110611c5157600080fd5b60006104e0828403121561229f57600080fd5b6122a7612138565b823581526020808401359082015260408084013590820152606080840135908201526080808401359082015260a0808401359082015260c0808401359082015260e08084013590820152610100808401359082015261012080840135908201526101408084013590820152610160808401359082015261018080840135908201526101a080840135908201526101c080840135908201526101e08084013590820152610200808401359082015261022080840135908201526102408084013590820152610260808401359082015261028080840135908201526102a080840135908201526102c080840135908201526102e08084013590820152610300808401359082015261032080840135908201526103408084013590820152610360808401359082015261038080840135908201526103a080840135908201526103c080840135908201526103e08084013590820152610400808401359082015261042080840135908201526104408084013590820152610460808401359082015261048080840135908201526104a080840135908201526104c0928301359281019290925250919050565b6000806040838503121561246257600080fd5b823567ffffffffffffffff8082111561247a57600080fd5b908401906106c0828703121561248f57600080fd5b612497612162565b6124a083611c42565b81526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a08201526124e060c08401612272565b60c082015260e083810135908201526101008084013590820152610120808401359082015261014061251381850161227d565b90820152610160612525848201612272565b90820152610180612537848201612272565b908201526101a0612549848201612272565b908201526101c061255c8885830161228c565b908201526106a08301358281111561257357600080fd5b61257f88828601612186565b6101e0830152509660209590950135955050505050565b602081526125a8602082018351611c87565b602082015160408201526040820151606082015260608201516080820152608082015160a082015260a082015160c0820152600060c08301516125ef60e084018215159052565b5060e083015161010083810191909152830151610120808401919091528301516101408084019190915283015161016061262b81850183611c9b565b84015190506101806126408482018315159052565b84015190506101a06126558482018315159052565b84015190506101c061266a8482018315159052565b84015190506101e061267e84820183611cab565b8401516106c08481015290506118be6106e0840182611e4b565b600181811c908216806126ac57607f821691505b6020821081036126cc57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156126fa57600080fd5b8151610b3581612261565b601f821115610ffc57600081815260208120601f850160051c8101602086101561272c5750805b601f850160051c820191505b8181101561274b57828155600101612738565b505050505050565b815167ffffffffffffffff81111561276d5761276d612122565b6127818161277b8454612698565b84612705565b602080601f8311600181146127b6576000841561279e5750858301515b600019600386901b1c1916600185901b17855561274b565b600085815260208120601f198616915b828110156127e5578886015182559484019460019091019084016127c6565b50858210156128035787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761032357610323612813565b634e487b7160e01b600052601260045260246000fd5b60008261286557612865612840565b500490565b8082018082111561032357610323612813565b60008261288c5761288c612840565b500690565b6000600182016128a3576128a3612813565b5060010190565b818103818111156103235761032361281356fea264697066735822122099e8986e471ab29d6051eef305692bd8ccf7bc172b6a5aba9f12bed94f1caae064736f6c63430008130033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100ea5760003560e01c80636a6a12981161008c5780638c3458b4116100665780638c3458b414610254578063a667647814610267578063c694facb14610287578063f27dc8651461029a57600080fd5b80636a6a1298146101cb5780637b0b55d2146101e05780637ed541ab146101f357600080fd5b80634e308a15116100c85780634e308a15146101485780635580bfa114610168578063561ed0d81461018857806358f1fe23146101a857600080fd5b806319b2a5cd146100ef5780632b38d81a1461011557806346b12b4214610135575b600080fd5b6101026100fd366004611c20565b6102ad565b6040519081526020015b60405180910390f35b610128610123366004611c56565b610329565b60405161010c9190611e91565b610128610143366004611f66565b6106fa565b61015b610156366004611f7f565b610774565b60405161010c9190612031565b61017b610176366004611f66565b6108ad565b60405161010c9190612044565b61019b610196366004611f66565b610a48565b60405161010c91906120a6565b6101bb6101b63660046120b4565b610abc565b604051901515815260200161010c565b6101de6101d93660046120e0565b610b3c565b005b61015b6101ee366004611f66565b610cef565b610206610201366004611c20565b610e67565b60405161010c9190600060c0820190508251151582526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015292915050565b6101de610262366004612213565b610f07565b61027a61027536600461244f565b611001565b60405161010c9190612596565b610102610295366004611c20565b6112a3565b61027a6102a8366004611c56565b611300565b600082815260656020908152604080832084845290915281205481036102f55760405163bbb6110160e01b815260048101849052602481018390526044015b60405180910390fd5b600083815260656020908152604080832085845290915290205460555460565461032092919061179a565b90505b92915050565b6103316118c6565b605f600083601b81111561034757610347611c71565b601b81111561035857610358611c71565b8152602080820192909252604090810160002081516101808101909252805460ff80821615158452929391929184019161010090910416601b8111156103a0576103a0611c71565b601b8111156103b1576103b1611c71565b815260018201546020820152600282015460408201526003820154606082015260048201546080820152600582015460a09091019060ff1660178111156103fa576103fa611c71565b601781111561040b5761040b611c71565b815260200160068201604051806104e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f820154815260200160108201548152602001601182015481526020016012820154815260200160138201548152602001601482015481526020016015820154815260200160168201548152602001601782015481526020016018820154815260200160198201548152602001601a8201548152602001601b8201548152602001601c8201548152602001601d8201548152602001601e8201548152602001601f82015481526020016020820154815260200160218201548152602001602282015481526020016023820154815260200160248201548152602001602582015481526020016026820154815250508152602001602d820160009054906101000a900460ff16151515158152602001602e8201548152602001602f820180546105df90612698565b80601f016020809104026020016040519081016040528092919081815260200182805461060b90612698565b80156106585780601f1061062d57610100808354040283529160200191610658565b820191906000526020600020905b81548152906001019060200180831161063b57829003601f168201915b5050505050815260200160308201805461067190612698565b80601f016020809104026020016040519081016040528092919081815260200182805461069d90612698565b80156106ea5780601f106106bf576101008083540402835291602001916106ea565b820191906000526020600020905b8154815290600101906020018083116106cd57829003601f168201915b5050505050815250509050919050565b6107026118c6565b606054821061074d57604051630895c61960e01b8152602060048201526016602482015275135bdb9cdd195c88191bd95cc81b9bdd08195e1a5cdd60521b60448201526064016102ec565b605f600083601b81111561076357610763611c71565b601b81111561034757610347611c71565b61077c611a5a565b6061600083602281111561079257610792611c71565b60228111156107a3576107a3611c71565b8152602081019190915260409081016000208151606081019092528054829060ff1660228111156107d6576107d6611c71565b60228111156107e7576107e7611c71565b81528154602090910190610100900460ff16600581111561080a5761080a611c71565b600581111561081b5761081b611c71565b8152602001600182018054806020026020016040519081016040528092919081815260200182805480156106ea57602002820191906000526020600020906000905b82829054906101000a900460ff16601b81111561087c5761087c611c71565b81526020600192830181810494850194909303909202910180841161085d5790505050505050815250509050919050565b6000818152605b6020908152604080832060598352818420600f82015485529092529091206003810154606092919060ff166108fc57604051638792457b60e01b815260040160405180910390fd5b80600101805480602002602001604051908101604052809291908181526020016000905b82821015610a3b576000848152602090206040805160608101909152600284029091018054829060ff16602281111561095b5761095b611c71565b602281111561096c5761096c611c71565b81528154602090910190610100900460ff16600581111561098f5761098f611c71565b60058111156109a0576109a0611c71565b815260200160018201805480602002602001604051908101604052809291908181526020018280548015610a2357602002820191906000526020600020906000905b82829054906101000a900460ff16601b811115610a0157610a01611c71565b8152602060019283018181049485019490930390920291018084116109e25790505b50505050508152505081526020019060010190610920565b5050505092505050919050565b6000818152605b6020908152604080832060598352818420600f82015485529092528220600381015460ff16610a82575060059392505050565b80600101816002015481548110610a9b57610a9b6126d2565b6000918252602090912060029091020154610100900460ff16949350505050565b60008381526065602090815260408083208584529091528120548103610aff5760405163bbb6110160e01b815260048101859052602481018490526044016102ec565b6000848152606560209081526040808320868452909152902054610b249083906117ec565b15610b3157506001610b35565b5060005b9392505050565b600054604051632acd144760e21b81523360048201526001600160a01b039091169063ab34511c90602401602060405180830381865afa158015610b84573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ba891906126e8565b610bec5760405163718f3c1960e01b81526020600482015260146024820152734d75737420686176652041646d696e20526f6c6560601b60448201526064016102ec565b83605f600087601b811115610c0357610c03611c71565b601b811115610c1457610c14611c71565b815260200190815260200160002060020181905550826000605f01600087601b811115610c4357610c43611c71565b601b811115610c5457610c54611c71565b815260200190815260200160002060030181905550816000605f01600087601b811115610c8357610c83611c71565b601b811115610c9457610c94611c71565b815260200190815260200160002060040181905550806000605f01600087601b811115610cc357610cc3611c71565b601b811115610cd457610cd4611c71565b81526020810191909152604001600020602e01555050505050565b610cf7611a5a565b6000828152605b6020908152604080832060598352818420600f8201548552909252909120600381015460ff16610d4157604051638792457b60e01b815260040160405180910390fd5b80600101816002015481548110610d5a57610d5a6126d2565b6000918252602090912060408051606081019091526002909202018054829060ff166022811115610d8d57610d8d611c71565b6022811115610d9e57610d9e611c71565b81528154602090910190610100900460ff166005811115610dc157610dc1611c71565b6005811115610dd257610dd2611c71565b815260200160018201805480602002602001604051908101604052809291908181526020018280548015610e5557602002820191906000526020600020906000905b82829054906101000a900460ff16601b811115610e3357610e33611c71565b815260206001928301818104948501949093039092029101808411610e145790505b50505050508152505092505050919050565b610ea26040518060c0016040528060001515815260200160008152602001600081526020016000815260200160008152602001600081525090565b506000918252605e6020908152604080842092845291815291819020815160c081018352815460ff161515815260018201549381019390935260028101549183019190915260038101546060830152600481015460808301526005015460a082015290565b600054604051632acd144760e21b81523360048201526001600160a01b039091169063ab34511c90602401602060405180830381865afa158015610f4f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f7391906126e8565b610fb75760405163718f3c1960e01b81526020600482015260146024820152734d75737420686176652041646d696e20526f6c6560601b60448201526064016102ec565b80605f600084601b811115610fce57610fce611c71565b601b811115610fdf57610fdf611c71565b81526020019081526020016000206030019081610ffc9190612753565b505050565b611009611a7d565b81600003611018575081610323565b816001036110705760648360400151607d6110339190612829565b61103d9190612856565b604084018190526060840152608083015160649061105c90607d612829565b6110669190612856565b608084015261129c565b8160020361109f5760648360a00151607d61108b9190612829565b6110959190612856565b60a084015261129c565b816003036110ba5760648360a00151607d61108b9190612829565b816004036111345760648360a00151607d6110d59190612829565b6110df9190612856565b60a084015260808301516064906110f790607d612829565b6111019190612856565b6080840152604083015160649061111990607d612829565b6111239190612856565b60408401819052606084015261129c565b8160050361114f5760648360a00151607d6110d59190612829565b816006036111ae5760648360a00151607d61116a9190612829565b6111749190612856565b60a0840152608083015160649061118c906096612829565b6111969190612856565b60808401526040830151606490611119906096612829565b816007036111c95760648360a00151607d61116a9190612829565b816008036111e45760648360a00151607d61116a9190612829565b816009036112315760808301516111fc906002612829565b60808401526040830151611211906002612829565b6040840181905260608401526101c083015160016104609091015261129c565b81600a0361129c5760648360a00151607d61124c9190612829565b6112569190612856565b60a0840152608083015161126b906002612829565b60808401526040830151611280906002612829565b6040840181905260608401526101c08301516001610460909101525b5090919050565b60008281526059602090815260408083208484529091528120600381015460ff166112e15760405163067816a560e01b815260040160405180910390fd5b5050600091825260656020908152604080842092845291905290205490565b611308611a7d565b6000605f8184601b81111561131f5761131f611c71565b601b81111561133057611330611c71565b8152602080820192909252604090810160002081516101808101909252805460ff80821615158452929391929184019161010090910416601b81111561137857611378611c71565b601b81111561138957611389611c71565b815260018201546020820152600282015460408201526003820154606082015260048201546080820152600582015460a09091019060ff1660178111156113d2576113d2611c71565b60178111156113e3576113e3611c71565b815260200160068201604051806104e001604052908160008201548152602001600182015481526020016002820154815260200160038201548152602001600482015481526020016005820154815260200160068201548152602001600782015481526020016008820154815260200160098201548152602001600a8201548152602001600b8201548152602001600c8201548152602001600d8201548152602001600e8201548152602001600f820154815260200160108201548152602001601182015481526020016012820154815260200160138201548152602001601482015481526020016015820154815260200160168201548152602001601782015481526020016018820154815260200160198201548152602001601a8201548152602001601b8201548152602001601c8201548152602001601d8201548152602001601e8201548152602001601f82015481526020016020820154815260200160218201548152602001602282015481526020016023820154815260200160248201548152602001602582015481526020016026820154815250508152602001602d820160009054906101000a900460ff16151515158152602001602e8201548152602001602f820180546115b790612698565b80601f01602080910402602001604051908101604052809291908181526020018280546115e390612698565b80156116305780601f1061160557610100808354040283529160200191611630565b820191906000526020600020905b81548152906001019060200180831161161357829003601f168201915b5050505050815260200160308201805461164990612698565b80601f016020809104026020016040519081016040528092919081815260200182805461167590612698565b80156116c25780601f10611697576101008083540402835291602001916116c2565b820191906000526020600020905b8154815290600101906020018083116116a557829003601f168201915b50505050508152505090506040518061020001604052808260200151601b8111156116ef576116ef611c71565b8152602001826040015181526020018260600151815260200182606001518152602001826080015181526020018260a001518152602001600015158152602001606481526020018260a001518152602001606481526020018260c00151601781111561175d5761175d611c71565b815261010083015115156020820152600060408201819052606082015260e083015160808201526101609092015160a09092019190915292915050565b60008060026117aa85600161286a565b901c90506117b8848661287d565b945060005b838110156117e2576117d0868387611804565b95506117db81612891565b90506117bd565b5093949350505050565b60006103208383600060550154600060560154611857565b60006001845b841561184e578460011660010361182f57838061182957611829612840565b81830991505b838061183d5761183d612840565b8182099050600185901c945061180a565b50949350505050565b6000805b8281101561188657838061187157611871612840565b868709955061187f81612891565b905061185b565b50611891838561287d565b93508484036118a2575060016118be565b846118ad85856128aa565b036118ba575060016118be565b5060005b949350505050565b604080516101808101909152600080825260208201908152602001600081526020016000815260200160008152602001600081526020016000601781111561191057611910611c71565b8152602001611a36604051806104e001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b81526020016000151581526020016000815260200160608152602001606081525090565b6040805160608101909152806000815260200160005b8152602001606081525090565b6040805161020081019091528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160001515815260200160008152602001600081526020016000815260200160006017811115611ae557611ae5611c71565b8152600060208201819052604082018190526060820152608001611a70604051806104e001604052806000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60008060408385031215611c3357600080fd5b50508035926020909101359150565b8035601c8110611c5157600080fd5b919050565b600060208284031215611c6857600080fd5b61032082611c42565b634e487b7160e01b600052602160045260246000fd5b601c8110611c9757611c97611c71565b9052565b60188110611c9757611c97611c71565b805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a0808201519083015260c0808201519083015260e08082015190830152610100808201519083015261012080820151908301526101408082015190830152610160808201519083015261018080820151908301526101a080820151908301526101c080820151908301526101e08082015190830152610200808201519083015261022080820151908301526102408082015190830152610260808201519083015261028080820151908301526102a080820151908301526102c080820151908301526102e08082015190830152610300808201519083015261032080820151908301526103408082015190830152610360808201519083015261038080820151908301526103a080820151908301526103c080820151908301526103e08082015190830152610400808201519083015261042080820151908301526104408082015190830152610460808201519083015261048080820151908301526104a080820151908301526104c090810151910152565b6000815180845260005b81811015611e7157602081850181015186830182015201611e55565b506000602082860101526020601f19601f83011685010191505092915050565b60208152611ea460208201835115159052565b60006020830151611eb86040840182611c87565b506040830151606083015260608301516080830152608083015160a083015260a083015160c083015260c0830151611ef360e0840182611c9b565b5060e0830151610100611f0881850183611cab565b84015115156105e0840152506101208301516106008301526101408301516106406106208401819052611f3f610660850183611e4b565b9150610160850151601f198584030182860152611f5c8382611e4b565b9695505050505050565b600060208284031215611f7857600080fd5b5035919050565b600060208284031215611f9157600080fd5b813560238110610b3557600080fd5b60068110611c9757611c97611c71565b600060608301825160238110611fc857611fc8611c71565b8452602083810151611fdc82870182611fa0565b506040840151606060408701528281518085526080880191508383019450600092505b8083101561202657612012828651611c87565b938301936001929092019190830190611fff565b509695505050505050565b6020815260006103206020830184611fb0565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b8281101561209957603f19888603018452612087858351611fb0565b9450928501929085019060010161206b565b5092979650505050505050565b602081016103238284611fa0565b6000806000606084860312156120c957600080fd5b505081359360208301359350604090920135919050565b600080600080600060a086880312156120f857600080fd5b61210186611c42565b97602087013597506040870135966060810135965060800135945092505050565b634e487b7160e01b600052604160045260246000fd5b6040516104e0810167ffffffffffffffff8111828210171561215c5761215c612122565b60405290565b604051610200810167ffffffffffffffff8111828210171561215c5761215c612122565b600082601f83011261219757600080fd5b813567ffffffffffffffff808211156121b2576121b2612122565b604051601f8301601f19908116603f011681019082821181831017156121da576121da612122565b816040528381528660208588010111156121f357600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806040838503121561222657600080fd5b61222f83611c42565b9150602083013567ffffffffffffffff81111561224b57600080fd5b61225785828601612186565b9150509250929050565b801515811461226f57600080fd5b50565b8035611c5181612261565b803560188110611c5157600080fd5b60006104e0828403121561229f57600080fd5b6122a7612138565b823581526020808401359082015260408084013590820152606080840135908201526080808401359082015260a0808401359082015260c0808401359082015260e08084013590820152610100808401359082015261012080840135908201526101408084013590820152610160808401359082015261018080840135908201526101a080840135908201526101c080840135908201526101e08084013590820152610200808401359082015261022080840135908201526102408084013590820152610260808401359082015261028080840135908201526102a080840135908201526102c080840135908201526102e08084013590820152610300808401359082015261032080840135908201526103408084013590820152610360808401359082015261038080840135908201526103a080840135908201526103c080840135908201526103e08084013590820152610400808401359082015261042080840135908201526104408084013590820152610460808401359082015261048080840135908201526104a080840135908201526104c0928301359281019290925250919050565b6000806040838503121561246257600080fd5b823567ffffffffffffffff8082111561247a57600080fd5b908401906106c0828703121561248f57600080fd5b612497612162565b6124a083611c42565b81526020830135602082015260408301356040820152606083013560608201526080830135608082015260a083013560a08201526124e060c08401612272565b60c082015260e083810135908201526101008084013590820152610120808401359082015261014061251381850161227d565b90820152610160612525848201612272565b90820152610180612537848201612272565b908201526101a0612549848201612272565b908201526101c061255c8885830161228c565b908201526106a08301358281111561257357600080fd5b61257f88828601612186565b6101e0830152509660209590950135955050505050565b602081526125a8602082018351611c87565b602082015160408201526040820151606082015260608201516080820152608082015160a082015260a082015160c0820152600060c08301516125ef60e084018215159052565b5060e083015161010083810191909152830151610120808401919091528301516101408084019190915283015161016061262b81850183611c9b565b84015190506101806126408482018315159052565b84015190506101a06126558482018315159052565b84015190506101c061266a8482018315159052565b84015190506101e061267e84820183611cab565b8401516106c08481015290506118be6106e0840182611e4b565b600181811c908216806126ac57607f821691505b6020821081036126cc57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b6000602082840312156126fa57600080fd5b8151610b3581612261565b601f821115610ffc57600081815260208120601f850160051c8101602086101561272c5750805b601f850160051c820191505b8181101561274b57828155600101612738565b505050505050565b815167ffffffffffffffff81111561276d5761276d612122565b6127818161277b8454612698565b84612705565b602080601f8311600181146127b6576000841561279e5750858301515b600019600386901b1c1916600185901b17855561274b565b600085815260208120601f198616915b828110156127e5578886015182559484019460019091019084016127c6565b50858210156128035787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b808202811582820484141761032357610323612813565b634e487b7160e01b600052601260045260246000fd5b60008261286557612865612840565b500490565b8082018082111561032357610323612813565b60008261288c5761288c612840565b500690565b6000600182016128a3576128a3612813565b5060010190565b818103818111156103235761032361281356fea264697066735822122099e8986e471ab29d6051eef305692bd8ccf7bc172b6a5aba9f12bed94f1caae064736f6c63430008130033
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.