Contract Overview
Balance:
0 FTM
FTM Value:
$0.00
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0xc25224c2929c646960e35e4e4be766391fdcb781e208e39df66d0d23f2d74ac3 | 0x60a08060 | 63079144 | 8 days 12 hrs ago | PaintSwap Finance: Deployer | IN | Create: ItemNFT | 0 FTM | 0.44883171 |
[ Download CSV Export ]
Latest 1 internal transaction
Parent Txn Hash | Block | From | To | Value | |||
---|---|---|---|---|---|---|---|
0xc25224c2929c646960e35e4e4be766391fdcb781e208e39df66d0d23f2d74ac3 | 63079144 | 8 days 12 hrs ago | PaintSwap Finance: Deployer | Contract Creation | 0 FTM |
[ Download CSV Export ]
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Source Code Verified (Exact Match)
Contract Name:
ItemNFT
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 9999999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {UnsafeMath} from '../UnsafeMath.sol'; using UnsafeMath for int256; type I256 is int256; using { add as +, sub as -, mul as *, div as /, mod as %, neq as !=, eq as ==, lt as <, lte as <=, gt as >, gte as >=, and as &, or as |, xor as ^, not as ~ } for I256 global; function add(I256 _i256, I256 _addend) pure returns (I256) { return I256.wrap(I256.unwrap(_i256).add(I256.unwrap(_addend))); } function sub(I256 _i256, I256 _subtrahend) pure returns (I256) { return I256.wrap(I256.unwrap(_i256).sub(I256.unwrap(_subtrahend))); } function mul(I256 _i256, I256 _multiplier) pure returns (I256) { return I256.wrap(I256.unwrap(_i256).mul(I256.unwrap(_multiplier))); } function div(I256 _i256, I256 _divisor) pure returns (I256) { return I256.wrap(I256.unwrap(_i256).div(I256.unwrap(_divisor))); } function mod(I256 _i256, I256 _divisor) pure returns (I256) { return I256.wrap(I256.unwrap(_i256).mod(I256.unwrap(_divisor))); } function and(I256 _i256, I256 _mask) pure returns (I256) { return I256.wrap(I256.unwrap(_i256) & I256.unwrap(_mask)); } function or(I256 _i256, I256 _mask) pure returns (I256) { return I256.wrap(I256.unwrap(_i256) | I256.unwrap(_mask)); } function xor(I256 _i256, I256 _mask) pure returns (I256) { return I256.wrap(I256.unwrap(_i256) ^ I256.unwrap(_mask)); } function not(I256 _i256) pure returns (I256) { return I256.wrap(~I256.unwrap(_i256)); } function neq(I256 _i256, I256 _bounds) pure returns (bool) { return I256.unwrap(_i256) != I256.unwrap(_bounds); } function eq(I256 _i256, I256 _bounds) pure returns (bool) { return I256.unwrap(_i256) == I256.unwrap(_bounds); } function lt(I256 _i256, I256 _bounds) pure returns (bool) { return I256.unwrap(_i256) < I256.unwrap(_bounds); } function lte(I256 _i256, I256 _bounds) pure returns (bool) { return I256.unwrap(_i256) <= I256.unwrap(_bounds); } function gt(I256 _i256, I256 _bounds) pure returns (bool) { return I256.unwrap(_i256) > I256.unwrap(_bounds); } function gte(I256 _i256, I256 _bounds) pure returns (bool) { return I256.unwrap(_i256) >= I256.unwrap(_bounds); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import {UnsafeMath} from '../UnsafeMath.sol'; using UnsafeMath for uint256; type U256 is uint256; using { add as +, sub as -, mul as *, div as /, mod as %, neq as !=, eq as ==, lt as <, lte as <=, gt as >, gte as >=, and as &, or as |, xor as ^, not as ~ } for U256 global; function add(U256 _u256, U256 _addend) pure returns (U256) { return U256.wrap(U256.unwrap(_u256).add(U256.unwrap(_addend))); } function sub(U256 _u256, U256 _subtrahend) pure returns (U256) { return U256.wrap(U256.unwrap(_u256).sub(U256.unwrap(_subtrahend))); } function mul(U256 _u256, U256 _multiplier) pure returns (U256) { return U256.wrap(U256.unwrap(_u256).mul(U256.unwrap(_multiplier))); } function div(U256 _u256, U256 _divisor) pure returns (U256) { return U256.wrap(U256.unwrap(_u256).div(U256.unwrap(_divisor))); } function mod(U256 _u256, U256 _divisor) pure returns (U256) { return U256.wrap(U256.unwrap(_u256).mod(U256.unwrap(_divisor))); } function and(U256 _u256, U256 _mask) pure returns (U256) { return U256.wrap(U256.unwrap(_u256) & U256.unwrap(_mask)); } function or(U256 _u256, U256 _mask) pure returns (U256) { return U256.wrap(U256.unwrap(_u256) | U256.unwrap(_mask)); } function xor(U256 _u256, U256 _mask) pure returns (U256) { return U256.wrap(U256.unwrap(_u256) ^ U256.unwrap(_mask)); } function not(U256 _u256) pure returns (U256) { return U256.wrap(~U256.unwrap(_u256)); } function neq(U256 _u256, U256 _bounds) pure returns (bool) { return U256.unwrap(_u256) != U256.unwrap(_bounds); } function eq(U256 _u256, U256 _bounds) pure returns (bool) { return U256.unwrap(_u256) == U256.unwrap(_bounds); } function lt(U256 _u256, U256 _bounds) pure returns (bool) { return U256.unwrap(_u256) < U256.unwrap(_bounds); } function lte(U256 _u256, U256 _bounds) pure returns (bool) { return U256.unwrap(_u256) <= U256.unwrap(_bounds); } function gt(U256 _u256, U256 _bounds) pure returns (bool) { return U256.unwrap(_u256) > U256.unwrap(_bounds); } function gte(U256 _u256, U256 _bounds) pure returns (bool) { return U256.unwrap(_u256) >= U256.unwrap(_bounds); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; // solhint-disable func-name-mixedcase import {I256} from './types/I256.sol'; import {U256} from './types/U256.sol'; library UnsafeMath { /********************* * uint256 -> *********************/ /// @dev Returns the addition of two unsigned integers /// @param _uint256 The first unsigned integer /// @param _addend The second unsigned integer /// @return The addition of the two unsigned integers function add(uint256 _uint256, uint256 _addend) internal pure returns (uint256) { unchecked { return _uint256 + _addend; } } /// @dev Returns the subtraction of two unsigned integers /// @param _uint256 The first unsigned integer /// @param _subtrahend The second unsigned integer /// @return The subtraction of the two unsigned integers function sub(uint256 _uint256, uint256 _subtrahend) internal pure returns (uint256) { unchecked { return _uint256 - _subtrahend; } } /// @dev Increments an unsigned integer by one /// @param _uint256 The unsigned integer /// @return The incremented unsigned integer function inc(uint256 _uint256) internal pure returns (uint256) { unchecked { return ++_uint256; } } /// @dev Decrements an unsigned integer by one /// @param _uint256 The unsigned integer /// @return The decremented unsigned integer function dec(uint256 _uint256) internal pure returns (uint256) { unchecked { return --_uint256; } } /// @dev Returns the multiplication of two unsigned integers /// @param _uint256 The first unsigned integer /// @param _multiplier The second unsigned integer /// @return The multiplication of the two unsigned integers function mul(uint256 _uint256, uint256 _multiplier) internal pure returns (uint256) { unchecked { return _uint256 * _multiplier; } } /// @dev Returns the exponentiation of two unsigned integers /// @param _uint256 The first unsigned integer /// @param _exponent The second unsigned integer /// @return The exponentiation of the two unsigned integers function exp(uint256 _uint256, uint256 _exponent) internal pure returns (uint256) { uint256 result; // solhint-disable-next-line no-inline-assembly assembly { result := exp(_uint256, _exponent) } return result; } /// @dev Returns the division of two unsigned integers /// @param _uint256 The first unsigned integer /// @param _divisor The second unsigned integer /// @return The division of the two unsigned integers function div(uint256 _uint256, uint256 _divisor) internal pure returns (uint256) { uint256 result; // solhint-disable-next-line no-inline-assembly assembly { result := div(_uint256, _divisor) } return result; } /// @dev Returns the remainder of the division of two unsigned integers /// @param _uint256 The first unsigned integer /// @param _divisor The second unsigned integer /// @return The remainder of the division of the two unsigned integers function mod(uint256 _uint256, uint256 _divisor) internal pure returns (uint256) { uint256 result; // solhint-disable-next-line no-inline-assembly assembly { result := mod(_uint256, _divisor) } return result; } /********************* * int256 -> *********************/ /// @dev Returns the addition of two signed integers /// @param _int256 The first signed integer /// @param _addend The second signed integer /// @return The addition of the two signed integers function add(int256 _int256, int256 _addend) internal pure returns (int256) { unchecked { return _int256 + _addend; } } /// @dev Returns the subtraction of two signed integers /// @param _int256 The first signed integer /// @param _subtrahend The second signed integer /// @return The subtraction of the two signed integers function sub(int256 _int256, int256 _subtrahend) internal pure returns (int256) { unchecked { return _int256 - _subtrahend; } } /// @dev Increments a signed integer by one /// @param _int256 The signed integer /// @return The incremented signed integer function inc(int256 _int256) internal pure returns (int256) { unchecked { return ++_int256; } } /// @dev Decrements a signed integer by one /// @param _int256 The signed integer /// @return The decremented signed integer function dec(int256 _int256) internal pure returns (int256) { unchecked { return --_int256; } } /// @dev Returns the multiplication of two signed integers /// @param _int256 The first signed integer /// @param _multiplier The second signed integer /// @return The multiplication of the two signed integers function mul(int256 _int256, int256 _multiplier) internal pure returns (int256) { unchecked { return _int256 * _multiplier; } } /// @dev Returns the division of two signed integers /// @param _int256 The first signed integer /// @param _divisor The second signed integer /// @return The division of the two signed integers function div(int256 _int256, int256 _divisor) internal pure returns (int256) { int256 result; // solhint-disable-next-line no-inline-assembly assembly { result := sdiv(_int256, _divisor) } return result; } /// @dev Returns the remainder of the division of two signed integers /// @param _int256 The first signed integer /// @param _divisor The second signed integer /// @return The remainder of the division of the two signed integers function mod(int256 _int256, int256 _divisor) internal pure returns (int256) { int256 result; // solhint-disable-next-line no-inline-assembly assembly { result := smod(_int256, _divisor) } return result; } /********************* * I256 -> *********************/ /// @dev Wraps an int256 into an I256 /// @param _i256 The int256 to wrap /// @return i256 The wrapped I256 function asI256(int256 _i256) internal pure returns (I256 i256) { return I256.wrap(_i256); } /// @dev Wraps a uint256 into an I256 /// @param _i256 The uint256 to wrap /// @return i256 The wrapped I256 function asI256(uint256 _i256) internal pure returns (I256 i256) { return I256.wrap(int256(_i256)); } /// @dev Converts an I256 to a signed int256 /// @param _i256 The I256 to convert /// @return signed The signed int256 function asInt256(I256 _i256) internal pure returns (int256 signed) { return I256.unwrap(_i256); } /// @dev Converts an I256 to a signed int248 /// @param _i256 The I256 to convert /// @return signed The signed int248 function asInt248(I256 _i256) internal pure returns (int248 signed) { return int248(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int240 /// @param _i256 The I256 to convert /// @return signed The signed int240 function asInt240(I256 _i256) internal pure returns (int240 signed) { return int240(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int232 /// @param _i256 The I256 to convert /// @return signed The signed int232 function asInt232(I256 _i256) internal pure returns (int232 signed) { return int232(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int224 /// @param _i256 The I256 to convert /// @return signed The signed int224 function asInt224(I256 _i256) internal pure returns (int224 signed) { return int224(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int216 /// @param _i256 The I256 to convert /// @return signed The signed int216 function asInt216(I256 _i256) internal pure returns (int216 signed) { return int216(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int208 /// @param _i256 The I256 to convert /// @return signed The signed int208 function asInt208(I256 _i256) internal pure returns (int208 signed) { return int208(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int200 /// @param _i256 The I256 to convert /// @return signed The signed int200 function asInt200(I256 _i256) internal pure returns (int200 signed) { return int200(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int192 /// @param _i256 The I256 to convert /// @return signed The signed int192 function asInt192(I256 _i256) internal pure returns (int192 signed) { return int192(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int184 /// @param _i256 The I256 to convert /// @return signed The signed int184 function asInt184(I256 _i256) internal pure returns (int184 signed) { return int184(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int176 /// @param _i256 The I256 to convert /// @return signed The signed int176 function asInt176(I256 _i256) internal pure returns (int176 signed) { return int176(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int168 /// @param _i256 The I256 to convert /// @return signed The signed int168 function asInt168(I256 _i256) internal pure returns (int168 signed) { return int168(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int160 /// @param _i256 The I256 to convert /// @return signed The signed int160 function asInt160(I256 _i256) internal pure returns (int160 signed) { return int160(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int152 /// @param _i256 The I256 to convert /// @return signed The signed int152 function asInt152(I256 _i256) internal pure returns (int152 signed) { return int152(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int144 /// @param _i256 The I256 to convert /// @return signed The signed int144 function asInt144(I256 _i256) internal pure returns (int144 signed) { return int144(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int136 /// @param _i256 The I256 to convert /// @return signed The signed int136 function asInt136(I256 _i256) internal pure returns (int136 signed) { return int136(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int128 /// @param _i256 The I256 to convert /// @return signed The signed int128 function asInt128(I256 _i256) internal pure returns (int128 signed) { return int128(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int120 /// @param _i256 The I256 to convert /// @return signed The signed int120 function asInt120(I256 _i256) internal pure returns (int120 signed) { return int120(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int112 /// @param _i256 The I256 to convert /// @return signed The signed int112 function asInt112(I256 _i256) internal pure returns (int112 signed) { return int112(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int104 /// @param _i256 The I256 to convert /// @return signed The signed int104 function asInt104(I256 _i256) internal pure returns (int104 signed) { return int104(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int96 /// @param _i256 The I256 to convert /// @return signed The signed int96 function asInt96(I256 _i256) internal pure returns (int96 signed) { return int96(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int88 /// @param _i256 The I256 to convert /// @return signed The signed int88 function asInt88(I256 _i256) internal pure returns (int88 signed) { return int88(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int80 /// @param _i256 The I256 to convert /// @return signed The signed int80 function asInt80(I256 _i256) internal pure returns (int80 signed) { return int80(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int72 /// @param _i256 The I256 to convert /// @return signed The signed int72 function asInt72(I256 _i256) internal pure returns (int72 signed) { return int72(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int64 /// @param _i256 The I256 to convert /// @return signed The signed int64 function asInt64(I256 _i256) internal pure returns (int64 signed) { return int64(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int56 /// @param _i256 The I256 to convert /// @return signed The signed int56 function asInt56(I256 _i256) internal pure returns (int56 signed) { return int56(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int48 /// @param _i256 The I256 to convert /// @return signed The signed int48 function asInt48(I256 _i256) internal pure returns (int48 signed) { return int48(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int40 /// @param _i256 The I256 to convert /// @return signed The signed int40 function asInt40(I256 _i256) internal pure returns (int40 signed) { return int40(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int32 /// @param _i256 The I256 to convert /// @return signed The signed int32 function asInt32(I256 _i256) internal pure returns (int32 signed) { return int32(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int24 /// @param _i256 The I256 to convert /// @return signed The signed int24 function asInt24(I256 _i256) internal pure returns (int24 signed) { return int24(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int16 /// @param _i256 The I256 to convert /// @return signed The signed int16 function asInt16(I256 _i256) internal pure returns (int16 signed) { return int16(I256.unwrap(_i256)); } /// @dev Converts an I256 to a signed int8 /// @param _i256 The I256 to convert /// @return signed The signed int8 function asInt8(I256 _i256) internal pure returns (int8 signed) { return int8(I256.unwrap(_i256)); } /// @dev Converts an I256 to an unsigned uint256 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint256 function asUint256(I256 _i256) internal pure returns (uint256 unsigned) { return uint256(I256.unwrap(_i256)); } /// @dev Converts an I256 to an unsigned uint248 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint248 function asUint248(I256 _i256) internal pure returns (uint248 unsigned) { return uint248(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint240 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint240 function asUint240(I256 _i256) internal pure returns (uint240 unsigned) { return uint240(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint232 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint232 function asUint232(I256 _i256) internal pure returns (uint232 unsigned) { return uint232(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint224 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint224 function asUint224(I256 _i256) internal pure returns (uint224 unsigned) { return uint224(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint216 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint216 function asUint216(I256 _i256) internal pure returns (uint216 unsigned) { return uint216(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint208 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint208 function asUint208(I256 _i256) internal pure returns (uint208 unsigned) { return uint208(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint200 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint200 function asUint200(I256 _i256) internal pure returns (uint200 unsigned) { return uint200(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint192 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint192 function asUint192(I256 _i256) internal pure returns (uint192 unsigned) { return uint192(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint184 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint184 function asUint184(I256 _i256) internal pure returns (uint184 unsigned) { return uint184(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint176 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint176 function asUint176(I256 _i256) internal pure returns (uint176 unsigned) { return uint176(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint168 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint168 function asUint168(I256 _i256) internal pure returns (uint168 unsigned) { return uint168(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint160 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint160 function asUint160(I256 _i256) internal pure returns (uint160 unsigned) { return uint160(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint152 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint152 function asUint152(I256 _i256) internal pure returns (uint152 unsigned) { return uint152(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint144 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint144 function asUint144(I256 _i256) internal pure returns (uint144 unsigned) { return uint144(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint136 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint136 function asUint136(I256 _i256) internal pure returns (uint136 unsigned) { return uint136(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint128 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint128 function asUint128(I256 _i256) internal pure returns (uint128 unsigned) { return uint128(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint120 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint120 function asUint120(I256 _i256) internal pure returns (uint120 unsigned) { return uint120(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint112 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint112 function asUint112(I256 _i256) internal pure returns (uint112 unsigned) { return uint112(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint104 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint104 function asUint104(I256 _i256) internal pure returns (uint104 unsigned) { return uint104(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint96 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint96 function asUint96(I256 _i256) internal pure returns (uint96 unsigned) { return uint96(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint88 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint88 function asUint88(I256 _i256) internal pure returns (uint88 unsigned) { return uint88(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint80 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint80 function asUint80(I256 _i256) internal pure returns (uint80 unsigned) { return uint80(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint72 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint72 function asUint72(I256 _i256) internal pure returns (uint72 unsigned) { return uint72(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint64 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint64 function asUint64(I256 _i256) internal pure returns (uint64 unsigned) { return uint64(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint56 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint56 function asUint56(I256 _i256) internal pure returns (uint56 unsigned) { return uint56(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint48 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint48 function asUint48(I256 _i256) internal pure returns (uint48 unsigned) { return uint48(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint40 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint40 function asUint40(I256 _i256) internal pure returns (uint40 unsigned) { return uint40(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint32 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint32 function asUint32(I256 _i256) internal pure returns (uint32 unsigned) { return uint32(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint24 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint24 function asUint24(I256 _i256) internal pure returns (uint24 unsigned) { return uint24(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint16 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint16 function asUint16(I256 _i256) internal pure returns (uint16 unsigned) { return uint16(uint256(I256.unwrap(_i256))); } /// @dev Converts an I256 to an unsigned uint8 /// @param _i256 The I256 to convert /// @return unsigned The unsigned uint8 function asUint8(I256 _i256) internal pure returns (uint8 unsigned) { return uint8(uint256(I256.unwrap(_i256))); } /// @dev Adds an int256 to an I256 /// @param _i256 The I256 to add to /// @param _addend The int256 to add /// @return i256 The result of the addition function add(I256 _i256, int256 _addend) internal pure returns (I256 i256) { return I256.wrap(add(I256.unwrap(_i256), _addend)); } /// @dev Subtracts an int256 from an I256 /// @param _i256 The I256 to subtract from /// @param _subtrahend The int256 to subtract /// @return i256 The result of the subtraction function sub(I256 _i256, int256 _subtrahend) internal pure returns (I256 i256) { return I256.wrap(sub(I256.unwrap(_i256), _subtrahend)); } /// @dev Increments an I256 /// @param _i256 The I256 to increment /// @return i256 The result of the increment function inc(I256 _i256) internal pure returns (I256 i256) { return I256.wrap(inc(I256.unwrap(_i256))); } /// @dev Decrements an I256 /// @param _i256 The I256 to decrement /// @return i256 The result of the decrement function dec(I256 _i256) internal pure returns (I256 i256) { return I256.wrap(dec(I256.unwrap(_i256))); } /// @dev Multiplies an I256 by an int256 /// @param _i256 The I256 to multiply /// @param _multiplier The int256 to multiply by /// @return i256 The result of the multiplication function mul(I256 _i256, int256 _multiplier) internal pure returns (I256 i256) { return I256.wrap(mul(I256.unwrap(_i256), _multiplier)); } /// @dev Divides an I256 by an int256 /// @param _i256 The I256 to divide /// @param _divisor The int256 to divide by /// @return i256 The result of the division function div(I256 _i256, int256 _divisor) internal pure returns (I256 i256) { return I256.wrap(div(I256.unwrap(_i256), _divisor)); } /// @dev Divides an I256 by an int256 and returns the remainder /// @param _i256 The I256 to divide /// @param _divisor The int256 to divide by /// @return i256 The remainder of the division function mod(I256 _i256, int256 _divisor) internal pure returns (I256 i256) { return I256.wrap(mod(I256.unwrap(_i256), _divisor)); } /// @dev Logical and of an I256 and an int256 /// @param _i256 The I256 to and /// @param _value The int256 to and with /// @return i256 The result of the and function and(I256 _i256, int256 _value) internal pure returns (I256 i256) { return I256.wrap(I256.unwrap(_i256) & _value); } /// @dev Logical or of an I256 and an int256 /// @param _i256 The I256 to or /// @param _value The int256 to or with /// @return i256 The result of the or function or(I256 _i256, int256 _value) internal pure returns (I256 i256) { return I256.wrap(I256.unwrap(_i256) | _value); } /// @dev Logical xor of an I256 and an int256 /// @param _i256 The I256 to xor /// @param _value The int256 to xor with /// @return i256 The result of the xor function xor(I256 _i256, int256 _value) internal pure returns (I256 i256) { return I256.wrap(I256.unwrap(_i256) ^ _value); } /// @dev Logical not of an I256 /// @param _i256 The I256 to not /// @return i256 The result of the not function not(I256 _i256) internal pure returns (I256 i256) { return I256.wrap(~I256.unwrap(_i256)); } /// @dev Compares an I256 to an int256 for equality /// @param _i256 The I256 to compare /// @param _value The int256 to compare to /// @return equal True if the I256 and int256 are equal function eq(I256 _i256, int256 _value) internal pure returns (bool) { return I256.unwrap(_i256) == _value; } /// @dev Compares an I256 to an int256 for inequality /// @param _i256 The I256 to compare /// @param _value The int256 to compare to /// @return equal True if the I256 and int256 are not equal function neq(I256 _i256, int256 _value) internal pure returns (bool) { return I256.unwrap(_i256) != _value; } /// @dev Compares an I256 to an int256 for greater than /// @param _i256 The I256 to compare /// @param _value The int256 to compare to /// @return equal True if the I256 is greater than the int256 function gt(I256 _i256, int256 _value) internal pure returns (bool) { return I256.unwrap(_i256) > _value; } /// @dev Compares an I256 to an int256 for greater than or equal to /// @param _i256 The I256 to compare /// @param _value The int256 to compare to /// @return equal True if the I256 is greater than or equal to the int256 function gte(I256 _i256, int256 _value) internal pure returns (bool) { return I256.unwrap(_i256) >= _value; } /// @dev Compares an I256 to an int256 for less than /// @param _i256 The I256 to compare /// @param _value The int256 to compare to /// @return equal True if the I256 is less than the int256 function lt(I256 _i256, int256 _value) internal pure returns (bool) { return I256.unwrap(_i256) < _value; } /// @dev Compares an I256 to an int256 for less than or equal to /// @param _i256 The I256 to compare /// @param _value The int256 to compare to /// @return equal True if the I256 is less than or equal to the int256 function lte(I256 _i256, int256 _value) internal pure returns (bool) { return I256.unwrap(_i256) <= _value; } /********************* * U256 -> *********************/ /// @dev Wraps an int256 into a U256. /// @param _i256 The int256 to wrap. /// @return u256 The wrapped U256. function asU256(int256 _i256) internal pure returns (U256 u256) { u256 = U256.wrap(uint256(_i256)); } /// @dev Wraps a uint256 into a U256. /// @param _u256 The uint256 to wrap. /// @return u256 The wrapped U256. function asU256(uint256 _u256) internal pure returns (U256 u256) { u256 = U256.wrap(_u256); } /// @dev Converts a U256 to a uint256. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint256 representation of the U256. function asUint256(U256 _u256) internal pure returns (uint256 unsigned) { return U256.unwrap(_u256); } /// @dev Converts a U256 to a uint224. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint224 representation of the U256. function asUint224(U256 _u256) internal pure returns (uint224 unsigned) { return uint224(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint216. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint216 representation of the U256. function asUint216(U256 _u256) internal pure returns (uint216 unsigned) { return uint216(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint208. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint208 representation of the U256. function asUint208(U256 _u256) internal pure returns (uint208 unsigned) { return uint208(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint200. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint200 representation of the U256. function asUint200(U256 _u256) internal pure returns (uint200 unsigned) { return uint200(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint192. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint192 representation of the U256. function asUint192(U256 _u256) internal pure returns (uint192 unsigned) { return uint192(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint184. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint184 representation of the U256. function asUint184(U256 _u256) internal pure returns (uint184 unsigned) { return uint184(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint176. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint176 representation of the U256. function asUint176(U256 _u256) internal pure returns (uint176 unsigned) { return uint176(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint168. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint168 representation of the U256. function asUint168(U256 _u256) internal pure returns (uint168 unsigned) { return uint168(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint160. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint160 representation of the U256. function asUint160(U256 _u256) internal pure returns (uint160 unsigned) { return uint160(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint152. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint152 representation of the U256. function asUint152(U256 _u256) internal pure returns (uint152 unsigned) { return uint152(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint144. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint144 representation of the U256. function asUint144(U256 _u256) internal pure returns (uint144 unsigned) { return uint144(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint136. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint136 representation of the U256. function asUint136(U256 _u256) internal pure returns (uint136 unsigned) { return uint136(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint128. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint128 representation of the U256. function asUint128(U256 _u256) internal pure returns (uint128 unsigned) { return uint128(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint120. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint120 representation of the U256. function asUint120(U256 _u256) internal pure returns (uint120 unsigned) { return uint120(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint112. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint112 representation of the U256. function asUint112(U256 _u256) internal pure returns (uint112 unsigned) { return uint112(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint104. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint104 representation of the U256. function asUint104(U256 _u256) internal pure returns (uint104 unsigned) { return uint104(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint96. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint96 representation of the U256. function asUint96(U256 _u256) internal pure returns (uint96 unsigned) { return uint96(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint88. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint88 representation of the U256. function asUint88(U256 _u256) internal pure returns (uint88 unsigned) { return uint88(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint80. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint80 representation of the U256. function asUint80(U256 _u256) internal pure returns (uint80 unsigned) { return uint80(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint72. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint72 representation of the U256. function asUint72(U256 _u256) internal pure returns (uint72 unsigned) { return uint72(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint64. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint64 representation of the U256. function asUint64(U256 _u256) internal pure returns (uint64 unsigned) { return uint64(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint56. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint56 representation of the U256. function asUint56(U256 _u256) internal pure returns (uint56 unsigned) { return uint56(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint48. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint48 representation of the U256. function asUint48(U256 _u256) internal pure returns (uint48 unsigned) { return uint48(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint40. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint40 representation of the U256. function asUint40(U256 _u256) internal pure returns (uint40 unsigned) { return uint40(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint32. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint32 representation of the U256. function asUint32(U256 _u256) internal pure returns (uint32 unsigned) { return uint32(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint24. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint24 representation of the U256. function asUint24(U256 _u256) internal pure returns (uint24 unsigned) { return uint24(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint16. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint16 representation of the U256. function asUint16(U256 _u256) internal pure returns (uint16 unsigned) { return uint16(U256.unwrap(_u256)); } /// @dev Converts a U256 to a uint8. /// @param _u256 The U256 to unwrap. /// @return unsigned The uint8 representation of the U256. function asUint8(U256 _u256) internal pure returns (uint8 unsigned) { return uint8(U256.unwrap(_u256)); } /// @dev Converts a U256 to an int256. /// @param _u256 The U256 to convert. /// @return signed The int256 representation of the U256. function asInt256(U256 _u256) internal pure returns (int256 signed) { return int256(U256.unwrap(_u256)); } /// @dev Converts a U256 to an int248. /// @param _u256 The U256 to convert. /// @return signed The int248 representation of the U256. function asInt248(U256 _u256) internal pure returns (int248 signed) { return int248(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int240. /// @param _u256 The U256 to convert. /// @return signed The int240 representation of the U256. function asInt240(U256 _u256) internal pure returns (int240 signed) { return int240(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int232. /// @param _u256 The U256 to convert. /// @return signed The int232 representation of the U256. function asInt232(U256 _u256) internal pure returns (int232 signed) { return int232(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int224. /// @param _u256 The U256 to convert. /// @return signed The int224 representation of the U256. function asInt224(U256 _u256) internal pure returns (int224 signed) { return int224(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int216. /// @param _u256 The U256 to convert. /// @return signed The int216 representation of the U256. function asInt216(U256 _u256) internal pure returns (int216 signed) { return int216(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int208. /// @param _u256 The U256 to convert. /// @return signed The int208 representation of the U256. function asInt208(U256 _u256) internal pure returns (int208 signed) { return int208(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int200. /// @param _u256 The U256 to convert. /// @return signed The int200 representation of the U256. function asInt200(U256 _u256) internal pure returns (int200 signed) { return int200(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int192. /// @param _u256 The U256 to convert. /// @return signed The int192 representation of the U256. function asInt192(U256 _u256) internal pure returns (int192 signed) { return int192(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int184. /// @param _u256 The U256 to convert. /// @return signed The int184 representation of the U256. function asInt184(U256 _u256) internal pure returns (int184 signed) { return int184(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int176. /// @param _u256 The U256 to convert. /// @return signed The int176 representation of the U256. function asInt176(U256 _u256) internal pure returns (int176 signed) { return int176(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int168. /// @param _u256 The U256 to convert. /// @return signed The int168 representation of the U256. function asInt168(U256 _u256) internal pure returns (int168 signed) { return int168(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int160. /// @param _u256 The U256 to convert. /// @return signed The int160 representation of the U256. function asInt160(U256 _u256) internal pure returns (int160 signed) { return int160(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int152. /// @param _u256 The U256 to convert. /// @return signed The int152 representation of the U256. function asInt152(U256 _u256) internal pure returns (int152 signed) { return int152(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int144. /// @param _u256 The U256 to convert. /// @return signed The int144 representation of the U256. function asInt144(U256 _u256) internal pure returns (int144 signed) { return int144(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int136. /// @param _u256 The U256 to convert. /// @return signed The int136 representation of the U256. function asInt136(U256 _u256) internal pure returns (int136 signed) { return int136(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int128. /// @param _u256 The U256 to convert. /// @return signed The int128 representation of the U256. function asInt128(U256 _u256) internal pure returns (int128 signed) { return int128(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int120. /// @param _u256 The U256 to convert. /// @return signed The int120 representation of the U256. function asInt120(U256 _u256) internal pure returns (int120 signed) { return int120(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int112. /// @param _u256 The U256 to convert. /// @return signed The int112 representation of the U256. function asInt112(U256 _u256) internal pure returns (int112 signed) { return int112(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int104. /// @param _u256 The U256 to convert. /// @return signed The int104 representation of the U256. function asInt104(U256 _u256) internal pure returns (int104 signed) { return int104(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int96. /// @param _u256 The U256 to convert. /// @return signed The int96 representation of the U256. function asInt96(U256 _u256) internal pure returns (int96 signed) { return int96(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int88. /// @param _u256 The U256 to convert. /// @return signed The int88 representation of the U256. function asInt88(U256 _u256) internal pure returns (int88 signed) { return int88(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int80. /// @param _u256 The U256 to convert. /// @return signed The int80 representation of the U256. function asInt80(U256 _u256) internal pure returns (int80 signed) { return int80(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int72. /// @param _u256 The U256 to convert. /// @return signed The int72 representation of the U256. function asInt72(U256 _u256) internal pure returns (int72 signed) { return int72(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int64. /// @param _u256 The U256 to convert. /// @return signed The int64 representation of the U256. function asInt64(U256 _u256) internal pure returns (int64 signed) { return int64(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int56. /// @param _u256 The U256 to convert. /// @return signed The int56 representation of the U256. function asInt56(U256 _u256) internal pure returns (int56 signed) { return int56(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int48. /// @param _u256 The U256 to convert. /// @return signed The int48 representation of the U256. function asInt48(U256 _u256) internal pure returns (int48 signed) { return int48(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int40. /// @param _u256 The U256 to convert. /// @return signed The int40 representation of the U256. function asInt40(U256 _u256) internal pure returns (int40 signed) { return int40(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int32. /// @param _u256 The U256 to convert. /// @return signed The int32 representation of the U256. function asInt32(U256 _u256) internal pure returns (int32 signed) { return int32(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int24. /// @param _u256 The U256 to convert. /// @return signed The int24 representation of the U256. function asInt24(U256 _u256) internal pure returns (int24 signed) { return int24(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int16. /// @param _u256 The U256 to convert. /// @return signed The int16 representation of the U256. function asInt16(U256 _u256) internal pure returns (int16 signed) { return int16(int256(U256.unwrap(_u256))); } /// @dev Converts a U256 to an int8. /// @param _u256 The U256 to convert. /// @return signed The int8 representation of the U256. function asInt8(U256 _u256) internal pure returns (int8 signed) { return int8(int256(U256.unwrap(_u256))); } /// @dev Adds a uint256 to a U256. /// @param _u256 The U256 to add to. /// @param _addend The uint256 to add. /// @return u256 The U256 result of the addition. function add(U256 _u256, uint256 _addend) internal pure returns (U256 u256) { u256 = U256.wrap(add(U256.unwrap(_u256), _addend)); } /// @dev Subtracts a uint256 from a U256. /// @param _u256 The U256 to subtract from. /// @param _subtrahend The uint256 to subtract. /// @return u256 The U256 result of the subtraction. function sub(U256 _u256, uint256 _subtrahend) internal pure returns (U256 u256) { return U256.wrap(sub(U256.unwrap(_u256), _subtrahend)); } /// @dev Increments a U256. /// @param _u256 The U256 to increment. /// @return u256 The U256 result of the increment. function inc(U256 _u256) internal pure returns (U256 u256) { return U256.wrap(inc(U256.unwrap(_u256))); } /// @dev Decrements a U256. /// @param _u256 The U256 to decrement. /// @return u256 The U256 result of the decrement. function dec(U256 _u256) internal pure returns (U256 u256) { return U256.wrap(dec(U256.unwrap(_u256))); } /// @notice Calculate the product of a U256 and a uint256 /// @param _u256 The U256 /// @param _multiplier The uint256 /// @return u256 The product of _u256 and _multiplier function mul(U256 _u256, uint256 _multiplier) internal pure returns (U256 u256) { return U256.wrap(mul(U256.unwrap(_u256), _multiplier)); } /** * @dev Divide a U256 number by a uint256 number. * @param _u256 The U256 number to divide. * @param _divisor The uint256 number to divide by. * @return u256 The result of dividing _u256 by _divisor. */ function div(U256 _u256, uint256 _divisor) internal pure returns (U256 u256) { return U256.wrap(div(U256.unwrap(_u256), _divisor)); } /// @dev Get the modulus of a U256 and a uint256 /// @param _u256 The U256 to be divided /// @param _divisor The divisor /// @return u256 The result of the modulo operation function mod(U256 _u256, uint256 _divisor) internal pure returns (U256 u256) { return U256.wrap(mod(U256.unwrap(_u256), _divisor)); } /// @notice Raise a U256 to the power of a uint256 /// @param _u256 The base /// @param _exponent The exponent /// @return u256 The result of raising `_u256` to the power of `_exponent` function exp(U256 _u256, uint256 _exponent) internal pure returns (U256 u256) { return U256.wrap(exp(U256.unwrap(_u256), _exponent)); } /// @dev Right shift a uint256 by a uint256. /// @param _u256 uint256 to right shift /// @param _shift uint256 to shift by /// @return u256 uint256 result of right shift function rshift(U256 _u256, U256 _shift) internal pure returns (U256 u256) { return U256.wrap(U256.unwrap(_u256) >> U256.unwrap(_shift)); } /// @dev Left shift a U256 by a U256. /// @param _u256 U256 to left shift /// @param _shift U256 to shift by /// @return u256 U256 result of left shift function lshift(U256 _u256, U256 _shift) internal pure returns (U256 u256) { return U256.wrap(U256.unwrap(_u256) << U256.unwrap(_shift)); } /// @dev Right shift a U256 by a uint256. /// @param _u256 U256 to right shift /// @param _shift uint256 to shift by /// @return u256 U256 result of right shift function rshift(U256 _u256, uint256 _shift) internal pure returns (U256 u256) { return U256.wrap(U256.unwrap(_u256) >> _shift); } /// @dev Left shift a U256 by a uint256. /// @param _u256 U256 to left shift /// @param _shift uint256 to shift by /// @return u256 U256 result of left shift function lshift(U256 _u256, uint256 _shift) internal pure returns (U256 u256) { return U256.wrap(U256.unwrap(_u256) << _shift); } /// @dev logical and between the input and the value /// @param _u256 input /// @param _value value /// @return u256 the result of the logical and function and(U256 _u256, uint256 _value) internal pure returns (U256 u256) { return _u256 & U256.wrap(_value); } /// @dev logical or between the input and the value /// @param _u256 input /// @param _value value /// @return u256 the result of the logical or function or(U256 _u256, uint256 _value) internal pure returns (U256 u256) { return _u256 | U256.wrap(_value); } /// @dev logical xor between the input and the value /// @param _u256 input /// @param _value value /// @return u256 the result of the logical xor function xor(U256 _u256, uint256 _value) internal pure returns (U256 u256) { return _u256 ^ U256.wrap(_value); } /// @dev logical not of the input /// @param _u256 input /// @return u256 the result of the logical not function not(U256 _u256) internal pure returns (U256 u256) { return ~_u256; } /// @dev Compare a U256 to a uint256 for equality /// @param _u256 The U256 to compare /// @param _value The uint256 to compare /// @return result True if the U256 is equal to the uint256 function eq(U256 _u256, uint256 _value) internal pure returns (bool result) { return U256.unwrap(_u256) == _value; } /// @dev Compare a U256 to a uint256 for inequality /// @param _u256 The U256 to compare /// @param _value The uint256 to compare /// @return result True if the U256 is not equal to the uint256 function neq(U256 _u256, uint256 _value) internal pure returns (bool result) { return U256.unwrap(_u256) != _value; } /// @dev Compare a U256 to a uint256 for greater than /// @param _u256 The U256 to compare /// @param _value The uint256 to compare /// @return result True if the U256 is greater than the uint256 function gt(U256 _u256, uint256 _value) internal pure returns (bool result) { return U256.unwrap(_u256) > _value; } /// @dev Compare a U256 to a uint256 for greater than or equal to /// @param _u256 The U256 to compare /// @param _value The uint256 to compare /// @return result True if the U256 is greater than or equal to the uint256 function gte(U256 _u256, uint256 _value) internal pure returns (bool result) { return U256.unwrap(_u256) >= _value; } /// @dev Compare a U256 to a uint256 for less than /// @param _u256 The U256 to compare /// @param _value The uint256 to compare /// @return result True if the U256 is less than the uint256 function lt(U256 _u256, uint256 _value) internal pure returns (bool result) { return U256.unwrap(_u256) < _value; } /// @dev Compare a U256 to a uint256 for less than or equal to /// @param _u256 The U256 to compare /// @param _value The uint256 to compare /// @return result True if the U256 is less than or equal to the uint256 function lte(U256 _u256, uint256 _value) internal pure returns (bool result) { return U256.unwrap(_u256) <= _value; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface VRFCoordinatorV2Interface { /** * @notice Get configuration relevant for making requests * @return minimumRequestConfirmations global min for request confirmations * @return maxGasLimit global max for request gas limit * @return s_provingKeyHashes list of registered key hashes */ function getRequestConfig() external view returns ( uint16, uint32, bytes32[] memory ); /** * @notice Request a set of random words. * @param keyHash - Corresponds to a particular oracle job which uses * that key for generating the VRF proof. Different keyHash's have different gas price * ceilings, so you can select a specific one to bound your maximum per request cost. * @param subId - The ID of the VRF subscription. Must be funded * with the minimum subscription balance required for the selected keyHash. * @param minimumRequestConfirmations - How many blocks you'd like the * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS * for why you may want to request more. The acceptable range is * [minimumRequestBlockConfirmations, 200]. * @param callbackGasLimit - How much gas you'd like to receive in your * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords * may be slightly less than this amount because of gas used calling the function * (argument decoding etc.), so you may need to request slightly more than you expect * to have inside fulfillRandomWords. The acceptable range is * [0, maxGasLimit] * @param numWords - The number of uint256 random values you'd like to receive * in your fulfillRandomWords callback. Note these numbers are expanded in a * secure way by the VRFCoordinator from a single random value supplied by the oracle. * @return requestId - A unique identifier of the request. Can be used to match * a request to a response in fulfillRandomWords. */ function requestRandomWords( bytes32 keyHash, uint64 subId, uint16 minimumRequestConfirmations, uint32 callbackGasLimit, uint32 numWords ) external returns (uint256 requestId); /** * @notice Create a VRF subscription. * @return subId - A unique subscription id. * @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. * @dev Note to fund the subscription, use transferAndCall. For example * @dev LINKTOKEN.transferAndCall( * @dev address(COORDINATOR), * @dev amount, * @dev abi.encode(subId)); */ function createSubscription() external returns (uint64 subId); /** * @notice Get a VRF subscription. * @param subId - ID of the subscription * @return balance - LINK balance of the subscription in juels. * @return reqCount - number of requests for this subscription, determines fee tier. * @return owner - owner of the subscription. * @return consumers - list of consumer address which are able to use this subscription. */ function getSubscription(uint64 subId) external view returns ( uint96 balance, uint64 reqCount, address owner, address[] memory consumers ); /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @param newOwner - proposed new owner of the subscription */ function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external; /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @dev will revert if original owner of subId has * not requested that msg.sender become the new owner. */ function acceptSubscriptionOwnerTransfer(uint64 subId) external; /** * @notice Add a consumer to a VRF subscription. * @param subId - ID of the subscription * @param consumer - New consumer which can use the subscription */ function addConsumer(uint64 subId, address consumer) external; /** * @notice Remove a consumer from a VRF subscription. * @param subId - ID of the subscription * @param consumer - Consumer to remove from the subscription */ function removeConsumer(uint64 subId, address consumer) external; /** * @notice Cancel a subscription * @param subId - ID of the subscription * @param to - Where to send the remaining LINK to */ function cancelSubscription(uint64 subId, address to) external; /* * @notice Check to see if there exists a request commitment consumers * for all consumers and keyhashes for a given sub. * @param subId - ID of the subscription * @return true if there exists at least one unfulfilled request for the subscription, false * otherwise. */ function pendingRequestExists(uint64 subId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol) pragma solidity ^0.8.0; /** * @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified * proxy whose upgrades are fully controlled by the current implementation. */ interface IERC1822ProxiableUpgradeable { /** * @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation * address. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. */ function proxiableUUID() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol) pragma solidity ^0.8.0; /** * @dev This is the interface that {BeaconProxy} expects of its beacon. */ interface IBeaconUpgradeable { /** * @dev Must return an address that can be used as a delegate call target. * * {BeaconProxy} will check that this address is a contract. */ function implementation() external view returns (address); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol) pragma solidity ^0.8.0; import "../IERC1155Upgradeable.sol"; /** * @dev Interface of the optional ERC1155MetadataExtension interface, as defined * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP]. * * _Available since v3.1._ */ interface IERC1155MetadataURIUpgradeable is IERC1155Upgradeable { /** * @dev Returns the URI for token type `id`. * * If the `\{id\}` substring is present in the URI, it must be replaced by * clients with the actual token type ID. */ function uri(uint256 id) external view returns (string memory); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev _Available since v3.1._ */ interface IERC1155ReceiverUpgradeable is IERC165Upgradeable { /** * @dev Handles the receipt of a single ERC1155 token type. This function is * called at the end of a `safeTransferFrom` after the balance has been updated. * * NOTE: To accept the transfer, this must return * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` * (i.e. 0xf23a6e61, or its own function selector). * * @param operator The address which initiated the transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param id The ID of the token being transferred * @param value The amount of tokens being transferred * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed */ function onERC1155Received( address operator, address from, uint256 id, uint256 value, bytes calldata data ) external returns (bytes4); /** * @dev Handles the receipt of a multiple ERC1155 token types. This function * is called at the end of a `safeBatchTransferFrom` after the balances have * been updated. * * NOTE: To accept the transfer(s), this must return * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` * (i.e. 0xbc197c81, or its own function selector). * * @param operator The address which initiated the batch transfer (i.e. msg.sender) * @param from The address which previously owned the token * @param ids An array containing ids of each token being transferred (order and length must match values array) * @param values An array containing amounts of each token being transferred (order and length must match ids array) * @param data Additional data with no specified format * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed */ function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata values, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.sol"; /** * @dev Required interface of an ERC1155 compliant contract, as defined in the * https://eips.ethereum.org/EIPS/eip-1155[EIP]. * * _Available since v3.1._ */ interface IERC1155Upgradeable is IERC165Upgradeable { /** * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`. */ event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value); /** * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all * transfers. */ event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] values ); /** * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to * `approved`. */ event ApprovalForAll(address indexed account, address indexed operator, bool approved); /** * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI. * * If an {URI} event was emitted for `id`, the standard * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value * returned by {IERC1155MetadataURI-uri}. */ event URI(string value, uint256 indexed id); /** * @dev Returns the amount of tokens of token type `id` owned by `account`. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) external view returns (uint256); /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids) external view returns (uint256[] memory); /** * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`, * * Emits an {ApprovalForAll} event. * * Requirements: * * - `operator` cannot be the caller. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns true if `operator` is approved to transfer ``account``'s tokens. * * See {setApprovalForAll}. */ function isApprovedForAll(address account, address operator) external view returns (bool); /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes calldata data ) external; /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function safeBatchTransferFrom( address from, address to, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165Upgradeable { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol) pragma solidity ^0.8.0; /** * @dev Library for reading and writing primitive types to specific storage slots. * * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts. * This library helps with reading and writing to such slots without the need for inline assembly. * * The functions in this library return Slot structs that contain a `value` member that can be used to read or write. * * Example usage to set ERC1967 implementation slot: * ``` * contract ERC1967 { * bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; * * function _getImplementation() internal view returns (address) { * return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value; * } * * function _setImplementation(address newImplementation) internal { * require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract"); * StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; * } * } * ``` * * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._ */ library StorageSlotUpgradeable { struct AddressSlot { address value; } struct BooleanSlot { bool value; } struct Bytes32Slot { bytes32 value; } struct Uint256Slot { uint256 value; } /** * @dev Returns an `AddressSlot` with member `value` located at `slot`. */ function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `BooleanSlot` with member `value` located at `slot`. */ function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Bytes32Slot` with member `value` located at `slot`. */ function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } /** * @dev Returns an `Uint256Slot` with member `value` located at `slot`. */ function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) { /// @solidity memory-safe-assembly assembly { r.slot := slot } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (interfaces/IERC2981.sol) pragma solidity ^0.8.0; import "../utils/introspection/IERC165.sol"; /** * @dev Interface for the NFT Royalty Standard. * * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal * support for royalty payments across all NFT marketplaces and ecosystem participants. * * _Available since v4.5._ */ interface IERC2981 is IERC165 { /** * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of * exchange. The royalty amount is denominated and should be paid in that same unit of exchange. */ function royaltyInfo(uint256 tokenId, uint256 salePrice) external view returns (address receiver, uint256 royaltyAmount); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {UUPSUpgradeable} from "./ozUpgradeable/proxy/utils/UUPSUpgradeable.sol"; import {OwnableUpgradeable} from "./ozUpgradeable/access/OwnableUpgradeable.sol"; import {UnsafeMath, U256} from "@0xdoublesharp/unsafe-math/contracts/UnsafeMath.sol"; contract AdminAccess is UUPSUpgradeable, OwnableUpgradeable { using UnsafeMath for U256; using UnsafeMath for uint256; mapping(address admin => bool isAdmin) private admins; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize(address[] calldata _admins) public initializer { __Ownable_init(); __UUPSUpgradeable_init(); _updateAdmins(_admins, true); } function addAdmins(address[] calldata _admins) external onlyOwner { _updateAdmins(_admins, true); } function addAdmin(address _admin) external onlyOwner { _updateAdmin(_admin, true); } function removeAdmin(address _admin) external onlyOwner { _updateAdmin(_admin, false); } function isAdmin(address _admin) external view returns (bool) { return admins[_admin]; } function _updateAdmins(address[] calldata _admins, bool _isAdmin) internal { U256 bounds = _admins.length.asU256(); for (U256 iter; iter < bounds; iter = iter.inc()) { admins[_admins[iter.asUint256()]] = _isAdmin; } } function _updateAdmin(address _admin, bool _isAdmin) internal { admins[_admin] = _isAdmin; } // solhint-disable-next-line no-empty-blocks function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {Skill, Attire, CombatStyle, CombatStats} from "./misc.sol"; import {GuaranteedReward, RandomReward} from "./rewards.sol"; enum ActionQueueStatus { NONE, APPEND, KEEP_LAST_IN_PROGRESS } // The user chooses these struct QueuedActionInput { // Keep this first Attire attire; uint16 actionId; uint16 regenerateId; // Food (combat), maybe something for non-combat later uint16 choiceId; // Melee/Arrow/Magic (combat), logs, ore (non-combat) uint16 rightHandEquipmentTokenId; // Axe/Sword/bow, can be empty uint16 leftHandEquipmentTokenId; // Shield, can be empty uint24 timespan; // How long to queue the action for CombatStyle combatStyle; // specific style of combat, can also be used } struct QueuedAction { uint16 actionId; uint16 regenerateId; // Food (combat), maybe something for non-combat later uint16 choiceId; // Melee/Arrow/Magic (combat), logs, ore (non-combat) uint16 rightHandEquipmentTokenId; // Axe/Sword/bow, can be empty uint16 leftHandEquipmentTokenId; // Shield, can be empty uint24 timespan; // How long to queue the action for CombatStyle combatStyle; // specific style of combat, can also be used uint24 prevProcessedTime; // How long the action has been processed for previously uint24 prevProcessedXPTime; // How much XP has been gained for this action so far uint64 queueId; // id of this queued action bool isValid; // If we still have the item, TODO: Not used yet } // This is only used as an input arg struct Action { uint16 actionId; ActionInfo info; GuaranteedReward[] guaranteedRewards; RandomReward[] randomRewards; CombatStats combatStats; } struct ActionInfo { Skill skill; bool isAvailable; bool isDynamic; bool actionChoiceRequired; // If true, then the user must choose an action choice uint24 xpPerHour; uint32 minXP; uint24 numSpawned; // Mostly for combat, capped respawn rate for xp/drops. Per hour, base 10000 uint16 handItemTokenIdRangeMin; // Inclusive uint16 handItemTokenIdRangeMax; // Inclusive uint8 successPercent; // 0-100 } // Allows for 2, 4 or 8 hour respawn time uint constant SPAWN_MUL = 1000; uint constant RATE_MUL = 1000; uint constant GUAR_MUL = 10; // Guaranteeded reward multiplier (1 decimal, allows for 2 hour respawn time)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "./actions.sol"; import "./items.sol"; import "./misc.sol"; import "./players.sol"; import "./rewards.sol";
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; uint16 constant NONE = 0; // 1 - 255 (head) uint16 constant HEAD_BASE = 1; uint16 constant BRONZE_HELMET = HEAD_BASE; uint16 constant IRON_HELMET = HEAD_BASE + 1; uint16 constant MITHRIL_HELMET = HEAD_BASE + 2; uint16 constant ADAMANTINE_HELMET = HEAD_BASE + 3; uint16 constant RUNITE_HELMET = HEAD_BASE + 4; uint16 constant TITANIUM_HELMET = HEAD_BASE + 5; uint16 constant ORICHALCUM_HELMET = HEAD_BASE + 6; uint16 constant NATUOW_HOOD = HEAD_BASE + 7; uint16 constant BAT_WING_HAT = HEAD_BASE + 8; uint16 constant NATURE_MASK = HEAD_BASE + 9; uint16 constant APPRENTICE_HAT = HEAD_BASE + 10; uint16 constant MAGE_HOOD = HEAD_BASE + 11; uint16 constant SORCERER_HAT = HEAD_BASE + 12; uint16 constant SEERS_HOOD = HEAD_BASE + 13; uint16 constant SHAMAN_HOOD = HEAD_BASE + 14; uint16 constant MASTER_HAT = HEAD_BASE + 15; uint16 constant HEAD_MAX = HEAD_BASE + 254; // Inclusive // 257 - 511 (neck) uint16 constant NECK_BASE = 257; uint16 constant SAPPHIRE_AMULET = NECK_BASE; uint16 constant EMERALD_AMULET = NECK_BASE + 1; uint16 constant RUBY_AMULET = NECK_BASE + 2; uint16 constant AMETHYST_AMULET = NECK_BASE + 3; uint16 constant DIAMOND_AMULET = NECK_BASE + 4; uint16 constant DRAGONSTONE_AMULET = NECK_BASE + 5; uint16 constant NECK_MAX = NECK_BASE + 254; // 513 - 767 (body) uint16 constant BODY_BASE = 513; uint16 constant BRONZE_ARMOR = BODY_BASE; uint16 constant IRON_ARMOR = BODY_BASE + 1; uint16 constant MITHRIL_ARMOR = BODY_BASE + 2; uint16 constant ADAMANTINE_ARMOR = BODY_BASE + 3; uint16 constant RUNITE_ARMOR = BODY_BASE + 4; uint16 constant TITANIUM_ARMOR = BODY_BASE + 5; uint16 constant ORICHALCUM_ARMOR = BODY_BASE + 6; uint16 constant NATUOW_BODY = BODY_BASE + 7; uint16 constant BAT_WING_BODY = BODY_BASE + 8; uint16 constant NATURE_BODY = BODY_BASE + 9; uint16 constant APPRENTICE_BODY = BODY_BASE + 10; uint16 constant MAGE_BODY = BODY_BASE + 11; uint16 constant SORCERER_BODY = BODY_BASE + 12; uint16 constant SEERS_BODY = BODY_BASE + 13; uint16 constant SHAMAN_BODY = BODY_BASE + 14; uint16 constant MASTER_BODY = BODY_BASE + 15; uint16 constant BODY_MAX = BODY_BASE + 254; // 769 - 1023 (arms) uint16 constant ARMS_BASE = 769; uint16 constant BRONZE_GAUNTLETS = ARMS_BASE; uint16 constant IRON_GAUNTLETS = ARMS_BASE + 1; uint16 constant MITHRIL_GAUNTLETS = ARMS_BASE + 2; uint16 constant ADAMANTINE_GAUNTLETS = ARMS_BASE + 3; uint16 constant RUNITE_GAUNTLETS = ARMS_BASE + 4; uint16 constant TITANIUM_GAUNTLETS = ARMS_BASE + 5; uint16 constant ORICHALCUM_GAUNTLETS = ARMS_BASE + 6; uint16 constant NATUOW_BRACERS = ARMS_BASE + 7; uint16 constant BAT_WING_BRACERS = ARMS_BASE + 8; uint16 constant NATURE_BRACERS = ARMS_BASE + 9; uint16 constant APPRENTICE_GAUNTLETS = ARMS_BASE + 10; uint16 constant MAGE_BRACERS = ARMS_BASE + 11; uint16 constant SORCERER_GAUNTLETS = ARMS_BASE + 12; uint16 constant SEERS_BRACERS = ARMS_BASE + 13; uint16 constant SHAMAN_GAUNTLETS = ARMS_BASE + 14; uint16 constant MASTER_BRACERS = ARMS_BASE + 15; uint16 constant ARMS_MAX = ARMS_BASE + 254; // 1025 - 1279 (legs) uint16 constant LEGS_BASE = 1025; uint16 constant BRONZE_TASSETS = LEGS_BASE; uint16 constant IRON_TASSETS = LEGS_BASE + 1; uint16 constant MITHRIL_TASSETS = LEGS_BASE + 2; uint16 constant ADAMANTINE_TASSETS = LEGS_BASE + 3; uint16 constant RUNITE_TASSETS = LEGS_BASE + 4; uint16 constant TITANIUM_TASSETS = LEGS_BASE + 5; uint16 constant ORICHALCUM_TASSETS = LEGS_BASE + 6; uint16 constant NATUOW_TASSETS = LEGS_BASE + 7; uint16 constant BAT_WING_TROUSERS = LEGS_BASE + 8; uint16 constant NATURE_TROUSERS = LEGS_BASE + 9; uint16 constant APPRENTICE_TROUSERS = LEGS_BASE + 10; uint16 constant MAGE_TROUSERS = LEGS_BASE + 11; uint16 constant SORCERER_TROUSERS = LEGS_BASE + 12; uint16 constant SEERS_TROUSERS = LEGS_BASE + 13; uint16 constant SHAMAN_TROUSERS = LEGS_BASE + 14; uint16 constant MASTER_TROUSERS = LEGS_BASE + 15; uint16 constant LEGS_MAX = LEGS_BASE + 254; // 1281 - 1535 (feet) uint16 constant FEET_BASE = 1281; uint16 constant BRONZE_BOOTS = FEET_BASE; uint16 constant IRON_BOOTS = FEET_BASE + 1; uint16 constant MITHRIL_BOOTS = FEET_BASE + 2; uint16 constant ADAMANTINE_BOOTS = FEET_BASE + 3; uint16 constant RUNITE_BOOTS = FEET_BASE + 4; uint16 constant TITANIUM_BOOTS = FEET_BASE + 5; uint16 constant ORICHALCUM_BOOTS = FEET_BASE + 6; uint16 constant NATUOW_BOOTS = FEET_BASE + 7; uint16 constant BAT_WING_BOOTS = FEET_BASE + 8; uint16 constant NATURE_BOOTS = FEET_BASE + 9; uint16 constant APPRENTICE_BOOTS = FEET_BASE + 10; uint16 constant MAGE_BOOTS = FEET_BASE + 11; uint16 constant SORCERER_BOOTS = FEET_BASE + 12; uint16 constant SEERS_BOOTS = FEET_BASE + 13; uint16 constant SHAMAN_BOOTS = FEET_BASE + 14; uint16 constant MASTER_BOOTS = FEET_BASE + 15; uint16 constant BOOTS_MAX = FEET_BASE + 254; // 1536 - 1791 spare(1) // 1792 - 2047 spare(2) // Combat (right arm) (2048 - 2303) uint16 constant COMBAT_BASE = 2048; // Melee uint16 constant SWORD_BASE = COMBAT_BASE; uint16 constant BRONZE_SWORD = SWORD_BASE; uint16 constant IRON_SWORD = COMBAT_BASE + 1; uint16 constant MITHRIL_SWORD = COMBAT_BASE + 2; uint16 constant ADAMANTINE_SWORD = COMBAT_BASE + 3; uint16 constant RUNITE_SWORD = COMBAT_BASE + 4; uint16 constant TITANIUM_SWORD = COMBAT_BASE + 5; uint16 constant ORICHALCUM_SWORD = COMBAT_BASE + 6; uint16 constant SWORD_MAX = SWORD_BASE + 49; // Magic uint16 constant STAFF_BASE = COMBAT_BASE + 50; uint16 constant TOTEM_STAFF = STAFF_BASE; uint16 constant SAPPHIRE_STAFF = STAFF_BASE + 1; uint16 constant EMERALD_STAFF = STAFF_BASE + 2; uint16 constant RUBY_STAFF = STAFF_BASE + 3; uint16 constant AMETHYST_STAFF = STAFF_BASE + 4; uint16 constant DIAMOND_STAFF = STAFF_BASE + 5; uint16 constant DRAGONSTONE_STAFF = STAFF_BASE + 6; uint16 constant STAFF_MAX = STAFF_BASE + 49; // Ranged uint16 constant BOW_BASE = COMBAT_BASE + 100; uint16 constant BOW_MAX = BOW_BASE + 49; // Shields (left arm) uint16 constant SHIELD_BASE = COMBAT_BASE + 150; uint16 constant BRONZE_SHIELD = SHIELD_BASE; uint16 constant IRON_SHIELD = SHIELD_BASE + 1; uint16 constant MITHRIL_SHIELD = SHIELD_BASE + 2; uint16 constant ADAMANTINE_SHIELD = SHIELD_BASE + 3; uint16 constant RUNITE_SHIELD = SHIELD_BASE + 4; uint16 constant TITANIUM_SHIELD = SHIELD_BASE + 5; uint16 constant ORICHALCUM_SHIELD = SHIELD_BASE + 6; uint16 constant SHIELD_MAX = SHIELD_BASE + 49; uint16 constant COMBAT_MAX = COMBAT_BASE + 255; // Mining (2560 - 2815) uint16 constant MINING_BASE = 2560; uint16 constant BRONZE_PICKAXE = MINING_BASE; uint16 constant IRON_PICKAXE = MINING_BASE + 1; uint16 constant MITHRIL_PICKAXE = MINING_BASE + 2; uint16 constant ADAMANTINE_PICKAXE = MINING_BASE + 3; uint16 constant RUNITE_PICKAXE = MINING_BASE + 4; uint16 constant TITANIUM_PICKAXE = MINING_BASE + 5; uint16 constant ORICHALCUM_PICKAXE = MINING_BASE + 6; uint16 constant MINING_MAX = MINING_BASE + 255; // Woodcutting (2816 - 3071) uint16 constant WOODCUTTING_BASE = 2816; uint16 constant BRONZE_AXE = WOODCUTTING_BASE; uint16 constant IRON_AXE = WOODCUTTING_BASE + 1; uint16 constant MITHRIL_AXE = WOODCUTTING_BASE + 2; uint16 constant ADAMANTINE_AXE = WOODCUTTING_BASE + 3; uint16 constant RUNITE_AXE = WOODCUTTING_BASE + 4; uint16 constant TITANIUM_AXE = WOODCUTTING_BASE + 5; uint16 constant ORICHALCUM_AXE = WOODCUTTING_BASE + 6; uint16 constant WOODCUTTING_MAX = WOODCUTTING_BASE + 255; // Fishing (3072 - 3327) uint16 constant FISHING_BASE = 3072; uint16 constant NET_STICK = FISHING_BASE; uint16 constant MEDIUM_NET = FISHING_BASE + 1; uint16 constant WOOD_FISHING_ROD = FISHING_BASE + 2; uint16 constant TITANIUM_FISHING_ROD = FISHING_BASE + 3; uint16 constant HARPOON = FISHING_BASE + 4; uint16 constant LARGE_NET = FISHING_BASE + 5; uint16 constant MAGIC_NET = FISHING_BASE + 6; uint16 constant CAGE = FISHING_BASE + 7; uint16 constant FISHING_MAX = FISHING_BASE + 255; // Firemaking (3328 - 3583) uint16 constant FIRE_BASE = 3328; uint16 constant MAGIC_FIRE_STARTER = FIRE_BASE; uint16 constant FIRE_MAX = FIRE_BASE + 255; // Smithing (none needed) // Crafting (none needed) // Cooking (none needed) // 10000+ it'a all other items // Bars uint16 constant BAR_BASE = 10240; // (256 * 40) uint16 constant BRONZE_BAR = BAR_BASE; uint16 constant IRON_BAR = BAR_BASE + 1; uint16 constant MITHRIL_BAR = BAR_BASE + 2; uint16 constant ADAMANTINE_BAR = BAR_BASE + 3; uint16 constant RUNITE_BAR = BAR_BASE + 4; uint16 constant TITANIUM_BAR = BAR_BASE + 5; uint16 constant ORICHALCUM_BAR = BAR_BASE + 6; uint16 constant BAR_MAX = BAR_BASE + 255; // Logs uint16 constant LOG_BASE = 10496; uint16 constant LOG = LOG_BASE; uint16 constant OAK_LOG = LOG_BASE + 1; uint16 constant WILLOW_LOG = LOG_BASE + 2; uint16 constant MAPLE_LOG = LOG_BASE + 3; uint16 constant REDWOOD_LOG = LOG_BASE + 4; uint16 constant MAGICAL_LOG = LOG_BASE + 5; uint16 constant ASH_LOG = LOG_BASE + 6; uint16 constant ENCHANTED_LOG = LOG_BASE + 7; uint16 constant LIVING_LOG = LOG_BASE + 8; uint16 constant LOG_MAX = LOG_BASE + 255; // Fish uint16 constant RAW_FISH_BASE = 10752; uint16 constant RAW_MINNUS = RAW_FISH_BASE; uint16 constant RAW_BLEKK = RAW_FISH_BASE + 1; uint16 constant RAW_SKRIMP = RAW_FISH_BASE + 2; uint16 constant RAW_FEOLA = RAW_FISH_BASE + 3; uint16 constant RAW_ANCHO = RAW_FISH_BASE + 4; uint16 constant RAW_TROUT = RAW_FISH_BASE + 5; uint16 constant RAW_ROJJA = RAW_FISH_BASE + 6; uint16 constant RAW_BOWFISH = RAW_FISH_BASE + 7; uint16 constant RAW_GOLDFISH = RAW_FISH_BASE + 8; uint16 constant RAW_MYSTY_BLUE = RAW_FISH_BASE + 9; uint16 constant RAW_FLITFISH = RAW_FISH_BASE + 10; uint16 constant RAW_RAZORFISH = RAW_FISH_BASE + 11; uint16 constant RAW_QUAFFER = RAW_FISH_BASE + 12; uint16 constant RAW_ROXA = RAW_FISH_BASE + 13; uint16 constant RAW_AZACUDDA = RAW_FISH_BASE + 14; uint16 constant RAW_STONECLAW = RAW_FISH_BASE + 15; uint16 constant RAW_CRUSKAN = RAW_FISH_BASE + 16; uint16 constant RAW_CHODFISH = RAW_FISH_BASE + 17; uint16 constant RAW_DOUBTFISH = RAW_FISH_BASE + 18; uint16 constant RAW_ROSEFIN = RAW_FISH_BASE + 19; uint16 constant RAW_SPHINX_FISH = RAW_FISH_BASE + 20; uint16 constant RAW_SHAW = RAW_FISH_BASE + 21; uint16 constant RAW_VANISHING_PERCH = RAW_FISH_BASE + 22; uint16 constant RAW_VIPER_BASS = RAW_FISH_BASE + 23; uint16 constant RAW_WATER_SERPENT = RAW_FISH_BASE + 24; uint16 constant RAW_WHISKFIN = RAW_FISH_BASE + 25; uint16 constant RAW_MHARA = RAW_FISH_BASE + 26; uint16 constant RAW_GRAN_SQUIN = RAW_FISH_BASE + 27; uint16 constant RAW_LANCER = RAW_FISH_BASE + 28; uint16 constant RAW_OCTACLE = RAW_FISH_BASE + 29; uint16 constant RAW_DRAGONFISH = RAW_FISH_BASE + 30; uint16 constant RAW_YERESPATUM = RAW_FISH_BASE + 31; uint16 constant RAW_FISH_MAX = RAW_FISH_BASE + 255; // Cooked fish uint16 constant COOKED_FISH_BASE = 11008; uint16 constant COOKED_MINNUS = COOKED_FISH_BASE; uint16 constant COOKED_BLEKK = COOKED_FISH_BASE + 1; uint16 constant COOKED_SKRIMP = COOKED_FISH_BASE + 2; uint16 constant COOKED_FEOLA = COOKED_FISH_BASE + 3; uint16 constant COOKED_ANCHO = COOKED_FISH_BASE + 4; uint16 constant COOKED_TROUT = COOKED_FISH_BASE + 5; uint16 constant COOKED_ROJJA = COOKED_FISH_BASE + 6; uint16 constant COOKED_BOWFISH = COOKED_FISH_BASE + 7; uint16 constant COOKED_GOLDFISH = COOKED_FISH_BASE + 8; uint16 constant COOKED_MYSTY_BLUE = COOKED_FISH_BASE + 9; uint16 constant COOKED_FLITFISH = COOKED_FISH_BASE + 10; uint16 constant COOKED_RAZORFISH = COOKED_FISH_BASE + 11; uint16 constant COOKED_QUAFFER = COOKED_FISH_BASE + 12; uint16 constant COOKED_ROXA = COOKED_FISH_BASE + 13; uint16 constant COOKED_AZACUDDA = COOKED_FISH_BASE + 14; uint16 constant COOKED_STONECLAW = COOKED_FISH_BASE + 15; uint16 constant COOKED_CRUSKAN = COOKED_FISH_BASE + 16; uint16 constant COOKED_CHODFISH = COOKED_FISH_BASE + 17; uint16 constant COOKED_DOUBTFISH = COOKED_FISH_BASE + 18; uint16 constant COOKED_ROSEFIN = COOKED_FISH_BASE + 19; uint16 constant COOKED_SPHINX_FISH = COOKED_FISH_BASE + 20; uint16 constant COOKED_SHAW = COOKED_FISH_BASE + 21; uint16 constant COOKED_VANISHING_PERCH = COOKED_FISH_BASE + 22; uint16 constant COOKED_VIPER_BASS = COOKED_FISH_BASE + 23; uint16 constant COOKED_WATER_SERPENT = COOKED_FISH_BASE + 24; uint16 constant COOKED_WHISKFIN = COOKED_FISH_BASE + 25; uint16 constant COOKED_MHARA = COOKED_FISH_BASE + 26; uint16 constant COOKED_GRAN_SQUIN = COOKED_FISH_BASE + 27; uint16 constant COOKED_LANCER = COOKED_FISH_BASE + 28; uint16 constant COOKED_OCTACLE = COOKED_FISH_BASE + 29; uint16 constant COOKED_DRAGONFISH = COOKED_FISH_BASE + 30; uint16 constant COOKED_YERESPATUM = COOKED_FISH_BASE + 31; uint16 constant COOKED_FISH_MAX = COOKED_FISH_BASE + 255; // Farming uint16 constant FARMING_BASE = 11264; uint16 constant BONEMEAL = FARMING_BASE; uint16 constant FARMING_MAX = FARMING_BASE + 255; // Mining uint16 constant ORE_BASE = 11520; uint16 constant COPPER_ORE = ORE_BASE; uint16 constant TIN_ORE = ORE_BASE + 1; uint16 constant IRON_ORE = ORE_BASE + 2; uint16 constant SAPPHIRE = ORE_BASE + 3; uint16 constant COAL_ORE = ORE_BASE + 4; uint16 constant EMERALD = ORE_BASE + 5; uint16 constant MITHRIL_ORE = ORE_BASE + 6; uint16 constant RUBY = ORE_BASE + 7; uint16 constant ADAMANTINE_ORE = ORE_BASE + 8; uint16 constant AMETHYST = ORE_BASE + 9; uint16 constant DIAMOND = ORE_BASE + 10; uint16 constant RUNITE_ORE = ORE_BASE + 11; uint16 constant DRAGONSTONE = ORE_BASE + 12; uint16 constant TITANIUM_ORE = ORE_BASE + 13; uint16 constant ORICHALCUM_ORE = ORE_BASE + 14; uint16 constant ORE_MAX = ORE_BASE + 255; // Arrows uint16 constant ARROW_BASE = 11776; uint16 constant BRONZE_ARROW = ARROW_BASE; uint16 constant ARROW_MAX = ARROW_BASE + 255; // Scrolls uint16 constant SCROLL_BASE = 12032; uint16 constant SHADOW_SCROLL = SCROLL_BASE; uint16 constant NATURE_SCROLL = SCROLL_BASE + 1; uint16 constant AQUA_SCROLL = SCROLL_BASE + 2; uint16 constant HELL_SCROLL = SCROLL_BASE + 3; uint16 constant AIR_SCROLL = SCROLL_BASE + 4; uint16 constant BARRAGE_SCROLL = SCROLL_BASE + 5; uint16 constant FREEZE_SCROLL = SCROLL_BASE + 6; uint16 constant ANCIENT_SCROLL = SCROLL_BASE + 7; uint16 constant SCROLL_MAX = SCROLL_BASE + 255; // Free interval uint16 constant NOT_USED_BASE = 12544; uint16 constant NOT_USED_MAX = 12799; // Boosts uint16 constant BOOST_BASE = 12800; uint16 constant COMBAT_BOOST = BOOST_BASE; uint16 constant XP_BOOST = BOOST_BASE + 1; uint16 constant GATHERING_BOOST = BOOST_BASE + 2; uint16 constant SKILL_BOOST = BOOST_BASE + 3; uint16 constant ABSENCE_BOOST = BOOST_BASE + 4; uint16 constant PRAY_TO_THE_BEARDIE = BOOST_BASE + 5; uint16 constant GO_OUTSIDE = BOOST_BASE + 6; uint16 constant RAINING_RARES = BOOST_BASE + 7; uint16 constant BOOST_MAX = 13055; // MISC uint16 constant MISC_BASE = 65535; uint16 constant MYSTERY_BOX = MISC_BASE; uint16 constant RAID_PASS = MISC_BASE - 1; uint16 constant NATUOW_HIDE = MISC_BASE - 2; uint16 constant NATUOW_LEATHER = MISC_BASE - 3; uint16 constant SMALL_BONE = MISC_BASE - 4; uint16 constant MEDIUM_BONE = MISC_BASE - 5; uint16 constant LARGE_BONE = MISC_BASE - 6; uint16 constant DRAGON_BONE = MISC_BASE - 7; uint16 constant DRAGON_TEETH = MISC_BASE - 8; uint16 constant DRAGON_SCALE = MISC_BASE - 9; uint16 constant POISON = MISC_BASE - 10; uint16 constant STRING = MISC_BASE - 11; uint16 constant ROPE = MISC_BASE - 12; uint16 constant LEAF_FRAGMENTS = MISC_BASE - 13; uint16 constant VENOM_POUCH = MISC_BASE - 14; uint16 constant BAT_WING = MISC_BASE - 15; uint16 constant BAT_WING_PATCH = MISC_BASE - 16; uint16 constant THREAD_NEEDLE = MISC_BASE - 17; uint16 constant LOSSUTH_TEETH = MISC_BASE - 18; uint16 constant LOSSUTH_SCALE = MISC_BASE - 19; uint16 constant FEATHER = MISC_BASE - 20; uint16 constant QUARTZ_INFUSED_FEATHER = MISC_BASE - 21; uint16 constant BARK_CHUNK = MISC_BASE - 22; uint16 constant APPRENTICE_FABRIC = MISC_BASE - 23; uint16 constant MAGE_FABRIC = MISC_BASE - 24; uint16 constant SORCERER_FABRIC = MISC_BASE - 25; uint16 constant SEERS_FABRIC = MISC_BASE - 26; uint16 constant SHAMAN_FABRIC = MISC_BASE - 27; uint16 constant MASTER_FABRIC = MISC_BASE - 28; uint16 constant DRAGON_KEY = MISC_BASE - 29; uint16 constant BONE_KEY = MISC_BASE - 30; uint16 constant NATURE_KEY = MISC_BASE - 31; uint16 constant AQUA_KEY = MISC_BASE - 32; uint16 constant BLUECANAR = MISC_BASE - 33; uint16 constant ANURGAT = MISC_BASE - 34; uint16 constant RUFARUM = MISC_BASE - 35; uint16 constant WHITE_DEATH_SPORE = MISC_BASE - 36; uint16 constant ENCHANTED_ACORN = MISC_BASE - 37; uint16 constant ACORN_PATCH = MISC_BASE - 38; uint16 constant MISC_MIN = 32768;
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; enum BoostType { NONE, ANY_XP, COMBAT_XP, NON_COMBAT_XP, GATHERING, ABSENCE } struct Equipment { uint16 itemTokenId; uint24 amount; } enum Skill { NONE, COMBAT, // This is a helper which incorporates all combat skills, attack <-> magic, defence, health etc MELEE, RANGE, MAGIC, DEFENCE, HEALTH, RESERVED_COMBAT, MINING, WOODCUTTING, FISHING, SMITHING, THIEVING, CRAFTING, COOKING, FIREMAKING } struct Attire { uint16 head; uint16 neck; uint16 body; uint16 arms; uint16 legs; uint16 feet; uint16 ring; uint16 reserved1; } struct CombatStats { // From skill points int16 melee; int16 magic; int16 range; int16 health; // These include equipment int16 meleeDefence; int16 magicDefence; int16 rangeDefence; } enum CombatStyle { NONE, ATTACK, DEFENCE }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {QueuedAction} from "./actions.sol"; import {Skill, BoostType, CombatStats, Equipment} from "./misc.sol"; // 4 bytes for each level. 0x00000000 is the first level, 0x00000054 is the second, etc. bytes constant XP_BYTES = hex"0000000000000054000000AE0000010E00000176000001E60000025E000002DE00000368000003FD0000049B00000546000005FC000006C000000792000008730000096400000A6600000B7B00000CA400000DE100000F36000010A200001229000013CB0000158B0000176B0000196E00001B9400001DE20000205A000022FF000025D5000028DD00002C1E00002F99000033540000375200003B9A000040300000451900004A5C00004FFF0000560900005C810000637000006ADD000072D100007B570000847900008E42000098BE0000A3F90000B0020000BCE70000CAB80000D9860000E9630000FA6200010C990001201D0001350600014B6F0001637300017D2E000198C10001B64E0001D5F80001F7E600021C430002433B00026CFD000299BE0002C9B30002FD180003342B00036F320003AE730003F23D00043AE3000488BE0004DC2F0005359B000595700005FC2400066A360006E02D00075E990007E6160008774C000912EB0009B9B4000A6C74000B2C06000BF956000CD561000DC134000EBDF3000FCCD40010EF24"; enum EquipPosition { NONE, HEAD, NECK, BODY, ARMS, LEGS, FEET, SPARE1, SPARE2, LEFT_HAND, RIGHT_HAND, BOTH_HANDS, ARROW_SATCHEL, MAGIC_BAG, FOOD, AUX, // wood, seeds etc.. BOOST_VIAL } struct Player { uint40 currentActionStartTime; // The start time of the first queued action Skill currentActionProcessedSkill1; // The skill that the queued action has already gained XP in uint24 currentActionProcessedXPGained1; // The amount of XP that the queued action has already gained Skill currentActionProcessedSkill2; uint24 currentActionProcessedXPGained2; uint16 currentActionProcessedFoodConsumed; uint16 currentActionProcessedBaseInputItemsConsumedNum; // e.g scrolls, crafting materials etc Skill skillBoosted1; // The skill that is boosted Skill skillBoosted2; // The second skill that is boosted uint56 totalXP; Skill currentActionProcessedSkill3; uint24 currentActionProcessedXPGained3; // TODO: Can be up to 7 QueuedAction[] actionQueue; string name; // Raw name } struct Item { EquipPosition equipPosition; bool exists; // Can it be transferred? bool isTransferable; // Food uint16 healthRestored; // Boost vial BoostType boostType; uint16 boostValue; // Varies, could be the % increase uint24 boostDuration; // How long the effect of the boost last // Combat stats int16 melee; int16 magic; int16 range; int16 meleeDefence; int16 magicDefence; int16 rangeDefence; int16 health; // Minimum requirements in this skill to use this item (can be NONE) Skill skill; uint32 minXP; } struct PlayerBoostInfo { uint40 startTime; uint24 duration; uint16 value; uint16 itemTokenId; // Get the effect of it BoostType boostType; } // This is effectively a ratio to produce 1 of outputTokenId. // Fixed based available actions that can be undertaken for an action struct ActionChoice { Skill skill; // Skill that this action choice is related to uint32 minXP; // Min XP in the skill to be able to do this action choice int16 skillDiff; // How much the skill is increased/decreased by this action choice uint24 rate; // Rate of output produced per hour (base 1000) 3 decimals uint24 xpPerHour; uint16 inputTokenId1; uint8 inputAmount1; uint16 inputTokenId2; uint8 inputAmount2; uint16 inputTokenId3; uint8 inputAmount3; uint16 outputTokenId; uint8 outputAmount; uint8 successPercent; // 0-100 } // Must be in the same order as Skill struct PackedXP { uint40 melee; uint40 range; uint40 magic; uint40 defence; uint40 health; uint40 reservedCombat; // Next slot uint40 mining; uint40 woodcutting; uint40 fishing; uint40 smithing; uint40 thieving; uint40 crafting; // Next slot uint40 cooking; uint40 firemaking; } struct AvatarInfo { string name; string description; string imageURI; Skill[2] startSkills; // Can be NONE } struct PastRandomRewardInfo { uint64 queueId; uint16 itemTokenId; uint24 amount; } struct PendingQueuedActionEquipmentState { uint[] consumedItemTokenIds; uint[] consumedAmounts; uint[] producedItemTokenIds; uint[] producedAmounts; } struct PendingQueuedActionMetadata { uint32 xpGained; // total xp gained uint32 rolls; bool died; uint16 actionId; uint64 queueId; uint24 elapsedTime; uint24 xpElapsedTime; } struct PendingQueuedActionData { // The amount of XP that the queued action has already gained Skill skill1; uint24 xpGained1; Skill skill2; // Most likely health uint24 xpGained2; Skill skill3; // Could come uint24 xpGained3; // How much food is consumed in the current action so far uint16 foodConsumed; // How many base consumables are consumed in the current action so far uint16 baseInputItemsConsumedNum; } struct PendingQueuedActionProcessed { // XP gained during this session Skill[] skills; uint32[] xpGainedSkills; // Data for the current action which has been previously processed, this is used to store on the Player PendingQueuedActionData currentAction; } struct QuestState { uint[] consumedItemTokenIds; uint[] consumedAmounts; uint[] rewardItemTokenIds; uint[] rewardAmounts; PlayerQuest[] activeQuestInfo; uint[] questsCompleted; Skill[] skills; // Skills gained XP in uint32[] xpGainedSkills; // XP gained in these skills } struct PendingQueuedActionState { // These 2 are in sync. Separated to reduce gas/deployment costs as these are passed down many layers. PendingQueuedActionEquipmentState[] equipmentStates; PendingQueuedActionMetadata[] actionMetadatas; QueuedAction[] remainingQueuedActions; PendingQueuedActionProcessed processedData; PastRandomRewardInfo[] producedPastRandomRewards; uint[] xpRewardItemTokenIds; uint[] xpRewardAmounts; uint[] dailyRewardItemTokenIds; uint[] dailyRewardAmounts; bytes32 dailyRewardMask; QuestState quests; uint numPastRandomRewardInstancesToRemove; } struct FullAttireBonusInput { Skill skill; uint8 bonusXPPercent; uint8 bonusRewardsPercent; // 3 = 3% uint16[5] itemTokenIds; // 0 = head, 1 = body, 2 arms, 3 body, 4 = feet } struct Quest { uint16 dependentQuestId; // The quest that must be completed before this one can be started uint16 actionId1; // action to do uint16 actionNum1; // how many (up to 65535) uint16 actionId2; // another action to do uint16 actionNum2; // how many (up to 65535) uint16 actionChoiceId; // actionChoice to perform uint16 actionChoiceNum; // how many to do (base number), (up to 65535) Skill skillReward; // The skill to reward XP to uint16 skillXPGained; // The amount of XP to give (up to 65535) uint16 rewardItemTokenId1; // Reward an item uint16 rewardAmount1; // amount of the reward (up to 65535) uint16 rewardItemTokenId2; // Reward another item uint16 rewardAmount2; // amount of the reward (up to 65535) uint16 burnItemTokenId; // Burn an item uint16 burnAmount; // amount of the burn (up to 65535) uint16 questId; // Unique id for this quest bool requireActionsCompletedBeforeBurning; // If true, the player must complete the actions before the item can be burnt } struct PlayerQuest { uint32 questId; uint16 actionCompletedNum1; uint16 actionCompletedNum2; uint16 actionChoiceCompletedNum; uint16 burnCompletedAmount; bool isFixed; } // Contains everything you need to create an item struct InputItem { CombatStats combatStats; uint16 tokenId; EquipPosition equipPosition; // Can it be transferred? bool isTransferable; // Minimum requirements in this skill Skill skill; uint32 minXP; // Food uint16 healthRestored; // Boost BoostType boostType; uint16 boostValue; // Varies, could be the % increase uint24 boostDuration; // How long the effect of the boost vial last // uri string metadataURI; string name; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {BoostType, Equipment} from "./misc.sol"; struct GuaranteedReward { uint16 itemTokenId; uint16 rate; // num per hour, base 10 (1 decimal) } struct RandomReward { uint16 itemTokenId; uint16 chance; // out of 65535 uint8 amount; // out of 255 } struct PendingRandomReward { uint16 actionId; uint40 startTime; uint24 xpElapsedTime; uint64 queueId; BoostType boostType; // Could be removed if necessary, just used as an optimization uint16 boostItemTokenId; uint24 elapsedTime; uint40 boostStartTime; // When the boost was started // Full equipment at the time this was generated uint8 fullAttireBonusRewardsPercent; } struct ActionRewards { uint16 guaranteedRewardTokenId1; uint16 guaranteedRewardRate1; // Num per hour, base 10 (1 decimal). Max 6553.5 per hour uint16 guaranteedRewardTokenId2; uint16 guaranteedRewardRate2; uint16 guaranteedRewardTokenId3; uint16 guaranteedRewardRate3; // Random chance rewards uint16 randomRewardTokenId1; uint16 randomRewardChance1; // out of 65335 uint8 randomRewardAmount1; // out of 255 uint16 randomRewardTokenId2; uint16 randomRewardChance2; uint8 randomRewardAmount2; uint16 randomRewardTokenId3; uint16 randomRewardChance3; uint8 randomRewardAmount3; uint16 randomRewardTokenId4; uint16 randomRewardChance4; uint8 randomRewardAmount4; // No more room! } struct XPThresholdReward { uint32 xpThreshold; Equipment[] rewards; } uint constant MAX_GUARANTEED_REWARDS_PER_ACTION = 3; uint constant MAX_RANDOM_REWARDS_PER_ACTION = 4; uint constant MAX_REWARDS_PER_ACTION = MAX_GUARANTEED_REWARDS_PER_ACTION + MAX_RANDOM_REWARDS_PER_ACTION; uint constant MAX_CONSUMED_PER_ACTION = 3; uint constant MAX_QUEST_REWARDS = 2; // 4 bytes for each threshold, starts at 500 xp in decimal bytes constant xpRewardBytes = hex"00000000000001F4000003E8000009C40000138800002710000075300000C350000186A00001D4C0000493E0000557300007A120000927C0000B71B0";
//SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IBankFactory { function bankAddress(uint clanId) external view returns (address); function createdHere(address bank) external view returns (bool); function createBank(address from, uint clanId) external returns (address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol"; interface IBrushToken is IERC20 { function burn(uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "../globals/misc.sol"; interface IPlayers { function clearEverythingBeforeTokenTransfer(address from, uint tokenId) external; function getURI( uint playerId, string calldata name, string calldata avatarName, string calldata avatarDescription, string calldata imageURI ) external view returns (string memory); function mintedPlayer( address from, uint playerId, Skill[2] calldata startSkills, bool makeActive, uint[] calldata startingItemTokenIds, uint[] calldata startingAmounts ) external; function isOwnerOfPlayerAndActive(address from, uint playerId) external view returns (bool); function activePlayer(address owner) external view returns (uint playerId); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IQuests { function newOracleRandomWords(uint[3] calldata randomWords) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {ERC1155Upgradeable} from "./ozUpgradeable/token/ERC1155/ERC1155Upgradeable.sol"; import {UUPSUpgradeable} from "./ozUpgradeable/proxy/utils/UUPSUpgradeable.sol"; import {OwnableUpgradeable} from "./ozUpgradeable/access/OwnableUpgradeable.sol"; import {IERC2981, IERC165} from "@openzeppelin/contracts/interfaces/IERC2981.sol"; import {UnsafeMath, U256} from "@0xdoublesharp/unsafe-math/contracts/UnsafeMath.sol"; import {ItemNFTLibrary} from "./ItemNFTLibrary.sol"; import {IBrushToken} from "./interfaces/IBrushToken.sol"; import {IPlayers} from "./interfaces/IPlayers.sol"; import {IBankFactory} from "./interfaces/IBankFactory.sol"; import {World} from "./World.sol"; import {AdminAccess} from "./AdminAccess.sol"; // solhint-disable-next-line no-global-import import "./globals/all.sol"; // The NFT contract contains data related to the items and who owns them contract ItemNFT is ERC1155Upgradeable, UUPSUpgradeable, OwnableUpgradeable, IERC2981 { using UnsafeMath for U256; using UnsafeMath for uint256; using UnsafeMath for uint16; event AddItem(Item item, uint16 tokenId, string name); event AddItems(Item[] items, uint16[] tokenIds, string[] names); event EditItem(Item item, uint16 tokenId, string name); event EditItems(Item[] items, uint16[] tokenIds, string[] names); error IdTooHigh(); error ItemNotTransferable(); error InvalidChainId(); error InvalidTokenId(); error ItemAlreadyExists(); error ItemDoesNotExist(uint16); error EquipmentPositionShouldNotChange(); error OnlyForHardhat(); error NotAllowedHardhat(); error ERC1155ReceiverNotApproved(); error NotPlayersOrShop(); error NotAdminAndBeta(); World private world; bool private isBeta; string private baseURI; // How many of this item exist mapping(uint itemId => uint amount) public itemBalances; mapping(uint itemId => uint timestamp) public timestampFirstMint; address private players; address private shop; uint16 public numUniqueItems; // Royalties address private royaltyReceiver; uint8 private royaltyFee; // base 1000, highest is 25.5 mapping(uint itemId => string tokenURI) private tokenURIs; mapping(uint itemId => CombatStats combatStats) private combatStats; mapping(uint itemId => Item item) private items; AdminAccess private adminAccess; IBankFactory private bankFactory; modifier onlyPlayersOrShop() { if (_msgSender() != players && _msgSender() != shop) { revert NotPlayersOrShop(); } _; } modifier isAdminAndBeta() { if (!(adminAccess.isAdmin(_msgSender()) && isBeta)) { revert NotAdminAndBeta(); } _; } /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize( World _world, address _shop, address _royaltyReceiver, AdminAccess _adminAccess, string calldata _baseURI, bool _isBeta ) public initializer { __ERC1155_init(""); __Ownable_init(); __UUPSUpgradeable_init(); world = _world; shop = _shop; baseURI = _baseURI; royaltyFee = 30; // 3% royaltyReceiver = _royaltyReceiver; adminAccess = _adminAccess; isBeta = _isBeta; } // Can't use Item[] array unfortunately as they don't support array casts function mintBatch(address _to, uint[] calldata _ids, uint256[] calldata _amounts) external onlyPlayersOrShop { _mintBatchItems(_to, _ids, _amounts); } function uri(uint256 _tokenId) public view virtual override returns (string memory) { if (!exists(_tokenId)) { revert ItemDoesNotExist(uint16(_tokenId)); } return string(abi.encodePacked(baseURI, tokenURIs[_tokenId])); } function exists(uint _tokenId) public view returns (bool) { return items[_tokenId].exists; } function getItem(uint16 _tokenId) external view returns (Item memory) { return _getItem(_tokenId); } function getEquipPositionAndMinRequirement( uint16 _item ) external view returns (Skill skill, uint32 minXP, EquipPosition equipPosition) { (skill, minXP) = _getMinRequirement(_item); equipPosition = _getEquipPosition(_item); } function getMinRequirements( uint16[] calldata _tokenIds ) external view returns (Skill[] memory skills, uint32[] memory minXPs) { skills = new Skill[](_tokenIds.length); minXPs = new uint32[](_tokenIds.length); U256 tokenIdsLength = _tokenIds.length.asU256(); for (U256 iter; iter < tokenIdsLength; iter = iter.inc()) { uint i = iter.asUint256(); (skills[i], minXPs[i]) = _getMinRequirement(_tokenIds[i]); } } function getItems(uint16[] calldata _tokenIds) external view returns (Item[] memory _items) { U256 tokenIdsLength = _tokenIds.length.asU256(); _items = new Item[](tokenIdsLength.asUint256()); for (U256 iter; iter < tokenIdsLength; iter = iter.inc()) { uint i = iter.asUint256(); _items[i] = _getItem(_tokenIds[i]); } } function getEquipPositions( uint16[] calldata _tokenIds ) external view returns (EquipPosition[] memory equipPositions) { U256 tokenIdsLength = _tokenIds.length.asU256(); equipPositions = new EquipPosition[](tokenIdsLength.asUint256()); for (U256 iter; iter < tokenIdsLength; iter = iter.inc()) { uint i = iter.asUint256(); equipPositions[i] = _getEquipPosition(_tokenIds[i]); } } function _getMinRequirement(uint16 _tokenId) private view returns (Skill, uint32) { return (items[_tokenId].skill, items[_tokenId].minXP); } function _getEquipPosition(uint16 _tokenId) private view returns (EquipPosition) { if (!exists(_tokenId)) { revert ItemDoesNotExist(_tokenId); } return items[_tokenId].equipPosition; } function _premint(uint _tokenId, uint _amount) private returns (uint numNewUniqueItems) { if (_tokenId >= type(uint16).max) { revert IdTooHigh(); } uint existingBalance = itemBalances[_tokenId]; if (existingBalance == 0) { // Brand new item timestampFirstMint[_tokenId] = block.timestamp; numNewUniqueItems = numNewUniqueItems.inc(); } itemBalances[_tokenId] = existingBalance + _amount; } function _mintItem(address _to, uint _tokenId, uint _amount) internal { uint newlyMintedItems = _premint(_tokenId, _amount); if (newlyMintedItems > 0) { numUniqueItems = uint16(numUniqueItems.inc()); } _mint(_to, uint(_tokenId), _amount, ""); } function _mintBatchItems(address _to, uint[] calldata _tokenIds, uint[] calldata _amounts) internal { U256 numNewItems; U256 tokenIdsLength = _tokenIds.length.asU256(); for (U256 iter; iter < tokenIdsLength; iter = iter.inc()) { uint i = iter.asUint256(); numNewItems = numNewItems.add(_premint(_tokenIds[i], _amounts[i])); } if (numNewItems.neq(0)) { numUniqueItems = uint16(numUniqueItems.add(numNewItems.asUint16())); } _mintBatch(_to, _tokenIds, _amounts, ""); } function mint(address _to, uint _tokenId, uint256 _amount) external onlyPlayersOrShop { _mintItem(_to, _tokenId, _amount); } /** * @dev See {IERC1155-balanceOfBatch}. This implementation is not standard ERC1155, it's optimized for the single account case */ function balanceOfs(address _account, uint16[] memory _ids) external view returns (uint256[] memory batchBalances) { U256 iter = _ids.length.asU256(); batchBalances = new uint256[](iter.asUint256()); while (iter.neq(0)) { iter = iter.dec(); uint i = iter.asUint256(); batchBalances[i] = balanceOf(_account, _ids[i]); } } function burnBatch(address _from, uint[] calldata _tokenIds, uint[] calldata _amounts) external { if ( _from != _msgSender() && !isApprovedForAll(_from, _msgSender()) && players != _msgSender() && shop != _msgSender() ) { revert ERC1155ReceiverNotApproved(); } _burnBatch(_from, _tokenIds, _amounts); } function burn(address _from, uint _tokenId, uint _amount) external { if ( _from != _msgSender() && !isApprovedForAll(_from, _msgSender()) && players != _msgSender() && shop != _msgSender() ) { revert ERC1155ReceiverNotApproved(); } _burn(_from, _tokenId, _amount); } function royaltyInfo( uint256 /*_tokenId*/, uint256 _salePrice ) external view override returns (address receiver, uint256 royaltyAmount) { uint256 amount = (_salePrice * royaltyFee) / 1000; return (royaltyReceiver, amount); } function _getItem(uint16 _tokenId) private view returns (Item storage) { if (!exists(_tokenId)) { revert ItemDoesNotExist(_tokenId); } return items[_tokenId]; } // If an item is burnt, remove it from the total function _removeAnyBurntFromTotal(uint[] memory _ids, uint[] memory _amounts) private { U256 iter = _ids.length.asU256(); while (iter.neq(0)) { iter = iter.dec(); uint i = iter.asUint256(); uint newBalance = itemBalances[_ids[i]] - _amounts[i]; if (newBalance == 0) { numUniqueItems = uint16(numUniqueItems.dec()); } itemBalances[_ids[i]] = newBalance; } } function _checkIsTransferable(address _from, uint[] memory _ids) private view { U256 iter = _ids.length.asU256(); bool anyNonTransferable; while (iter.neq(0)) { iter = iter.dec(); uint i = iter.asUint256(); if (exists(_ids[i]) && !items[_ids[i]].isTransferable) { anyNonTransferable = true; } } if (anyNonTransferable && (address(bankFactory) == address(0) || !bankFactory.createdHere(_from))) { // Check if this is from a bank, that's the only place it's allowed to withdraw non-transferable items revert ItemNotTransferable(); } } function _beforeTokenTransfer( address /*_operator*/, address _from, address _to, uint[] memory _ids, uint[] memory _amounts, bytes memory /*_data*/ ) internal virtual override { if (_from == address(0) || _amounts.length == 0 || _from == _to) { // When minting or self sending, then no further processing is required return; } bool isBurnt = _to == address(0) || _to == 0x000000000000000000000000000000000000dEaD; if (isBurnt) { _removeAnyBurntFromTotal(_ids, _amounts); } else { _checkIsTransferable(_from, _ids); } if (players == address(0)) { if (block.chainid != 31337) { revert InvalidChainId(); } } } function _setItem(InputItem calldata _item) private returns (Item storage item) { if (_item.tokenId == 0) { revert InvalidTokenId(); } ItemNFTLibrary.setItem(_item, items[_item.tokenId]); item = items[_item.tokenId]; tokenURIs[_item.tokenId] = _item.metadataURI; } function getBoostInfo(uint16 _tokenId) external view returns (uint16 boostValue, uint24 boostDuration) { Item storage item = _getItem(_tokenId); return (item.boostValue, item.boostDuration); } function supportsInterface(bytes4 interfaceId) public view override(IERC165, ERC1155Upgradeable) returns (bool) { return interfaceId == type(IERC2981).interfaceId || super.supportsInterface(interfaceId); } function name() external view returns (string memory) { return string(abi.encodePacked("Estfor Items", isBeta ? " (Beta)" : "")); } function symbol() external view returns (string memory) { return string(abi.encodePacked("EK_I", isBeta ? "B" : "")); } // Or make it constants and redeploy the contracts function addItem(InputItem calldata _inputItem) external onlyOwner { if (exists(_inputItem.tokenId)) { revert ItemAlreadyExists(); } Item storage item = _setItem(_inputItem); emit AddItem(item, _inputItem.tokenId, _inputItem.name); } function addItems(InputItem[] calldata _inputItems) external onlyOwner { U256 iter = _inputItems.length.asU256(); Item[] memory _items = new Item[](iter.asUint256()); uint16[] memory tokenIds = new uint16[](iter.asUint256()); string[] memory names = new string[](iter.asUint256()); while (iter.neq(0)) { iter = iter.dec(); uint i = iter.asUint256(); if (exists(_inputItems[i].tokenId)) { revert ItemAlreadyExists(); } _items[i] = _setItem(_inputItems[i]); tokenIds[i] = _inputItems[i].tokenId; names[i] = _inputItems[i].name; } emit AddItems(_items, tokenIds, names); } function _editItem(InputItem calldata _inputItem) private returns (Item storage item) { if (!exists(_inputItem.tokenId)) { revert ItemDoesNotExist(_inputItem.tokenId); } if ( items[_inputItem.tokenId].equipPosition != _inputItem.equipPosition && items[_inputItem.tokenId].equipPosition != EquipPosition.NONE ) { revert EquipmentPositionShouldNotChange(); } item = _setItem(_inputItem); } function editItem(InputItem calldata _inputItem) external onlyOwner { Item storage item = _editItem(_inputItem); emit EditItem(item, _inputItem.tokenId, _inputItem.name); } function editItems(InputItem[] calldata _inputItems) external onlyOwner { Item[] memory items = new Item[](_inputItems.length); uint16[] memory tokenIds = new uint16[](_inputItems.length); string[] memory names = new string[](_inputItems.length); for (uint i = 0; i < _inputItems.length; ++i) { items[i] = _editItem(_inputItems[i]); tokenIds[i] = _inputItems[i].tokenId; names[i] = _inputItems[i].name; } emit EditItems(items, tokenIds, names); } function setPlayers(address _players) external onlyOwner { players = _players; } function setBankFactory(IBankFactory _bankFactory) external onlyOwner { bankFactory = _bankFactory; } function setBaseURI(string calldata _baseURI) external onlyOwner { baseURI = _baseURI; } // solhint-disable-next-line no-empty-blocks function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} function testMint(address _to, uint _tokenId, uint _amount) external isAdminAndBeta { _mintItem(_to, _tokenId, _amount); } function testMints(address _to, uint[] calldata _tokenIds, uint[] calldata _amounts) external isAdminAndBeta { _mintBatchItems(_to, _tokenIds, _amounts); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; // solhint-disable-next-line no-global-import import "./globals/players.sol"; // This file contains methods for interacting with the item NFT, used to decrease implementation deployment bytecode code. library ItemNFTLibrary { function setItem(InputItem calldata _inputItem, Item storage _item) external { bool hasCombat; CombatStats calldata _combatStats = _inputItem.combatStats; assembly ("memory-safe") { hasCombat := not(iszero(_combatStats)) } _item.equipPosition = _inputItem.equipPosition; _item.isTransferable = _inputItem.isTransferable; _item.exists = true; if (hasCombat) { // Combat stats _item.melee = _inputItem.combatStats.melee; _item.magic = _inputItem.combatStats.magic; _item.range = _inputItem.combatStats.range; _item.meleeDefence = _inputItem.combatStats.meleeDefence; _item.magicDefence = _inputItem.combatStats.magicDefence; _item.rangeDefence = _inputItem.combatStats.rangeDefence; _item.health = _inputItem.combatStats.health; } if (_inputItem.healthRestored != 0) { _item.healthRestored = _inputItem.healthRestored; } if (_inputItem.boostType != BoostType.NONE) { _item.boostType = _inputItem.boostType; _item.boostValue = _inputItem.boostValue; _item.boostDuration = _inputItem.boostDuration; } _item.minXP = _inputItem.minXP; _item.skill = _inputItem.skill; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); error CallerIsNotOwner(); error NewOwnerIsZeroAddress(); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert CallerIsNotOwner(); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { if (newOwner == address(0)) { revert NewOwnerIsZeroAddress(); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/ERC1967/ERC1967Upgrade.sol) pragma solidity ^0.8.20; import "@openzeppelin/contracts-upgradeable/proxy/beacon/IBeaconUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/StorageSlotUpgradeable.sol"; import "../utils/Initializable.sol"; /** * @dev This abstract contract provides getters and event emitting update functions for * https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots. * * _Available since v4.1._ * * @custom:oz-upgrades-unsafe-allow delegatecall */ abstract contract ERC1967UpgradeUpgradeable is Initializable { error NewImplementationIsNotAContract(); error NewImplementationNotUUPS(); error UnsupportedProxiableUUID(); error NewAdminIsZeroAddress(); error NewBeaconIsNotAContract(); error BeaconImplementationIsNotAContract(); error AddressIsNotContract(); function __ERC1967Upgrade_init() internal onlyInitializing {} function __ERC1967Upgrade_init_unchained() internal onlyInitializing {} // This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1 bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143; /** * @dev Storage slot with the address of the current implementation. * This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc; /** * @dev Emitted when the implementation is upgraded. */ event Upgraded(address indexed implementation); /** * @dev Returns the current implementation address. */ function _getImplementation() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value; } /** * @dev Stores a new address in the EIP1967 implementation slot. */ function _setImplementation(address newImplementation) private { if (!AddressUpgradeable.isContract(newImplementation)) { revert NewImplementationIsNotAContract(); } StorageSlotUpgradeable.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation; } /** * @dev Perform implementation upgrade * * Emits an {Upgraded} event. */ function _upgradeTo(address newImplementation) internal { _setImplementation(newImplementation); emit Upgraded(newImplementation); } /** * @dev Perform implementation upgrade with additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCall(address newImplementation, bytes memory data, bool forceCall) internal { _upgradeTo(newImplementation); if (data.length > 0 || forceCall) { _functionDelegateCall(newImplementation, data); } } /** * @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call. * * Emits an {Upgraded} event. */ function _upgradeToAndCallUUPS(address newImplementation, bytes memory data, bool forceCall) internal { // Upgrades from old implementations will perform a rollback test. This test requires the new // implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing // this special case will break upgrade paths from old UUPS implementation to new ones. if (StorageSlotUpgradeable.getBooleanSlot(_ROLLBACK_SLOT).value) { _setImplementation(newImplementation); } else { try IERC1822ProxiableUpgradeable(newImplementation).proxiableUUID() returns (bytes32 slot) { if (slot != _IMPLEMENTATION_SLOT) { revert UnsupportedProxiableUUID(); } } catch { revert NewImplementationNotUUPS(); } _upgradeToAndCall(newImplementation, data, forceCall); } } /** * @dev Storage slot with the admin of the contract. * This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is * validated in the constructor. */ bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103; /** * @dev Emitted when the admin account has changed. */ event AdminChanged(address previousAdmin, address newAdmin); /** * @dev Returns the current admin. */ function _getAdmin() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value; } /** * @dev Stores a new address in the EIP1967 admin slot. */ function _setAdmin(address newAdmin) private { if (newAdmin == address(0)) { revert NewAdminIsZeroAddress(); } StorageSlotUpgradeable.getAddressSlot(_ADMIN_SLOT).value = newAdmin; } /** * @dev Changes the admin of the proxy. * * Emits an {AdminChanged} event. */ function _changeAdmin(address newAdmin) internal { emit AdminChanged(_getAdmin(), newAdmin); _setAdmin(newAdmin); } /** * @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy. * This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor. */ bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50; /** * @dev Emitted when the beacon is upgraded. */ event BeaconUpgraded(address indexed beacon); /** * @dev Returns the current beacon. */ function _getBeacon() internal view returns (address) { return StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value; } /** * @dev Stores a new beacon in the EIP1967 beacon slot. */ function _setBeacon(address newBeacon) private { if (!AddressUpgradeable.isContract(newBeacon)) { revert NewBeaconIsNotAContract(); } if (!AddressUpgradeable.isContract(IBeaconUpgradeable(newBeacon).implementation())) { revert BeaconImplementationIsNotAContract(); } StorageSlotUpgradeable.getAddressSlot(_BEACON_SLOT).value = newBeacon; } /** * @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does * not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that). * * Emits a {BeaconUpgraded} event. */ function _upgradeBeaconToAndCall(address newBeacon, bytes memory data, bool forceCall) internal { _setBeacon(newBeacon); emit BeaconUpgraded(newBeacon); if (data.length > 0 || forceCall) { _functionDelegateCall(IBeaconUpgradeable(newBeacon).implementation(), data); } } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function _functionDelegateCall(address target, bytes memory data) private returns (bytes memory) { if (!AddressUpgradeable.isContract(target)) { revert AddressIsNotContract(); } // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return AddressUpgradeable.verifyCallResult(success, returndata, "Address: low-level delegate call failed"); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol) pragma solidity ^0.8.20; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in * case an upgrade adds a module that needs to be initialized. * * For example: * * [.hljs-theme-light.nopadding] * ``` * contract MyToken is ERC20Upgradeable { * function initialize() initializer public { * __ERC20_init("MyToken", "MTK"); * } * } * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable { * function initializeV2() reinitializer(2) public { * __ERC20Permit_init("MyToken"); * } * } * ``` * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() { * _disableInitializers(); * } * ``` * ==== */ abstract contract Initializable { error NotInitializing(); error IsInitializing(); error AlreadyInitialized(); /** * @dev Indicates that the contract has been initialized. * @custom:oz-retyped-from bool */ uint8 private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Triggered when the contract has been initialized or reinitialized. */ event Initialized(uint8 version); /** * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope, * `onlyInitializing` functions can be used to initialize parent contracts. * * Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a * constructor. * * Emits an {Initialized} event. */ modifier initializer() { bool isTopLevelCall = !_initializing; if ( !((isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1)) ) { revert AlreadyInitialized(); } _initialized = 1; if (isTopLevelCall) { _initializing = true; } _; if (isTopLevelCall) { _initializing = false; emit Initialized(1); } } /** * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be * used to initialize parent contracts. * * A reinitializer may be used after the original initialization step. This is essential to configure modules that * are added through upgrades and that require initialization. * * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer` * cannot be nested. If one is invoked in the context of another, execution will revert. * * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in * a contract, executing them in the right order is up to the developer or operator. * * WARNING: setting the version to 255 will prevent any future reinitialization. * * Emits an {Initialized} event. */ modifier reinitializer(uint8 version) { if (!(!_initializing && _initialized < version)) { revert AlreadyInitialized(); } _initialized = version; _initializing = true; _; _initializing = false; emit Initialized(version); } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} and {reinitializer} modifiers, directly or indirectly. */ modifier onlyInitializing() { if (!_initializing) { revert NotInitializing(); } _; } /** * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call. * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized * to any version. It is recommended to use this to lock implementation contracts that are designed to be called * through proxies. * * Emits an {Initialized} event the first time it is successfully executed. */ function _disableInitializers() internal virtual { if (_initializing) { revert IsInitializing(); } if (_initialized < type(uint8).max) { _initialized = type(uint8).max; emit Initialized(type(uint8).max); } } /** * @dev Returns the highest version that has been initialized. See {reinitializer}. */ function _getInitializedVersion() internal view returns (uint8) { return _initialized; } /** * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}. */ function _isInitializing() internal view returns (bool) { return _initializing; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (proxy/utils/UUPSUpgradeable.sol) pragma solidity ^0.8.20; import {IERC1822ProxiableUpgradeable} from "@openzeppelin/contracts-upgradeable/interfaces/draft-IERC1822Upgradeable.sol"; import {ERC1967UpgradeUpgradeable} from "../ERC1967/ERC1967UpgradeUpgradeable.sol"; import "./Initializable.sol"; /** * @dev An upgradeability mechanism designed for UUPS proxies. The functions included here can perform an upgrade of an * {ERC1967Proxy}, when this contract is set as the implementation behind such a proxy. * * A security mechanism ensures that an upgrade does not turn off upgradeability accidentally, although this risk is * reinstated if the upgrade retains upgradeability but removes the security mechanism, e.g. by replacing * `UUPSUpgradeable` with a custom implementation of upgrades. * * The {_authorizeUpgrade} function must be overridden to include access restriction to the upgrade mechanism. * * _Available since v4.1._ */ abstract contract UUPSUpgradeable is Initializable, IERC1822ProxiableUpgradeable, ERC1967UpgradeUpgradeable { error FunctionMustBeCalledThroughDelegateCall(); error FunctionMustBeCalledThroughActiveProxy(); error FunctionMustNotBeCalledThroughDelegateCall(); function __UUPSUpgradeable_init() internal onlyInitializing {} function __UUPSUpgradeable_init_unchained() internal onlyInitializing {} /// @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment address private immutable __self = address(this); /** * @dev Check that the execution is being performed through a delegatecall call and that the execution context is * a proxy contract with an implementation (as defined in ERC1967) pointing to self. This should only be the case * for UUPS and transparent proxies that are using the current contract as their implementation. Execution of a * function through ERC1167 minimal proxies (clones) would not normally pass this test, but is not guaranteed to * fail. */ modifier onlyProxy() { if (address(this) == __self) { revert FunctionMustBeCalledThroughDelegateCall(); } if (_getImplementation() != __self) { revert FunctionMustBeCalledThroughActiveProxy(); } _; } /** * @dev Check that the execution is not being performed through a delegate call. This allows a function to be * callable on the implementing contract but not through proxies. */ modifier notDelegated() { if (address(this) != __self) { revert FunctionMustNotBeCalledThroughDelegateCall(); } _; } /** * @dev Implementation of the ERC1822 {proxiableUUID} function. This returns the storage slot used by the * implementation. It is used to validate the implementation's compatibility when performing an upgrade. * * IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks * bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this * function revert if invoked through a proxy. This is guaranteed by the `notDelegated` modifier. */ function proxiableUUID() external view virtual override notDelegated returns (bytes32) { return _IMPLEMENTATION_SLOT; } /** * @dev Upgrade the implementation of the proxy to `newImplementation`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeTo(address newImplementation) external virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, new bytes(0), false); } /** * @dev Upgrade the implementation of the proxy to `newImplementation`, and subsequently execute the function call * encoded in `data`. * * Calls {_authorizeUpgrade}. * * Emits an {Upgraded} event. */ function upgradeToAndCall(address newImplementation, bytes memory data) external payable virtual onlyProxy { _authorizeUpgrade(newImplementation); _upgradeToAndCallUUPS(newImplementation, data, true); } /** * @dev Function that should revert when `msg.sender` is not authorized to upgrade the contract. Called by * {upgradeTo} and {upgradeToAndCall}. * * Normally, this function will use an xref:access.adoc[access control] modifier such as {Ownable-onlyOwner}. * * ```solidity * function _authorizeUpgrade(address) internal override onlyOwner {} * ``` */ function _authorizeUpgrade(address newImplementation) internal virtual; /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (token/ERC1155/ERC1155.sol) pragma solidity ^0.8.20; import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155ReceiverUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC1155/extensions/IERC1155MetadataURIUpgradeable.sol"; import "../../utils/AddressUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import "../../proxy/utils/Initializable.sol"; import "../../utils/introspection/ERC165Upgradeable.sol"; /** * @dev Implementation of the basic standard multi-token. * See https://eips.ethereum.org/EIPS/eip-1155 * Originally based on code by Enjin: https://github.com/enjin/erc-1155 * * _Available since v3.1._ */ contract ERC1155Upgradeable is Initializable, ContextUpgradeable, ERC165Upgradeable, IERC1155Upgradeable, IERC1155MetadataURIUpgradeable { using AddressUpgradeable for address; error ERC1155TransferToNonERC1155Receiver(); error ERC1155ReceiverRejectedTokens(); error ERC1155SettingApprovalStatusForSelf(); error ERC115BurnFromZeroAddress(); error ERC1155LengthMismatch(); error ERC115BurnAmountExceedsBalance(); error ERC1155MintToZeroAddress(); error ERC1155TransferToZeroAddress(); error ERC1155InsufficientBalance(); error ERC1155TransferFromNotApproved(); error ERC1155ZeroAddressNotValidOwner(); // Mapping from token ID to account balances mapping(uint256 => mapping(address => uint256)) private _balances; // Mapping from account to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json string private _uri; /** * @dev See {_setURI}. */ function __ERC1155_init(string memory uri_) internal onlyInitializing { __ERC1155_init_unchained(uri_); } function __ERC1155_init_unchained(string memory uri_) internal onlyInitializing { _setURI(uri_); } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface( bytes4 interfaceId ) public view virtual override(ERC165Upgradeable, IERC165Upgradeable) returns (bool) { return interfaceId == type(IERC1155Upgradeable).interfaceId || interfaceId == type(IERC1155MetadataURIUpgradeable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC1155MetadataURI-uri}. * * This implementation returns the same URI for *all* token types. It relies * on the token type ID substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * Clients calling this function must replace the `\{id\}` substring with the * actual token type ID. */ function uri(uint256) public view virtual override returns (string memory) { return _uri; } /** * @dev See {IERC1155-balanceOf}. * * Requirements: * * - `account` cannot be the zero address. */ function balanceOf(address account, uint256 id) public view virtual override returns (uint256) { if (account == address(0)) { revert ERC1155ZeroAddressNotValidOwner(); } return _balances[id][account]; } /** * @dev See {IERC1155-balanceOfBatch}. * * Requirements: * * - `accounts` and `ids` must have the same length. */ function balanceOfBatch( address[] memory accounts, uint256[] memory ids ) public view virtual override returns (uint256[] memory) { if (accounts.length != ids.length) { revert ERC1155LengthMismatch(); } uint256[] memory batchBalances = new uint256[](accounts.length); for (uint256 i = 0; i < accounts.length; ++i) { batchBalances[i] = balanceOf(accounts[i], ids[i]); } return batchBalances; } /** * @dev See {IERC1155-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { _setApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC1155-isApprovedForAll}. */ function isApprovedForAll(address account, address operator) public view virtual override returns (bool) { return _operatorApprovals[account][operator]; } /** * @dev See {IERC1155-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) public virtual override { if (from != _msgSender() && !isApprovedForAll(from, _msgSender())) { revert ERC1155TransferFromNotApproved(); } _safeTransferFrom(from, to, id, amount, data); } /** * @dev See {IERC1155-safeBatchTransferFrom}. */ function safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public virtual override { if (from != _msgSender() && !isApprovedForAll(from, _msgSender())) { revert ERC1155TransferFromNotApproved(); } _safeBatchTransferFrom(from, to, ids, amounts, data); } /** * @dev Transfers `amount` tokens of token type `id` from `from` to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - `from` must have a balance of tokens of type `id` of at least `amount`. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _safeTransferFrom(address from, address to, uint256 id, uint256 amount, bytes memory data) internal virtual { if (to == address(0)) { revert ERC1155TransferToZeroAddress(); } address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, from, to, ids, amounts, data); uint256 fromBalance = _balances[id][from]; if (fromBalance < amount) { revert ERC1155InsufficientBalance(); } unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; emit TransferSingle(operator, from, to, id, amount); _afterTokenTransfer(operator, from, to, ids, amounts, data); _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}. * * Emits a {TransferBatch} event. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual { if (ids.length != amounts.length) { revert ERC1155LengthMismatch(); } if (to == address(0)) { revert ERC1155TransferToZeroAddress(); } address operator = _msgSender(); _beforeTokenTransfer(operator, from, to, ids, amounts, data); for (uint256 i = 0; i < ids.length; ++i) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; if (fromBalance < amount) { revert ERC1155InsufficientBalance(); } unchecked { _balances[id][from] = fromBalance - amount; } _balances[id][to] += amount; } emit TransferBatch(operator, from, to, ids, amounts); _afterTokenTransfer(operator, from, to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data); } /** * @dev Sets a new URI for all token types, by relying on the token type ID * substitution mechanism * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP]. * * By this mechanism, any occurrence of the `\{id\}` substring in either the * URI or any of the amounts in the JSON file at said URI will be replaced by * clients with the token type ID. * * For example, the `https://token-cdn-domain/\{id\}.json` URI would be * interpreted by clients as * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json` * for token type ID 0x4cce0. * * See {uri}. * * Because these URIs cannot be meaningfully represented by the {URI} event, * this function emits no events. */ function _setURI(string memory newuri) internal virtual { _uri = newuri; } /** * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`. * * Emits a {TransferSingle} event. * * Requirements: * * - `to` cannot be the zero address. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the * acceptance magic value. */ function _mint(address to, uint256 id, uint256 amount, bytes memory data) internal virtual { if (to == address(0)) { revert ERC1155MintToZeroAddress(); } address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); _balances[id][to] += amount; emit TransferSingle(operator, address(0), to, id, amount); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the * acceptance magic value. */ function _mintBatch(address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data) internal virtual { if (to == address(0)) { revert ERC1155MintToZeroAddress(); } if (ids.length != amounts.length) { revert ERC1155LengthMismatch(); } address operator = _msgSender(); _beforeTokenTransfer(operator, address(0), to, ids, amounts, data); for (uint256 i = 0; i < ids.length; i++) { _balances[ids[i]][to] += amounts[i]; } emit TransferBatch(operator, address(0), to, ids, amounts); _afterTokenTransfer(operator, address(0), to, ids, amounts, data); _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data); } /** * @dev Destroys `amount` tokens of token type `id` from `from` * * Emits a {TransferSingle} event. * * Requirements: * * - `from` cannot be the zero address. * - `from` must have at least `amount` tokens of token type `id`. */ function _burn(address from, uint256 id, uint256 amount) internal virtual { if (from == address(0)) { revert ERC115BurnFromZeroAddress(); } address operator = _msgSender(); uint256[] memory ids = _asSingletonArray(id); uint256[] memory amounts = _asSingletonArray(amount); _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); uint256 fromBalance = _balances[id][from]; if (fromBalance < amount) { revert ERC115BurnAmountExceedsBalance(); } unchecked { _balances[id][from] = fromBalance - amount; } emit TransferSingle(operator, from, address(0), id, amount); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}. * * Emits a {TransferBatch} event. * * Requirements: * * - `ids` and `amounts` must have the same length. */ function _burnBatch(address from, uint256[] memory ids, uint256[] memory amounts) internal virtual { if (from == address(0)) { revert ERC115BurnFromZeroAddress(); } if (ids.length != amounts.length) { revert ERC1155LengthMismatch(); } address operator = _msgSender(); _beforeTokenTransfer(operator, from, address(0), ids, amounts, ""); for (uint256 i = 0; i < ids.length; i++) { uint256 id = ids[i]; uint256 amount = amounts[i]; uint256 fromBalance = _balances[id][from]; if (fromBalance < amount) { revert ERC115BurnAmountExceedsBalance(); } unchecked { _balances[id][from] = fromBalance - amount; } } emit TransferBatch(operator, from, address(0), ids, amounts); _afterTokenTransfer(operator, from, address(0), ids, amounts, ""); } /** * @dev Approve `operator` to operate on all of `owner` tokens * * Emits an {ApprovalForAll} event. */ function _setApprovalForAll(address owner, address operator, bool approved) internal virtual { if (owner == operator) { revert ERC1155SettingApprovalStatusForSelf(); } _operatorApprovals[owner][operator] = approved; emit ApprovalForAll(owner, operator, approved); } /** * @dev Hook that is called before any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `ids` and `amounts` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} /** * @dev Hook that is called after any token transfer. This includes minting * and burning, as well as batched variants. * * The same hook is called on both single and batched variants. For single * transfers, the length of the `id` and `amount` arrays will be 1. * * Calling conditions (for each `id` and `amount` pair): * * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens * of token type `id` will be transferred to `to`. * - When `from` is zero, `amount` tokens of token type `id` will be minted * for `to`. * - when `to` is zero, `amount` of ``from``'s tokens of token type `id` * will be burned. * - `from` and `to` are never both zero. * - `ids` and `amounts` have the same, non-zero length. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal virtual {} function _doSafeTransferAcceptanceCheck( address operator, address from, address to, uint256 id, uint256 amount, bytes memory data ) private { if (to.isContract()) { try IERC1155ReceiverUpgradeable(to).onERC1155Received(operator, from, id, amount, data) returns ( bytes4 response ) { if (response != IERC1155ReceiverUpgradeable.onERC1155Received.selector) { revert ERC1155ReceiverRejectedTokens(); } } catch Error(string memory reason) { revert(reason); } catch { revert ERC1155TransferToNonERC1155Receiver(); } } } function _doSafeBatchTransferAcceptanceCheck( address operator, address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) private { if (to.isContract()) { try IERC1155ReceiverUpgradeable(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns ( bytes4 response ) { if (response != IERC1155ReceiverUpgradeable.onERC1155BatchReceived.selector) { revert ERC1155ReceiverRejectedTokens(); } } catch Error(string memory reason) { revert(reason); } catch { revert ERC1155TransferToNonERC1155Receiver(); } } } function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) { uint256[] memory array = new uint256[](1); array[0] = element; return array; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[47] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { error RecipientMayHaveReverted(); error CallToNonContract(); error InsufficientAllowance(); error InsufficientBalance(); /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert InsufficientBalance(); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert RecipientMayHaveReverted(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { if (address(this).balance < value) { revert InsufficientAllowance(); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (!isContract(target)) { revert CallToNonContract(); } } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.20; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing {} function __Context_init_unchained() internal onlyInitializing {} function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/utils/introspection/IERC165Upgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165Upgradeable is Initializable, IERC165Upgradeable { function __ERC165_init() internal onlyInitializing {} function __ERC165_init_unchained() internal onlyInitializing {} /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165Upgradeable).interfaceId; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {Initializable} from "./ozUpgradeable/proxy/utils/Initializable.sol"; /** **************************************************************************** * @notice Interface for contracts using VRF randomness * ***************************************************************************** * @dev PURPOSE * * @dev Reggie the Random Oracle (not his real job) wants to provide randomness * @dev to Vera the verifier in such a way that Vera can be sure he's not * @dev making his output up to suit himself. Reggie provides Vera a public key * @dev to which he knows the secret key. Each time Vera provides a seed to * @dev Reggie, he gives back a value which is computed completely * @dev deterministically from the seed and the secret key. * * @dev Reggie provides a proof by which Vera can verify that the output was * @dev correctly computed once Reggie tells it to her, but without that proof, * @dev the output is indistinguishable to her from a uniform random sample * @dev from the output space. * * @dev The purpose of this contract is to make it easy for unrelated contracts * @dev to talk to Vera the verifier about the work Reggie is doing, to provide * @dev simple access to a verifiable source of randomness. It ensures 2 things: * @dev 1. The fulfillment came from the VRFCoordinator * @dev 2. The consumer contract implements fulfillRandomWords. * ***************************************************************************** * @dev USAGE * * @dev Calling contracts must inherit from VRFConsumerBase, and can * @dev initialize VRFConsumerBase's attributes in their constructor as * @dev shown: * * @dev contract VRFConsumer { * @dev constructor(<other arguments>, address _vrfCoordinator, address _link) * @dev VRFConsumerBase(_vrfCoordinator) public { * @dev <initialization with other arguments goes here> * @dev } * @dev } * * @dev The oracle will have given you an ID for the VRF keypair they have * @dev committed to (let's call it keyHash). Create subscription, fund it * @dev and your consumer contract as a consumer of it (see VRFCoordinatorInterface * @dev subscription management functions). * @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations, * @dev callbackGasLimit, numWords), * @dev see (VRFCoordinatorInterface for a description of the arguments). * * @dev Once the VRFCoordinator has received and validated the oracle's response * @dev to your request, it will call your contract's fulfillRandomWords method. * * @dev The randomness argument to fulfillRandomWords is a set of random words * @dev generated from your requestId and the blockHash of the request. * * @dev If your contract could have concurrent requests open, you can use the * @dev requestId returned from requestRandomWords to track which response is associated * @dev with which randomness request. * @dev See "SECURITY CONSIDERATIONS" for principles to keep in mind, * @dev if your contract could have multiple requests in flight simultaneously. * * @dev Colliding `requestId`s are cryptographically impossible as long as seeds * @dev differ. * * ***************************************************************************** * @dev SECURITY CONSIDERATIONS * * @dev A method with the ability to call your fulfillRandomness method directly * @dev could spoof a VRF response with any random value, so it's critical that * @dev it cannot be directly called by anything other than this base contract * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method). * * @dev For your users to trust that your contract's random behavior is free * @dev from malicious interference, it's best if you can write it so that all * @dev behaviors implied by a VRF response are executed *during* your * @dev fulfillRandomness method. If your contract must store the response (or * @dev anything derived from it) and use it later, you must ensure that any * @dev user-significant behavior which depends on that stored value cannot be * @dev manipulated by a subsequent VRF request. * * @dev Similarly, both miners and the VRF oracle itself have some influence * @dev over the order in which VRF responses appear on the blockchain, so if * @dev your contract could have multiple VRF requests in flight simultaneously, * @dev you must ensure that the order in which the VRF responses arrive cannot * @dev be used to manipulate your contract's user-significant behavior. * * @dev Since the block hash of the block which contains the requestRandomness * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful * @dev miner could, in principle, fork the blockchain to evict the block * @dev containing the request, forcing the request to be included in a * @dev different block with a different hash, and therefore a different input * @dev to the VRF. However, such an attack would incur a substantial economic * @dev cost. This cost scales with the number of blocks the VRF oracle waits * @dev until it calls responds to a request. It is for this reason that * @dev that you can signal to an oracle you'd like them to wait longer before * @dev responding to the request (however this is not enforced in the contract * @dev and so remains effective only in the case of unmodified oracle software). */ abstract contract VRFConsumerBaseV2Upgradeable is Initializable { error OnlyCoordinatorCanFulfill(address have, address want); address private vrfCoordinator; /** * @dev Initializes the contract setting the deployer as the initial owner. */ // solhint-disable-next-line func-name-mixedcase function __VRFConsumerBaseV2_init(address _vrfCoordinator) internal onlyInitializing { vrfCoordinator = _vrfCoordinator; } /** * @notice fulfillRandomness handles the VRF response. Your contract must * @notice implement it. See "SECURITY CONSIDERATIONS" above for important * @notice principles to keep in mind when implementing your fulfillRandomness * @notice method. * * @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this * @dev signature, and will call it once it has verified the proof * @dev associated with the randomness. (It is triggered via a call to * @dev rawFulfillRandomness, below.) * * @param requestId The Id initially returned by requestRandomness * @param randomWords the VRF output expanded to the requested number of words */ function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual; // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF // proof. rawFulfillRandomness then calls fulfillRandomness, after validating // the origin of the call function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external { if (msg.sender != vrfCoordinator) { revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator); } fulfillRandomWords(requestId, randomWords); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {VRFCoordinatorV2Interface} from "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol"; import {UUPSUpgradeable} from "./ozUpgradeable/proxy/utils/UUPSUpgradeable.sol"; import {OwnableUpgradeable} from "./ozUpgradeable/access/OwnableUpgradeable.sol"; import {UnsafeMath, U256} from "@0xdoublesharp/unsafe-math/contracts/UnsafeMath.sol"; import {VRFConsumerBaseV2Upgradeable} from "./VRFConsumerBaseV2Upgradeable.sol"; import {WorldLibrary} from "./WorldLibrary.sol"; import {IQuests} from "./interfaces/IQuests.sol"; // solhint-disable-next-line no-global-import import "./globals/all.sol"; contract World is VRFConsumerBaseV2Upgradeable, UUPSUpgradeable, OwnableUpgradeable { using UnsafeMath for U256; using UnsafeMath for uint256; event RequestSent(uint requestId, uint32 numWords, uint lastRandomWordsUpdatedTime); event RequestFulfilled(uint requestId, uint[3] randomWords); event AddAction(Action action); event AddActions(Action[] actions); event EditActions(Action[] actions); event SetAvailableAction(uint16 actionId, bool available); event AddDynamicActions(uint16[] actionIds); event RemoveDynamicActions(uint16[] actionIds); event AddActionChoice(uint16 actionId, uint16 actionChoiceId, ActionChoice choice); event AddActionChoices(uint16 actionId, uint16[] actionChoiceIds, ActionChoice[] choices); event EditActionChoice(uint16 actionId, uint16 actionChoiceId, ActionChoice choice); event EditActionChoices(uint16[] actionIds, uint16[] actionChoiceIds, ActionChoice[] choices); event NewDailyRewards(Equipment[8] dailyRewards); error RandomWordsCannotBeUpdatedYet(); error CanOnlyRequestAfterTheNextCheckpoint(uint256 currentTime, uint256 checkpoint); error RequestAlreadyFulfilled(); error NoValidRandomWord(); error CanOnlyRequestAfter1DayHasPassed(); error ActionIdZeroNotAllowed(); error MinCannotBeGreaterThanMax(); error DynamicActionsCannotBeAdded(); error ActionAlreadyExists(); error ActionDoesNotExist(); error ActionChoiceIdZeroNotAllowed(); error DynamicActionsCannotBeSet(); error LengthMismatch(); error NoActionChoices(); error ActionChoiceAlreadyExists(); error ActionChoiceDoesNotExist(); error OnlyCombatMultipleGuaranteedRewards(); error NotAFactorOf3600(); error NonCombatCannotHaveBothGuaranteedAndRandomRewards(); // solhint-disable-next-line var-name-mixedcase VRFCoordinatorV2Interface public COORDINATOR; // Your subscription ID. uint64 public subscriptionId; // Past request ids uint[] public requestIds; // Each one is a set of random words for 1 day mapping(uint requestId => uint[3] randomWord) public randomWords; uint40 public lastRandomWordsUpdatedTime; uint40 public startTime; uint40 public weeklyRewardCheckpoint; // The gas lane to use, which specifies the maximum gas price to bump to. // For a list of available gas lanes on each network, this is 10000gwei // see https://docs.chain.link/docs/vrf/v2/subscription/supported-networks/#configurations bytes32 public constant KEY_HASH = 0x5881eea62f9876043df723cf89f0c2bb6f950da25e9dfe66995c24f919c8f8ab; uint32 public constant CALLBACK_GAS_LIMIT = 500000; // The default is 3, but you can set this higher. uint16 public constant REQUEST_CONFIRMATIONS = 1; // For this example, retrieve 3 random values in one request. // Cannot exceed VRFCoordinatorV2.MAX_NUM_WORDS. uint32 public constant NUM_WORDS = 3; uint32 public constant MIN_RANDOM_WORDS_UPDATE_TIME = 1 days; uint32 public constant MIN_DYNAMIC_ACTION_UPDATE_TIME = 1 days; mapping(uint actionId => ActionInfo actionInfo) public actions; uint16[] private lastAddedDynamicActions; uint public lastDynamicUpdatedTime; bytes32 public dailyRewards; // Effectively stores Equipment[8] which is packed, first 7 are daily, last one is weekly reward mapping(uint actionId => mapping(uint16 choiceId => ActionChoice actionChoice)) private actionChoices; mapping(uint actionId => CombatStats combatStats) private actionCombatStats; mapping(uint actionId => ActionRewards actionRewards) private actionRewards; IQuests private quests; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize(VRFCoordinatorV2Interface _coordinator, uint64 _subscriptionId) public initializer { __VRFConsumerBaseV2_init(address(_coordinator)); __Ownable_init(); __UUPSUpgradeable_init(); COORDINATOR = _coordinator; subscriptionId = _subscriptionId; startTime = uint40((block.timestamp / MIN_RANDOM_WORDS_UPDATE_TIME) * MIN_RANDOM_WORDS_UPDATE_TIME) - 5 days; // Floor to the nearest day 00:00 UTC lastRandomWordsUpdatedTime = startTime + 4 days; weeklyRewardCheckpoint = uint40((block.timestamp - 4 days) / 1 weeks) * 1 weeks + 4 days + 1 weeks; // Issue new available daily rewards Equipment[8] memory rewards = [ Equipment(COPPER_ORE, 100), Equipment(COAL_ORE, 200), Equipment(RUBY, 100), Equipment(MITHRIL_BAR, 200), Equipment(COOKED_BOWFISH, 100), Equipment(LEAF_FRAGMENTS, 20), Equipment(HELL_SCROLL, 300), Equipment(XP_BOOST, 1) ]; _storeDailyRewards(rewards); emit NewDailyRewards(rewards); // Initialize 4 days worth of random words for (U256 iter; iter.lt(4); iter = iter.inc()) { uint i = iter.asUint256(); uint requestId = 200 + i; requestIds.push(requestId); emit RequestSent(requestId, NUM_WORDS, startTime + (i * 1 days) + 1 days); uint[] memory _randomWords = new uint[](3); _randomWords[0] = uint( blockhash(block.number - 4 + i) ^ 0x3632d8eba811d69784e6904a58de6e0ab55f32638189623b309895beaa6920c4 ); _randomWords[1] = uint( blockhash(block.number - 4 + i) ^ 0xca820e9e57e5e703aeebfa2dc60ae09067f931b6e888c0a7c7a15a76341ab2c2 ); _randomWords[2] = uint( blockhash(block.number - 4 + i) ^ 0xd1f1b7d57307aee9687ae39dbb462b1c1f07a406d34cd380670360ef02f243b6 ); fulfillRandomWords(requestId, _randomWords); } } function canRequestRandomWord() external view returns (bool) { // Last one has not been fulfilled yet if (requestIds.length != 0 && randomWords[requestIds[requestIds.length - 1]][0] == 0) { return false; } if (lastRandomWordsUpdatedTime + MIN_RANDOM_WORDS_UPDATE_TIME > block.timestamp) { return false; } return true; } function requestRandomWords() external returns (uint256 requestId) { // Last one has not been fulfilled yet if (requestIds.length != 0 && randomWords[requestIds[requestIds.length - 1]][0] == 0) { revert RandomWordsCannotBeUpdatedYet(); } uint40 newLastRandomWordsUpdatedTime = lastRandomWordsUpdatedTime + MIN_RANDOM_WORDS_UPDATE_TIME; if (newLastRandomWordsUpdatedTime > block.timestamp) { revert CanOnlyRequestAfterTheNextCheckpoint(block.timestamp, newLastRandomWordsUpdatedTime); } // Will revert if subscription is not set and funded. requestId = COORDINATOR.requestRandomWords( KEY_HASH, subscriptionId, REQUEST_CONFIRMATIONS, CALLBACK_GAS_LIMIT, NUM_WORDS ); requestIds.push(requestId); lastRandomWordsUpdatedTime = newLastRandomWordsUpdatedTime; emit RequestSent(requestId, NUM_WORDS, newLastRandomWordsUpdatedTime); return requestId; } function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override { if (randomWords[_requestId][0] != 0) { revert RequestAlreadyFulfilled(); } uint256[3] memory random = [_randomWords[0], _randomWords[1], _randomWords[2]]; if (random[0] == 0) { // Not sure if 0 can be selected, but in case use previous block hash as pseudo random number random[0] = uint(blockhash(block.number - 1)); } if (random[1] == 0) { random[1] = uint(blockhash(block.number - 2)); } if (random[2] == 0) { random[2] = uint(blockhash(block.number - 3)); } randomWords[_requestId] = random; if (address(quests) != address(0)) { quests.newOracleRandomWords(random); } emit RequestFulfilled(_requestId, random); // Are we at the threshold for a new week if (weeklyRewardCheckpoint <= ((block.timestamp) / 1 days) * 1 days) { // Issue new daily rewards based on the new random words (TODO) Equipment[8] memory rewards = [ Equipment(COPPER_ORE, 100), Equipment(COAL_ORE, 200), Equipment(RUBY, 100), Equipment(MITHRIL_BAR, 200), Equipment(COOKED_BOWFISH, 100), Equipment(LEAF_FRAGMENTS, 20), Equipment(HELL_SCROLL, 300), Equipment(XP_BOOST, 1) ]; _storeDailyRewards(rewards); emit NewDailyRewards(rewards); weeklyRewardCheckpoint = uint40((block.timestamp - 4 days) / 1 weeks) * 1 weeks + 4 days + 1 weeks; } } function getDailyReward() external view returns (uint itemTokenId, uint amount) { uint checkpoint = ((block.timestamp - 4 days) / 1 weeks) * 1 weeks + 4 days; uint day = ((block.timestamp / 1 days) * 1 days - checkpoint) / 1 days; (itemTokenId, amount) = _getDailyReward(day); } function getWeeklyReward() external view returns (uint itemTokenId, uint amount) { (itemTokenId, amount) = _getDailyReward(7); } function _getRandomWordOffset(uint _timestamp) private view returns (int) { if (_timestamp < startTime) { return -1; } return int((_timestamp - startTime) / MIN_RANDOM_WORDS_UPDATE_TIME); } // Just returns the first random word of the array function _getRandomWord(uint _timestamp) private view returns (uint) { int offset = _getRandomWordOffset(_timestamp); if (offset < 0 || requestIds.length <= uint(offset)) { return 0; } return randomWords[requestIds[uint(offset)]][0]; } function hasRandomWord(uint _timestamp) external view returns (bool) { return _getRandomWord(_timestamp) != 0; } function getRandomWord(uint _timestamp) public view returns (uint randomWord) { randomWord = _getRandomWord(_timestamp); if (randomWord == 0) { revert NoValidRandomWord(); } } function getFullRandomWords(uint _timestamp) public view returns (uint[3] memory) { int offset = _getRandomWordOffset(_timestamp); if (offset < 0 || requestIds.length <= uint(offset)) { revert NoValidRandomWord(); } return randomWords[requestIds[uint(offset)]]; } function getMultipleFullRandomWords(uint _timestamp) public view returns (uint[3][5] memory words) { for (U256 iter; iter.lt(5); iter = iter.inc()) { uint i = iter.asUint256(); words[i] = getFullRandomWords(_timestamp - i * 1 days); } } function getSkill(uint _actionId) external view returns (Skill) { return actions[_actionId].skill; } function getActionRewards(uint _actionId) external view returns (ActionRewards memory) { return actionRewards[_actionId]; } function getPermissibleItemsForAction( uint _actionId ) external view returns ( uint16 handItemTokenIdRangeMin, uint16 handItemTokenIdRangeMax, bool actionChoiceRequired, Skill skill, uint32 minXP, bool actionAvailable ) { ActionInfo storage actionInfo = actions[_actionId]; return ( actionInfo.handItemTokenIdRangeMin, actionInfo.handItemTokenIdRangeMax, actionInfo.actionChoiceRequired, actionInfo.skill, actionInfo.minXP, actionInfo.isAvailable ); } function getXPPerHour(uint16 _actionId, uint16 _actionChoiceId) external view returns (uint24 xpPerHour) { return _actionChoiceId != 0 ? actionChoices[_actionId][_actionChoiceId].xpPerHour : actions[_actionId].xpPerHour; } function getNumSpawn(uint16 _actionId) external view returns (uint numSpawned) { return actions[_actionId].numSpawned; } function getCombatStats(uint16 _actionId) external view returns (CombatStats memory stats) { stats = actionCombatStats[_actionId]; } function getActionChoice(uint16 _actionId, uint16 _choiceId) external view returns (ActionChoice memory) { return actionChoices[_actionId][_choiceId]; } function getActionSuccessPercentAndMinXP( uint16 _actionId ) external view returns (uint8 successPercent, uint32 minXP) { return (actions[_actionId].successPercent, actions[_actionId].minXP); } function getRewardsHelper(uint16 _actionId) external view returns (ActionRewards memory, Skill, uint) { return (actionRewards[_actionId], actions[_actionId].skill, actions[_actionId].numSpawned); } function getRandomBytes(uint _numTickets, uint _skillEndTime, uint _playerId) external view returns (bytes memory b) { if (_numTickets <= 16) { // 32 bytes bytes32 word = bytes32(getRandomWord(_skillEndTime)); b = abi.encodePacked(_getRandomComponent(word, _skillEndTime, _playerId)); } else if (_numTickets <= 48) { uint[3] memory fullWords = getFullRandomWords(_skillEndTime); // 3 * 32 bytes for (U256 iter; iter.lt(3); iter = iter.inc()) { uint i = iter.asUint256(); fullWords[i] = uint(_getRandomComponent(bytes32(fullWords[i]), _skillEndTime, _playerId)); } b = abi.encodePacked(fullWords); } else { // 3 * 5 * 32 bytes uint[3][5] memory multipleFullWords = getMultipleFullRandomWords(_skillEndTime); for (U256 iter; iter.lt(5); iter = iter.inc()) { uint i = iter.asUint256(); for (U256 jter; jter.lt(3); jter = jter.inc()) { uint j = jter.asUint256(); multipleFullWords[i][j] = uint( _getRandomComponent(bytes32(multipleFullWords[i][j]), _skillEndTime, _playerId) ); // XOR all the full words with the first fresh random number to give more randomness to the existing random words if (i != 0) { multipleFullWords[i][j] = multipleFullWords[i][j] ^ multipleFullWords[0][j]; } } } b = abi.encodePacked(multipleFullWords); } } function _addAction(Action calldata _action) private { if (_action.info.isDynamic) { revert DynamicActionsCannotBeAdded(); } if (actions[_action.actionId].skill != Skill.NONE) { revert ActionAlreadyExists(); } _setAction(_action); } function _getDailyReward(uint256 _day) private view returns (uint itemTokenId, uint amount) { itemTokenId = uint((dailyRewards & ((bytes32(hex"ffff0000") >> (_day * 32)))) >> ((7 - _day) * 32 + 16)); amount = uint((dailyRewards & ((bytes32(hex"0000ffff") >> (_day * 32)))) >> ((7 - _day) * 32)); } function _getUpdatedDailyReward( uint _index, Equipment memory _equipment, bytes32 _rewards ) private pure returns (bytes32) { bytes32 rewardItemTokenId; bytes32 rewardAmount; assembly ("memory-safe") { rewardItemTokenId := mload(_equipment) rewardAmount := mload(add(_equipment, 32)) } _rewards = _rewards | (rewardItemTokenId << ((7 - _index) * 32 + 16)); _rewards = _rewards | (rewardAmount << ((7 - _index) * 32)); return _rewards; } function _storeDailyRewards(Equipment[8] memory equipments) private { bytes32 rewards; U256 bounds = equipments.length.asU256(); for (U256 iter; iter < bounds; iter = iter.inc()) { uint i = iter.asUint256(); rewards = _getUpdatedDailyReward(i, equipments[i], rewards); } dailyRewards = rewards; } function _setAction(Action calldata _action) private { if (_action.actionId == 0) { revert ActionIdZeroNotAllowed(); } if (_action.info.handItemTokenIdRangeMin > _action.info.handItemTokenIdRangeMax) { revert MinCannotBeGreaterThanMax(); } if (_action.info.skill != Skill.COMBAT && _action.guaranteedRewards.length > 1) { revert OnlyCombatMultipleGuaranteedRewards(); } if (_action.info.numSpawned > 0) { // Combat if ((3600 * SPAWN_MUL) % _action.info.numSpawned != 0) { revert NotAFactorOf3600(); } } else if (_action.guaranteedRewards.length != 0) { // Non-combat guaranteed rewards if ((3600 * GUAR_MUL) % _action.guaranteedRewards[0].rate != 0) { revert NotAFactorOf3600(); } } actions[_action.actionId] = _action.info; // Set the rewards ActionRewards storage actionReward = actionRewards[_action.actionId]; WorldLibrary.setActionGuaranteedRewards(_action, actionReward); WorldLibrary.setActionRandomRewards(_action, actionReward); if (_action.info.skill == Skill.COMBAT) { actionCombatStats[_action.actionId] = _action.combatStats; } else { bool actionHasGuaranteedRewards = _action.guaranteedRewards.length != 0; bool actionHasRandomRewards = _action.randomRewards.length != 0; if (actionHasGuaranteedRewards && actionHasRandomRewards) { revert NonCombatCannotHaveBothGuaranteedAndRandomRewards(); } } } function _addActionChoice(uint16 _actionId, uint16 _actionChoiceId, ActionChoice calldata _actionChoice) private { if (_actionChoiceId == 0) { revert ActionChoiceIdZeroNotAllowed(); } if (actionChoices[_actionId][_actionChoiceId].skill != Skill.NONE) { revert ActionChoiceAlreadyExists(); } WorldLibrary.checkActionChoice(_actionChoice); actionChoices[_actionId][_actionChoiceId] = _actionChoice; } function _editActionChoice(uint16 _actionId, uint16 _actionChoiceId, ActionChoice calldata _actionChoice) private { if (actionChoices[_actionId][_actionChoiceId].skill == Skill.NONE) { revert ActionChoiceDoesNotExist(); } WorldLibrary.checkActionChoice(_actionChoice); actionChoices[_actionId][_actionChoiceId] = _actionChoice; } function _getRandomComponent(bytes32 _word, uint _skillEndTime, uint _playerId) private pure returns (bytes32) { return keccak256(abi.encodePacked(_word, _skillEndTime, _playerId)); } function addAction(Action calldata _action) external onlyOwner { _addAction(_action); emit AddAction(_action); } function addActions(Action[] calldata _actions) external onlyOwner { U256 iter = _actions.length.asU256(); while (iter.neq(0)) { iter = iter.dec(); uint16 i = iter.asUint16(); _addAction(_actions[i]); } emit AddActions(_actions); } function editActions(Action[] calldata _actions) external onlyOwner { for (uint i = 0; i < _actions.length; ++i) { if (actions[_actions[i].actionId].skill == Skill.NONE) { revert ActionDoesNotExist(); } _setAction(_actions[i]); } emit EditActions(_actions); } // actionId of 0 means it is not tied to a specific action (combat) function addActionChoice( uint16 _actionId, uint16 _actionChoiceId, ActionChoice calldata _actionChoice ) external onlyOwner { _addActionChoice(_actionId, _actionChoiceId, _actionChoice); emit AddActionChoice(_actionId, _actionChoiceId, _actionChoice); } function addBulkActionChoices( uint16[] calldata _actionIds, uint16[][] calldata _actionChoiceIds, ActionChoice[][] calldata _actionChoices ) external onlyOwner { if (_actionIds.length != _actionChoices.length) { revert LengthMismatch(); } if (_actionIds.length == 0) { revert NoActionChoices(); } U256 actionIdsLength = _actionIds.length.asU256(); for (U256 iter; iter < actionIdsLength; iter = iter.inc()) { uint16 i = iter.asUint16(); uint16 actionId = _actionIds[i]; emit AddActionChoices(actionId, _actionChoiceIds[i], _actionChoices[i]); U256 actionChoiceLength = _actionChoices[i].length.asU256(); if (actionChoiceLength.neq(_actionChoiceIds[i].length)) { revert LengthMismatch(); } for (U256 jter; jter < actionChoiceLength; jter = jter.inc()) { uint16 j = jter.asUint16(); _addActionChoice(actionId, _actionChoiceIds[i][j], _actionChoices[i][j]); } } } function editActionChoice(uint16 _actionId, uint16 _actionChoiceId, ActionChoice calldata _actionChoice) external { _editActionChoice(_actionId, _actionChoiceId, _actionChoice); emit EditActionChoice(_actionId, _actionChoiceId, _actionChoice); } function editActionChoices( uint16[] calldata _actionIds, uint16[] calldata _actionChoiceIds, ActionChoice[] calldata _actionChoices ) external { if (_actionIds.length == 0) { revert NoActionChoices(); } U256 actionIdsLength = _actionIds.length.asU256(); for (U256 iter; iter < actionIdsLength; iter = iter.inc()) { uint16 i = iter.asUint16(); _editActionChoice(_actionIds[i], _actionChoiceIds[i], _actionChoices[i]); } emit EditActionChoices(_actionIds, _actionChoiceIds, _actionChoices); } function setAvailable(uint16 _actionId, bool _isAvailable) external onlyOwner { if (actions[_actionId].skill == Skill.NONE) { revert ActionDoesNotExist(); } if (actions[_actionId].isDynamic) { revert DynamicActionsCannotBeSet(); } actions[_actionId].isAvailable = _isAvailable; emit SetAvailableAction(_actionId, _isAvailable); } function setQuests(IQuests _quests) external onlyOwner { quests = _quests; } // solhint-disable-next-line no-empty-blocks function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import {UnsafeMath, U256} from "@0xdoublesharp/unsafe-math/contracts/UnsafeMath.sol"; // solhint-disable-next-line no-global-import import "./globals/all.sol"; // This file contains methods for interacting with the World, used to decrease implementation deployment bytecode code. library WorldLibrary { using UnsafeMath for U256; using UnsafeMath for uint; error InputSpecifiedWithoutAmount(); error PreviousInputTokenIdMustBeSpecified(); error InputAmountsMustBeInOrder(); error OutputSpecifiedWithoutAmount(); error RandomRewardsMustBeInOrder(uint16 chance1, uint16 chance2); error RandomRewardNoDuplicates(); error GuaranteedRewardsMustBeInOrder(); error GuaranteedRewardsNoDuplicates(); error NotAFactorOf3600(); function checkActionChoice(ActionChoice calldata _actionChoice) external pure { if (_actionChoice.inputTokenId1 != NONE && _actionChoice.inputAmount1 == 0) { revert InputSpecifiedWithoutAmount(); } if (_actionChoice.inputTokenId2 != NONE) { if (_actionChoice.inputAmount2 == 0) { revert InputSpecifiedWithoutAmount(); } if (_actionChoice.inputTokenId1 == NONE) { revert PreviousInputTokenIdMustBeSpecified(); } if (_actionChoice.inputAmount2 < _actionChoice.inputAmount1) { revert InputAmountsMustBeInOrder(); } } if (_actionChoice.inputTokenId3 != NONE) { if (_actionChoice.inputAmount3 == 0) { revert InputSpecifiedWithoutAmount(); } if (_actionChoice.inputTokenId2 == NONE) { revert PreviousInputTokenIdMustBeSpecified(); } if (_actionChoice.inputAmount3 < _actionChoice.inputAmount2) { revert InputAmountsMustBeInOrder(); } } if (_actionChoice.outputTokenId != 0 && _actionChoice.outputAmount == 0) { revert OutputSpecifiedWithoutAmount(); } if (_actionChoice.rate != 0) { // Check that it is a factor of 3600 if ((3600 * RATE_MUL) % _actionChoice.rate != 0) { revert NotAFactorOf3600(); } } } // Random rewards have most common one first function setActionRandomRewards(Action calldata _action, ActionRewards storage actionReward) external { uint randomRewardsLength = _action.randomRewards.length; if (randomRewardsLength != 0) { actionReward.randomRewardTokenId1 = _action.randomRewards[0].itemTokenId; actionReward.randomRewardChance1 = _action.randomRewards[0].chance; actionReward.randomRewardAmount1 = _action.randomRewards[0].amount; } if (randomRewardsLength > 1) { actionReward.randomRewardTokenId2 = _action.randomRewards[1].itemTokenId; actionReward.randomRewardChance2 = _action.randomRewards[1].chance; actionReward.randomRewardAmount2 = _action.randomRewards[1].amount; if (actionReward.randomRewardChance2 > actionReward.randomRewardChance1) { revert RandomRewardsMustBeInOrder(_action.randomRewards[0].chance, _action.randomRewards[1].chance); } if (actionReward.randomRewardTokenId1 == actionReward.randomRewardTokenId2) { revert RandomRewardNoDuplicates(); } } if (randomRewardsLength > 2) { actionReward.randomRewardTokenId3 = _action.randomRewards[2].itemTokenId; actionReward.randomRewardChance3 = _action.randomRewards[2].chance; actionReward.randomRewardAmount3 = _action.randomRewards[2].amount; if (actionReward.randomRewardChance3 > actionReward.randomRewardChance2) { revert RandomRewardsMustBeInOrder(_action.randomRewards[1].chance, _action.randomRewards[2].chance); } U256 bounds = randomRewardsLength.dec().asU256(); for (U256 iter; iter < bounds; iter = iter.inc()) { uint i = iter.asUint256(); if (_action.randomRewards[i].itemTokenId == _action.randomRewards[randomRewardsLength.dec()].itemTokenId) { revert RandomRewardNoDuplicates(); } } } if (_action.randomRewards.length > 3) { actionReward.randomRewardTokenId4 = _action.randomRewards[3].itemTokenId; actionReward.randomRewardChance4 = _action.randomRewards[3].chance; actionReward.randomRewardAmount4 = _action.randomRewards[3].amount; if (actionReward.randomRewardChance4 > actionReward.randomRewardChance3) { revert RandomRewardsMustBeInOrder(_action.randomRewards[2].chance, _action.randomRewards[3].chance); } U256 bounds = _action.randomRewards.length.dec().asU256(); for (U256 iter; iter < bounds; iter = iter.inc()) { uint i = iter.asUint256(); if ( _action.randomRewards[i].itemTokenId == _action.randomRewards[_action.randomRewards.length - 1].itemTokenId ) { revert RandomRewardNoDuplicates(); } } } } function setActionGuaranteedRewards(Action calldata _action, ActionRewards storage _actionRewards) external { uint guaranteedRewardsLength = _action.guaranteedRewards.length; if (guaranteedRewardsLength != 0) { _actionRewards.guaranteedRewardTokenId1 = _action.guaranteedRewards[0].itemTokenId; _actionRewards.guaranteedRewardRate1 = _action.guaranteedRewards[0].rate; } if (guaranteedRewardsLength > 1) { _actionRewards.guaranteedRewardTokenId2 = _action.guaranteedRewards[1].itemTokenId; _actionRewards.guaranteedRewardRate2 = _action.guaranteedRewards[1].rate; if (_actionRewards.guaranteedRewardRate2 < _actionRewards.guaranteedRewardRate1) { revert GuaranteedRewardsMustBeInOrder(); } if (_actionRewards.guaranteedRewardTokenId1 == _actionRewards.guaranteedRewardTokenId2) { revert GuaranteedRewardsNoDuplicates(); } } if (guaranteedRewardsLength > 2) { _actionRewards.guaranteedRewardTokenId3 = _action.guaranteedRewards[2].itemTokenId; _actionRewards.guaranteedRewardRate3 = _action.guaranteedRewards[2].rate; if (_actionRewards.guaranteedRewardRate3 < _actionRewards.guaranteedRewardRate2) { revert GuaranteedRewardsMustBeInOrder(); } U256 bounds = guaranteedRewardsLength.dec().asU256(); for (U256 iter; iter < bounds; iter = iter.inc()) { uint i = iter.asUint256(); if ( _action.guaranteedRewards[i].itemTokenId == _action.guaranteedRewards[guaranteedRewardsLength.dec()].itemTokenId ) { revert GuaranteedRewardsNoDuplicates(); } } } } }
{ "optimizer": { "enabled": true, "runs": 9999999, "details": { "yul": true } }, "evmVersion": "paris", "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": { "contracts/ItemNFTLibrary.sol": { "ItemNFTLibrary": "0xa73f74c0fbed265a656293a1a91a9506678e3d54" } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressIsNotContract","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"BeaconImplementationIsNotAContract","type":"error"},{"inputs":[],"name":"CallerIsNotOwner","type":"error"},{"inputs":[],"name":"ERC1155InsufficientBalance","type":"error"},{"inputs":[],"name":"ERC1155LengthMismatch","type":"error"},{"inputs":[],"name":"ERC1155MintToZeroAddress","type":"error"},{"inputs":[],"name":"ERC1155ReceiverNotApproved","type":"error"},{"inputs":[],"name":"ERC1155ReceiverRejectedTokens","type":"error"},{"inputs":[],"name":"ERC1155SettingApprovalStatusForSelf","type":"error"},{"inputs":[],"name":"ERC1155TransferFromNotApproved","type":"error"},{"inputs":[],"name":"ERC1155TransferToNonERC1155Receiver","type":"error"},{"inputs":[],"name":"ERC1155TransferToZeroAddress","type":"error"},{"inputs":[],"name":"ERC1155ZeroAddressNotValidOwner","type":"error"},{"inputs":[],"name":"ERC115BurnAmountExceedsBalance","type":"error"},{"inputs":[],"name":"ERC115BurnFromZeroAddress","type":"error"},{"inputs":[],"name":"EquipmentPositionShouldNotChange","type":"error"},{"inputs":[],"name":"FunctionMustBeCalledThroughActiveProxy","type":"error"},{"inputs":[],"name":"FunctionMustBeCalledThroughDelegateCall","type":"error"},{"inputs":[],"name":"FunctionMustNotBeCalledThroughDelegateCall","type":"error"},{"inputs":[],"name":"IdTooHigh","type":"error"},{"inputs":[],"name":"InvalidChainId","type":"error"},{"inputs":[],"name":"InvalidTokenId","type":"error"},{"inputs":[],"name":"IsInitializing","type":"error"},{"inputs":[],"name":"ItemAlreadyExists","type":"error"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"ItemDoesNotExist","type":"error"},{"inputs":[],"name":"ItemNotTransferable","type":"error"},{"inputs":[],"name":"NewAdminIsZeroAddress","type":"error"},{"inputs":[],"name":"NewBeaconIsNotAContract","type":"error"},{"inputs":[],"name":"NewImplementationIsNotAContract","type":"error"},{"inputs":[],"name":"NewImplementationNotUUPS","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NotAdminAndBeta","type":"error"},{"inputs":[],"name":"NotAllowedHardhat","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"NotPlayersOrShop","type":"error"},{"inputs":[],"name":"OnlyForHardhat","type":"error"},{"inputs":[],"name":"UnsupportedProxiableUUID","type":"error"},{"anonymous":false,"inputs":[{"components":[{"internalType":"enum EquipPosition","name":"equipPosition","type":"uint8"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"isTransferable","type":"bool"},{"internalType":"uint16","name":"healthRestored","type":"uint16"},{"internalType":"enum BoostType","name":"boostType","type":"uint8"},{"internalType":"uint16","name":"boostValue","type":"uint16"},{"internalType":"uint24","name":"boostDuration","type":"uint24"},{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"range","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangeDefence","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"}],"indexed":false,"internalType":"struct Item","name":"item","type":"tuple"},{"indexed":false,"internalType":"uint16","name":"tokenId","type":"uint16"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"AddItem","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"enum EquipPosition","name":"equipPosition","type":"uint8"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"isTransferable","type":"bool"},{"internalType":"uint16","name":"healthRestored","type":"uint16"},{"internalType":"enum BoostType","name":"boostType","type":"uint8"},{"internalType":"uint16","name":"boostValue","type":"uint16"},{"internalType":"uint24","name":"boostDuration","type":"uint24"},{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"range","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangeDefence","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"}],"indexed":false,"internalType":"struct Item[]","name":"items","type":"tuple[]"},{"indexed":false,"internalType":"uint16[]","name":"tokenIds","type":"uint16[]"},{"indexed":false,"internalType":"string[]","name":"names","type":"string[]"}],"name":"AddItems","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"previousAdmin","type":"address"},{"indexed":false,"internalType":"address","name":"newAdmin","type":"address"}],"name":"AdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"enum EquipPosition","name":"equipPosition","type":"uint8"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"isTransferable","type":"bool"},{"internalType":"uint16","name":"healthRestored","type":"uint16"},{"internalType":"enum BoostType","name":"boostType","type":"uint8"},{"internalType":"uint16","name":"boostValue","type":"uint16"},{"internalType":"uint24","name":"boostDuration","type":"uint24"},{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"range","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangeDefence","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"}],"indexed":false,"internalType":"struct Item","name":"item","type":"tuple"},{"indexed":false,"internalType":"uint16","name":"tokenId","type":"uint16"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"EditItem","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"enum EquipPosition","name":"equipPosition","type":"uint8"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"isTransferable","type":"bool"},{"internalType":"uint16","name":"healthRestored","type":"uint16"},{"internalType":"enum BoostType","name":"boostType","type":"uint8"},{"internalType":"uint16","name":"boostValue","type":"uint16"},{"internalType":"uint24","name":"boostDuration","type":"uint24"},{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"range","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangeDefence","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"}],"indexed":false,"internalType":"struct Item[]","name":"items","type":"tuple[]"},{"indexed":false,"internalType":"uint16[]","name":"tokenIds","type":"uint16[]"},{"indexed":false,"internalType":"string[]","name":"names","type":"string[]"}],"name":"EditItems","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[{"components":[{"components":[{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"range","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangeDefence","type":"int16"}],"internalType":"struct CombatStats","name":"combatStats","type":"tuple"},{"internalType":"uint16","name":"tokenId","type":"uint16"},{"internalType":"enum EquipPosition","name":"equipPosition","type":"uint8"},{"internalType":"bool","name":"isTransferable","type":"bool"},{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"uint16","name":"healthRestored","type":"uint16"},{"internalType":"enum BoostType","name":"boostType","type":"uint8"},{"internalType":"uint16","name":"boostValue","type":"uint16"},{"internalType":"uint24","name":"boostDuration","type":"uint24"},{"internalType":"string","name":"metadataURI","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct InputItem","name":"_inputItem","type":"tuple"}],"name":"addItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"range","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangeDefence","type":"int16"}],"internalType":"struct CombatStats","name":"combatStats","type":"tuple"},{"internalType":"uint16","name":"tokenId","type":"uint16"},{"internalType":"enum EquipPosition","name":"equipPosition","type":"uint8"},{"internalType":"bool","name":"isTransferable","type":"bool"},{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"uint16","name":"healthRestored","type":"uint16"},{"internalType":"enum BoostType","name":"boostType","type":"uint8"},{"internalType":"uint16","name":"boostValue","type":"uint16"},{"internalType":"uint24","name":"boostDuration","type":"uint24"},{"internalType":"string","name":"metadataURI","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct InputItem[]","name":"_inputItems","type":"tuple[]"}],"name":"addItems","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint16[]","name":"_ids","type":"uint16[]"}],"name":"balanceOfs","outputs":[{"internalType":"uint256[]","name":"batchBalances","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"burnBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"range","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangeDefence","type":"int16"}],"internalType":"struct CombatStats","name":"combatStats","type":"tuple"},{"internalType":"uint16","name":"tokenId","type":"uint16"},{"internalType":"enum EquipPosition","name":"equipPosition","type":"uint8"},{"internalType":"bool","name":"isTransferable","type":"bool"},{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"uint16","name":"healthRestored","type":"uint16"},{"internalType":"enum BoostType","name":"boostType","type":"uint8"},{"internalType":"uint16","name":"boostValue","type":"uint16"},{"internalType":"uint24","name":"boostDuration","type":"uint24"},{"internalType":"string","name":"metadataURI","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct InputItem","name":"_inputItem","type":"tuple"}],"name":"editItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"components":[{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"range","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangeDefence","type":"int16"}],"internalType":"struct CombatStats","name":"combatStats","type":"tuple"},{"internalType":"uint16","name":"tokenId","type":"uint16"},{"internalType":"enum EquipPosition","name":"equipPosition","type":"uint8"},{"internalType":"bool","name":"isTransferable","type":"bool"},{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"uint16","name":"healthRestored","type":"uint16"},{"internalType":"enum BoostType","name":"boostType","type":"uint8"},{"internalType":"uint16","name":"boostValue","type":"uint16"},{"internalType":"uint24","name":"boostDuration","type":"uint24"},{"internalType":"string","name":"metadataURI","type":"string"},{"internalType":"string","name":"name","type":"string"}],"internalType":"struct InputItem[]","name":"_inputItems","type":"tuple[]"}],"name":"editItems","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenId","type":"uint16"}],"name":"getBoostInfo","outputs":[{"internalType":"uint16","name":"boostValue","type":"uint16"},{"internalType":"uint24","name":"boostDuration","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_item","type":"uint16"}],"name":"getEquipPositionAndMinRequirement","outputs":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"enum EquipPosition","name":"equipPosition","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_tokenIds","type":"uint16[]"}],"name":"getEquipPositions","outputs":[{"internalType":"enum EquipPosition[]","name":"equipPositions","type":"uint8[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_tokenId","type":"uint16"}],"name":"getItem","outputs":[{"components":[{"internalType":"enum EquipPosition","name":"equipPosition","type":"uint8"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"isTransferable","type":"bool"},{"internalType":"uint16","name":"healthRestored","type":"uint16"},{"internalType":"enum BoostType","name":"boostType","type":"uint8"},{"internalType":"uint16","name":"boostValue","type":"uint16"},{"internalType":"uint24","name":"boostDuration","type":"uint24"},{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"range","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangeDefence","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"}],"internalType":"struct Item","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_tokenIds","type":"uint16[]"}],"name":"getItems","outputs":[{"components":[{"internalType":"enum EquipPosition","name":"equipPosition","type":"uint8"},{"internalType":"bool","name":"exists","type":"bool"},{"internalType":"bool","name":"isTransferable","type":"bool"},{"internalType":"uint16","name":"healthRestored","type":"uint16"},{"internalType":"enum BoostType","name":"boostType","type":"uint8"},{"internalType":"uint16","name":"boostValue","type":"uint16"},{"internalType":"uint24","name":"boostDuration","type":"uint24"},{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"range","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangeDefence","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"}],"internalType":"struct Item[]","name":"_items","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_tokenIds","type":"uint16[]"}],"name":"getMinRequirements","outputs":[{"internalType":"enum Skill[]","name":"skills","type":"uint8[]"},{"internalType":"uint32[]","name":"minXPs","type":"uint32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract World","name":"_world","type":"address"},{"internalType":"address","name":"_shop","type":"address"},{"internalType":"address","name":"_royaltyReceiver","type":"address"},{"internalType":"contract AdminAccess","name":"_adminAccess","type":"address"},{"internalType":"string","name":"_baseURI","type":"string"},{"internalType":"bool","name":"_isBeta","type":"bool"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"itemBalances","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"numUniqueItems","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxiableUUID","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"royaltyAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IBankFactory","name":"_bankFactory","type":"address"}],"name":"setBankFactory","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_players","type":"address"}],"name":"setPlayers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"testMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[]","name":"_amounts","type":"uint256[]"}],"name":"testMints","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"timestampFirstMint","outputs":[{"internalType":"uint256","name":"timestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"}],"name":"upgradeTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newImplementation","type":"address"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"upgradeToAndCall","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a080604052346200009e57306080526000549060ff8260081c166200008f575060ff8082161062000053575b6040516159429081620000a482396080518181816120010152818161238801526128020152f35b60ff90811916176000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a1386200002c565b63ce446e0f60e01b8152600490fd5b600080fdfe6080604052600436101561001257600080fd5b60e0600035811c908162fdd58e14613bbb57816301ffc9a714613a985781630511134e146138c457816306fdde03146137e15781630e89341c146135a957816313e0131e14613565578163156e29f6146134275781631b77778414612d665781632a55205a14612cc05781632eb2c2d61461298d5781633659cfe6146127b15781634e1273f4146126555781634f1ef2861461231d5781634f558e79146122c4578163500ae0f31461207b57816352d1902d14611fbb57816355f4d5ca14611f3557816355f804b314611d795781636b20c45414611c02578163715018a614611b64578163793e9f26146119c9578163810de9de14611882578163857fdf611461182a5781638da5cb5b146117d857816395d89b41146116e1578163a22cb465146115e1578163a58c0ef7146113af578163acc255e51461132a578163ae5c3a4714611200578163b5500d1f146111b5578163c3ba1d5b1461111d578163c9489bb8146110ca578163d81d0a1514610efc578163df90046314610d30578163e985e9c514610cae578163f242432a14610935578163f2fde38b146108a7578163f5298aca146106f0578163f74e548b146105bf578163f96cc55a146104f857508063fbb5b976146104ad5763fed86c5c146101ec57600080fd5b346104a8576101fa36613f6b565b9193929073ffffffffffffffffffffffffffffffffffffffff918261013754169560405180977f24d7806c00000000000000000000000000000000000000000000000000000000825233600483015281602460209a8b935afa90811561049c5760009161046f575b508061045f575b15610435576000805b828110610408575091610292918361029a95946103ad575b503691613e3f565b933691613e3f565b93604051916102a883613d92565b6000835284169182156103835783518651036103595760005b845181101561031257806102d861030d9289614345565b516102e38288614345565b51600052606585526040600020866000528552610306604060002091825461442a565b9055614ecf565b6102c1565b610357828887898860006040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb33918061034e89898361561f565b0390a433615818565b005b60046040517f0b2e4b40000000000000000000000000000000000000000000000000000000008152fd5b60046040517f63930028000000000000000000000000000000000000000000000000000000008152fd5b610132907fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff75ffff000000000000000000000000000000000000000083549261ffff809116908460a01c160160a01b1691161790553861028a565b9060019061042d61041a8486886142f7565b35610426858b8a6142f7565b3590614437565b019101610272565b60046040517facc0304c000000000000000000000000000000000000000000000000000000008152fd5b5060ff61012d5460a01c16610269565b61048f9150883d8a11610495575b6104878183613de6565b810190614efc565b38610262565b503d61047d565b6040513d6000823e3d90fd5b600080fd5b346104a85760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a8576004356000526101306020526020604060002054604051908152f35b346104a85761050636614111565b9061050f614f14565b81019061053a61ffff61052184614336565b1660005261013660205260ff60406000205460081c1690565b610596577fa4cbd237ec05bcde89049f10b891b5f1396704c5e1d1f398186678d4c1a909fb9161059161058461057861057285614720565b93614336565b93610220810190614536565b90604051948594856145c6565b0390a1005b60046040517ea1e25e000000000000000000000000000000000000000000000000000000008152fd5b346104a8576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85760043567ffffffffffffffff81116104a85761060f903690600401613c4e565b9061061982613e27565b906106276040519283613de6565b82825261063383613e27565b927fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0858401940136853760005b8181106106ba5750505090604051928392818401908285525180915260408401929160005b82811061069457505050500390f35b91938395509080826106aa600194839751614016565b0195019101918594939192610685565b806106ea6106db6106d66106d160019587896142f7565b614336565b6143c6565b6106e58388614345565b6142df565b01610660565b346104a8576106fe36613cf2565b919073ffffffffffffffffffffffffffffffffffffffff9182811692338414159081610880575b81610870575b81610860575b5061083657821561080c5761076790610749836158cb565b610752866158cb565b91600060405161076181613d92565b5261525b565b806000526065602052604060002082600052602052604060002054928084106107e2578060009483865260656020526040862085875260205203604085205560405191825260208201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a4610357604051613d92565b60046040517fccec2489000000000000000000000000000000000000000000000000000000008152fd5b60046040517f2735fb7a000000000000000000000000000000000000000000000000000000008152fd5b60046040517f20230e99000000000000000000000000000000000000000000000000000000008152fd5b6101325416331415905085610731565b610131548116331415915061072b565b905083600052606660205260406000203360005260205260ff604060002054161590610725565b346104a85760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a8576108de613c08565b6108e6614f14565b73ffffffffffffffffffffffffffffffffffffffff81161561090b5761035790614f5f565b60046040517f7448fbae000000000000000000000000000000000000000000000000000000008152fd5b346104a85760a07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85761096c613c08565b610974613c2b565b9060643560443560843567ffffffffffffffff81116104a85761099b903690600401613f1c565b73ffffffffffffffffffffffffffffffffffffffff93848116943386141580610c89575b610c5f578616908115610c35576109e9906109d9856158cb565b886109e3886158cb565b926153c4565b82600052602095606587526040600020866000528752604060002054858110610c0b5785908560005260658952604060002088600052895203604060002055836000526065875260406000208260005287526040600020610a4b86825461442a565b90558186604051868152878a8201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a43b610a8757005b610ae49360008794604051968795869485937ff23a6e61000000000000000000000000000000000000000000000000000000009b8c865233600487015260248601526044850152606484015260a0608484015260a4830190613caf565b03925af160009181610bdc575b50610b875782610aff61567c565b6308c379a014610b34575b60046040517fde62dcd0000000000000000000000000000000000000000000000000000000008152fd5b610b3c61569a565b9081610b485750610b0a565b610b836040519283927f08c379a000000000000000000000000000000000000000000000000000000000845260048401526024830190613caf565b0390fd5b7fffffffff0000000000000000000000000000000000000000000000000000000016039050610bb257005b60046040517f01f83c78000000000000000000000000000000000000000000000000000000008152fd5b610bfd919250843d8611610c04575b610bf58183613de6565b810190615644565b9084610af1565b503d610beb565b60046040517fe4ebde13000000000000000000000000000000000000000000000000000000008152fd5b60046040517f6611a8b0000000000000000000000000000000000000000000000000000000008152fd5b60046040517fde927bb4000000000000000000000000000000000000000000000000000000008152fd5b5085600052606660205260406000203360005260205260ff60406000205416156109bf565b346104a85760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a857610ce5613c08565b610ced613c2b565b9073ffffffffffffffffffffffffffffffffffffffff809116600052606660205260406000209116600052602052602060ff604060002054166040519015158152f35b346104a857602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85760043567ffffffffffffffff81116104a857610d81903690600401613c4e565b929091610d8d84614359565b9360005b818110610daf5760405184815280610dab81870189614162565b0390f35b610dc5610dc06106d18385896142f7565b614507565b9060405191610dd383613d75565b549160ff92610de4848216836142df565b838160081c16151587830152838160101c161515604083015261ffff90818160181c166060840152848160281c166006811015610ecd5760019563ffffffff93610ea79260808701528360301c1660a086015262ffffff8360401c1660c0860152868360581c810b8a8701528360681c810b6101008701528360781c810b6101208701528360881c810b6101408701528360981c810b6101608701528360a81c810b6101808701528360b81c900b6101a08601528260c81c166101c085016142eb565b60d01c166101e0820152610ebb8289614345565b52610ec68188614345565b5001610d91565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b346104a857610f0a36613f6b565b91939273ffffffffffffffffffffffffffffffffffffffff94856101315416331415806110bb575b611091576000805b82811061106b575091610f599183610f61959461101057503691613e3f565b923691613e3f565b9260405190610f6f82613d92565b6000825283169081156103835782518551036103595760005b8351811015610fd45780610f9f610fcf9288614345565b51610faa8287614345565b516000526020606581526040600020908660005252610306604060002091825461442a565b610f88565b509261035794929160006040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb33918061034e89898361561f565b610132907fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff75ffff000000000000000000000000000000000000000083549261ffff809116908460a01c160160a01b1691161790558861028a565b9060019061108961107d8486886142f7565b35610426858a8a6142f7565b019101610f3a565b60046040517f8317dcc1000000000000000000000000000000000000000000000000000000008152fd5b50856101325416331415610f32565b346104a8577fe9f900dc3a657404abf975950198d9d6a1708765327eb5a617d7f3066349b8ee906110fa36614111565b90611103614f14565b61059161058461057861111585614d6f565b938501614336565b346104a85760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a8576060611156613ff6565b6111b361119563ffffffff61118d8461ffff166000526101366020526040600020549063ffffffff60ff8360c81c169260d01c1690565b9290946143c6565b916111a36040518096613c7f565b1660208401526040830190614016565bf35b346104a85760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85760043560005261012f6020526020604060002054604051908152f35b346104a85760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a857611237613c08565b60243567ffffffffffffffff81116104a857366023820112156104a85780600401359061126382613e27565b906112716040519283613de6565b82825260209260248484019160051b830101913683116104a8576024859101915b8383106113125750505050805192836112aa816144b8565b945b6112c757505050610dab604051928284938452830190613f37565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff018061130261ffff6112fa8387614345565b51168461505e565b61130c8288614345565b526112ac565b819061131d84614007565b8152019101908490611292565b346104a85760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a857611361613c08565b611369614f14565b73ffffffffffffffffffffffffffffffffffffffff61013191167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055600080f35b346104a8576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85760043567ffffffffffffffff81116104a8576113ff903690600401613c4e565b90611408614f14565b61141182614359565b9161141b816144b8565b9361142582614bfb565b9560005b838110611462576040517f44740188542067ae3f7937a89c534917043b16e62add74adc27577c92b5407cc90806105918b8b8b84614ca2565b611475611470828688614c62565b614d6f565b906040519161148383613d75565b549160ff90611494828516826142df565b818460081c16151586820152818460101c161515604082015261ffff91828560181c166060830152808560281c16946006861015610ecd5761155a63ffffffff926115dc976080860152858360301c1660a086015262ffffff8360401c1660c086015260018360581c810b8a8701528360681c810b6101008701528360781c810b6101208701528360881c810b6101408701528360981c810b6101608701528360a81c810b6101808701528360b81c900b6101a08601528260c81c166101c085016142eb565b60d01c166101e082015261156e838a614345565b526115798289614345565b5061158f8461158984898b614c62565b01614336565b9061159a838b614345565b911690526115c16115ba6115af83888a614c62565b610220810190614536565b3691613ee5565b6115cb828b614345565b526115d6818a614345565b50614ecf565b611429565b346104a85760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a857611618613c08565b602435908115158092036104a85773ffffffffffffffffffffffffffffffffffffffff16908133146116b75733600052606660205260406000208260005260205260406000207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0081541660ff83161790556040519081527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3160203392a3005b60046040517fe0bca5cf000000000000000000000000000000000000000000000000000000008152fd5b346104a85760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85761012d5460a01c60ff16156117c057610dab60405161172e81613dae565b600181527f420000000000000000000000000000000000000000000000000000000000000060208201525b6117ac602460405180937f454b5f4900000000000000000000000000000000000000000000000000000000602083015261179c8151809260208686019101613c8c565b8101036004810184520182613de6565b604051918291602083526020830190613caf565b610dab6040516117cf81613d92565b60008152611759565b346104a85760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a857602073ffffffffffffffffffffffffffffffffffffffff60fb5416604051908152f35b346104a85760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a8576040611866610dc0613ff6565b5462ffffff82519161ffff8160301c168352831c166020820152f35b346104a85760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a8576118ca6118bc613ff6565b6118c4614269565b50614507565b604051906118d782613d75565b54916118e660ff8416836142df565b60ff8360081c161515602083015260ff8360101c161515604083015261ffff92838160181c16606084015260ff8160281c16916006831015610ecd576102009463ffffffff9360808601528260301c1660a085015262ffffff8260401c1660c08501526001908260581c820b908501528160681c810b6101008501528160781c810b6101208501528160881c810b6101408501528160981c810b6101608501528160a81c810b6101808501528160b81c900b6101a08401526119b260ff8260c81c166101c085016142eb565b60d01c166101e08201526111b36040518092614030565b346104a8576119d736613cf2565b73ffffffffffffffffffffffffffffffffffffffff918261013754169360405180957f24d7806c00000000000000000000000000000000000000000000000000000000825233600483015281602460209889935afa90811561049c57600091611b47575b5080611b37575b1561043557611a518383614437565b611ae1575b60405193611a6385613d92565b600085528116801561038357600061035796611a7e856158cb565b50611a88866158cb565b508482526065815260408220838352815260408220611aa887825461442a565b905585604051918683528201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a433615727565b61013280547fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff75ffff0000000000000000000000000000000000000000600161ffff8460a01c160160a01b169116179055611a56565b5060ff61012d5460a01c16611a42565b611b5e9150863d8811610495576104878183613de6565b86611a3b565b346104a85760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a857611b9b614f14565b600073ffffffffffffffffffffffffffffffffffffffff60fb547fffffffffffffffffffffffff0000000000000000000000000000000000000000811660fb55167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b346104a857611c1036613f6b565b929073ffffffffffffffffffffffffffffffffffffffff9283861693338514159081611d52575b81611d42575b81611d32575b5061083657611c5792610292913691613e3f565b92811561080c578251845103610359578383611c81926000604051611c7b81613d92565b526150c2565b60005b8251811015611ced57611c978184614345565b5190611ca38186614345565b5182600052606560208181526040600020866000528152604060002054918383106107e257611ce8956000528152604060002090866000525203604060002055614ecf565b611c84565b50907f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb611d2460009460405191829133958361561f565b0390a4610357604051613d92565b6101325416331415905087611c43565b6101315481163314159150611c3d565b905084600052606660205260406000203360005260205260ff604060002054161590611c37565b346104a8576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85767ffffffffffffffff6004358181116104a857611dca903690600401613d47565b9091611dd4614f14565b8111611f065761012e91611df182611dec85546141a4565b6141f7565b600093601f8311600114611e4d575092819293600092611e42575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c1916179055600080f35b013590508380611e0c565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08316947fbdaadd9f750d0166045bf387a364eadd28ba243e04512a47282aa5147a68e37f926000905b878210611eee575050836001959610611eb6575b505050811b019055005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88560031b161c19910135169055838080611eac565b80600184968294958701358155019501920190611e98565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b346104a85760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85760043573ffffffffffffffffffffffffffffffffffffffff81168091036104a857611f8d614f14565b61013880547fffffffffffffffffffffffff0000000000000000000000000000000000000000169091179055005b346104a85760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85773ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001630036120515760206040517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b60046040517f7251afea000000000000000000000000000000000000000000000000000000008152fd5b346104a857602090817ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85760043567ffffffffffffffff81116104a8576120cc903690600401613c4e565b6120d7939193614f14565b80916120e282614359565b936120ec836144b8565b95846120f785614bfb565b955b61212f576040517f71f7ce703d681371883927b9fc89bb374140827d1eea0a740b92f4f4b90415d39080610591898c8c84614ca2565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0161ffff6121678161052186611589868b89614c62565b6105965761217e612179838886614c62565b614720565b6040519061218b82613d75565b5460ff9061219b828216846142df565b818160081c16151588840152818160101c1615156040840152838160181c166060840152818160281c166006811015610ecd5763ffffffff92612259916080860152858360301c1660a086015262ffffff8360401c1660c086015260018360581c810b8a8701528360681c810b6101008701528360781c810b6101208701528360881c810b6101408701528360981c810b6101608701528360a81c810b6101808701528360b81c900b6101a08601528260c81c166101c085016142eb565b60d01c166101e082015261226d838a614345565b526122788289614345565b5061228884611589848987614c62565b90612293838b614345565b911690526122a86115ba6115af838886614c62565b6122b28288614345565b52806122be8188614345565b506120f9565b346104a85760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a857602061231360043560005261013660205260ff60406000205460081c1690565b6040519015158152f35b60407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85761234f613c08565b60243567ffffffffffffffff81116104a85761236f903690600401613f1c565b9073ffffffffffffffffffffffffffffffffffffffff807f0000000000000000000000000000000000000000000000000000000000000000169081301461262b577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc918183541603612601576123e3614f14565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156124195750506103579150614fcc565b82919216604051927f52d1902d0000000000000000000000000000000000000000000000000000000084526020938481600481865afa600091816125d2575b506124875760046040517f81007d10000000000000000000000000000000000000000000000000000000008152fd5b036125a85761249582614fcc565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a28351158015906125a0575b6124cf57005b813b15612578575060008381928461035796519201905af43d15612570573d906124f882613eab565b916125066040519384613de6565b82523d60008484013e5b7f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c6040519361253e85613dca565b602785528401527f206661696c65640000000000000000000000000000000000000000000000000060408401526158f0565b606090612510565b807f1fdb1d6d0000000000000000000000000000000000000000000000000000000060049252fd5b5060016124c9565b60046040517f8ae7e94c000000000000000000000000000000000000000000000000000000008152fd5b9091508581813d83116125fa575b6125ea8183613de6565b810103126104a857519087612458565b503d6125e0565b60046040517f36a15c6e000000000000000000000000000000000000000000000000000000008152fd5b60046040517f0ce7e818000000000000000000000000000000000000000000000000000000008152fd5b346104a85760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85760043567ffffffffffffffff8082116104a857366023830112156104a8578160040135906126b182613e27565b926126bf6040519485613de6565b82845260209260248486019160051b830101913683116104a857602401905b828210612785575050506024359081116104a857612700903690600401613e8d565b82518151036103595761271383516144b8565b9260005b815181101561276e578061275973ffffffffffffffffffffffffffffffffffffffff6127466127699486614345565b51166127528387614345565b519061505e565b6127638288614345565b52614ecf565b612717565b505050610dab604051928284938452830190613f37565b813573ffffffffffffffffffffffffffffffffffffffff811681036104a85781529084019084016126de565b346104a8576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a8576127e9613c08565b73ffffffffffffffffffffffffffffffffffffffff91827f00000000000000000000000000000000000000000000000000000000000000001680301461262b577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc9084825416036126015761285c614f14565b6040519361286985613d92565b600085527f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff16156128a4575050506103579150614fcc565b83929316906040517f52d1902d0000000000000000000000000000000000000000000000000000000081528481600481865afa6000918161295e575b5061290f5760046040517f81007d10000000000000000000000000000000000000000000000000000000008152fd5b036125a85761291d82614fcc565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a2835115801590612956576124cf57005b5060006124c9565b9091508581813d8311612986575b6129768183613de6565b810103126104a8575190876128e0565b503d61296c565b346104a8577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60a0813601126104a8576129c5613c08565b6129cd613c2b565b9067ffffffffffffffff906044358281116104a8576129f0903690600401613e8d565b6064358381116104a857612a08903690600401613e8d565b926084359081116104a857612a21903690600401613f1c565b9473ffffffffffffffffffffffffffffffffffffffff95868416963388141580612c9b575b610c5f578351865103610359578616938415610c3557858488612a68936153c4565b60005b8351811015612af457612a7e8185614345565b5190612a8a8188614345565b5182600052606560209080825260406000208c600052825260406000205494838610610c0b5783612aef968e8360005284865260406000209060005285520360406000205560005281526040600020908860005252610306604060002091825461442a565b612a6b565b5090949392919382876040517f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb339180612b2f8a8c8361561f565b0390a43b612b3957005b6000602094612bb3612ba497612b9494604051998a98899788967fbc197c81000000000000000000000000000000000000000000000000000000009e8f89523360048a0152602489015260a0604489015260a4880190613f37565b9084878303016064880152613f37565b91848303016084850152613caf565b03925af160009181612c7b575b50612c5257612bcd61567c565b6308c379a014612c015760046040517fde62dcd0000000000000000000000000000000000000000000000000000000008152fd5b612c0961569a565b80612c145750610b0a565b610b83906040519182917f08c379a0000000000000000000000000000000000000000000000000000000008352602060048401526024830190613caf565b7fffffffff000000000000000000000000000000000000000000000000000000001603610bb257005b612c9491925060203d8111610c0457610bf58183613de6565b9083612bc0565b5087600052606660205260406000203360005260205260ff6040600020541615612a46565b346104a85760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a8576024356101335460ff8160a01c1691828102928184041490151715612d37576103e860409273ffffffffffffffffffffffffffffffffffffffff845193168352046020820152f35b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b346104a85760c07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85760043573ffffffffffffffffffffffffffffffffffffffff811681036104a857612dbd613c2b565b9060443573ffffffffffffffffffffffffffffffffffffffff811681036104a85760643573ffffffffffffffffffffffffffffffffffffffff811681036104a85760843567ffffffffffffffff81116104a857612e1e903690600401613d47565b94909260a4359384151585036104a8576000549660ff8860081c16159788809961341a575b8015613403575b156133d9578860017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008316176000556133aa575b50604051612e8b81613d92565b6000815260ff60005460081c16156131e75780519067ffffffffffffffff8211611f06578190612ebc6067546141a4565b601f8111613300575b50602090601f831160011461321c57600092613211575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c1916176067555b60ff60005460081c16156131e757612f2633614f5f565b60ff60005460081c16156131e7577fffffffffffffffffffffffff00000000000000000000000000000000000000009373ffffffffffffffffffffffffffffffffffffffff61012d98168589541617885573ffffffffffffffffffffffffffffffffffffffff61013291168582541617905567ffffffffffffffff8111611f06578061012e92612fba82611dec86546141a4565b600090601f83116001146131265760009261311b575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8260011b9260031b1c19161790555b741e000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff61013392167fffffffffffffffffffffff0000000000000000000000000000000000000000008354161717905573ffffffffffffffffffffffffffffffffffffffff6101379216908254161790557fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff74ff0000000000000000000000000000000000000000835492151560a01b1691161790556130c657005b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff600054166000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160018152a1005b013590508980612fd0565b90917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01691846000527fbdaadd9f750d0166045bf387a364eadd28ba243e04512a47282aa5147a68e37f9260005b8181106131cf5750908460019594939210613197575b505050811b019055613002565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88560031b161c1991013516905589808061318a565b91936020600181928787013581550195019201613174565b60046040517fd7e6bcf8000000000000000000000000000000000000000000000000000000008152fd5b015190508a80612edc565b925060676000527f9787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae906000935b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0841685106132e55760019450837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08116106132ae575b505050811b01606755612f0f565b01517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88460031b161c191690558a80806132a0565b81810151835560209485019460019093019290910190613249565b9091506067600052601f830160051c7f9787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae0160208410613383575b908392915b601f820160051c7f9787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae0181106133745750612ec5565b6000815584935060010161333f565b507f9787eeb91fe3101235e4a76063c7023ecb40f923f97916639c598592fa30d6ae61333a565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011760005588612e7e565b60046040517f0dc149f0000000000000000000000000000000000000000000000000000000008152fd5b50303b158015612e4a5750600160ff821614612e4a565b50600160ff821610612e43565b346104a85761343536613cf2565b73ffffffffffffffffffffffffffffffffffffffff9182610131541633141580613556575b611091576134688282614437565b613500575b6040519261347a84613d92565b6000845284169384156103835761035794613494836158cb565b5061349e846158cb565b5082600052606560205260406000208160005260205260406000206134c485825461442a565b905560006040518481528560208201527fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6260403392a433615727565b61013280547fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff75ffff0000000000000000000000000000000000000000600161ffff8460a01c160160a01b16911617905561346d565b5082610132541633141561345a565b346104a85760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a857602061ffff6101325460a01c16604051908152f35b346104a8576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85760043580600052610136825260ff60406000205460081c16156137ac5760005261013481526040600020906040519182600061012e9081549161361b836141a4565b9060019387858216918260001461377257505060011461371c575b5050600091845494613647866141a4565b958281169081156136df57506001146136a3575b50505061368f9250037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08101845283613de6565b610dab604051928284938452830190613caf565b6000908152868120959350905b868483106136c95750505061368f93500185808061365b565b86548385015295810195889550909101906136b0565b91505061368f959293507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff009150168252801515020185808061365b565b8692506000527fbdaadd9f750d0166045bf387a364eadd28ba243e04512a47282aa5147a68e37f6000905b82821061375a5750508301018680613636565b80548983018501528895508793909101908401613747565b915093507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0091501682850152801515028301018680613636565b60249061ffff604051917ffba27f87000000000000000000000000000000000000000000000000000000008352166004820152fd5b346104a85760007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85761012d5460a01c60ff16156138ac57610dab60405161382e81613dae565b600781527f202842657461290000000000000000000000000000000000000000000000000060208201525b6117ac602c60405180937f457374666f72204974656d730000000000000000000000000000000000000000602083015261389c8151809260208686019101613c8c565b810103600c810184520182613de6565b610dab6040516138bb81613d92565b60008152613859565b346104a8576020807ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a85760043567ffffffffffffffff81116104a857613914903690600401613c4e565b919061391f83613e27565b9161392d6040519384613de6565b83835261393984613e27565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe09284830191840136833761396d86613e27565b9561397b6040519788613de6565b80875261398781613e27565b878501950136863760005b818110613a27575050506040519485946040860190604087525180915260608601929060005b818110613a01575050508482038584015251808252908201929160005b8281106139e457505050500390f35b835163ffffffff16855286955093810193928101926001016139d5565b919596509192848082613a176001948a51613c7f565b01960191019187969593926139b8565b80613a8d613a6b613a436106d160019587899e9a9c9d9e6142f7565b61ffff166000526101366020526040600020549063ffffffff60ff8360c81c169260d01c1690565b63ffffffff613a7a858a614345565b91169052613a88838c614345565b6142eb565b019695949296613992565b346104a85760207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a8576004357fffffffff0000000000000000000000000000000000000000000000000000000081168091036104a857807f2a55205a0000000000000000000000000000000000000000000000000000000060209214908115613b2d575b506040519015158152f35b7fd9b67a2600000000000000000000000000000000000000000000000000000000811491508115613b91575b8115613b67575b5082613b22565b7f01ffc9a70000000000000000000000000000000000000000000000000000000091501482613b60565b7f0e89341c0000000000000000000000000000000000000000000000000000000081149150613b59565b346104a85760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc3601126104a8576020613c00613bf7613c08565b6024359061505e565b604051908152f35b6004359073ffffffffffffffffffffffffffffffffffffffff821682036104a857565b6024359073ffffffffffffffffffffffffffffffffffffffff821682036104a857565b9181601f840112156104a85782359167ffffffffffffffff83116104a8576020808501948460051b0101116104a857565b906010821015610ecd5752565b60005b838110613c9f5750506000910152565b8181015183820152602001613c8f565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f602093613ceb81518092818752878088019101613c8c565b0116010190565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc60609101126104a85760043573ffffffffffffffffffffffffffffffffffffffff811681036104a857906024359060443590565b9181601f840112156104a85782359167ffffffffffffffff83116104a857602083818601950101116104a857565b610200810190811067ffffffffffffffff821117611f0657604052565b6020810190811067ffffffffffffffff821117611f0657604052565b6040810190811067ffffffffffffffff821117611f0657604052565b6060810190811067ffffffffffffffff821117611f0657604052565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff821117611f0657604052565b67ffffffffffffffff8111611f065760051b60200190565b9291613e4a82613e27565b91613e586040519384613de6565b829481845260208094019160051b81019283116104a857905b828210613e7e5750505050565b81358152908301908301613e71565b9080601f830112156104a857816020613ea893359101613e3f565b90565b67ffffffffffffffff8111611f0657601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b929192613ef182613eab565b91613eff6040519384613de6565b8294818452818301116104a8578281602093846000960137010152565b9080601f830112156104a857816020613ea893359101613ee5565b90815180825260208080930193019160005b828110613f57575050505090565b835185529381019392810192600101613f49565b9060607ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc8301126104a85760043573ffffffffffffffffffffffffffffffffffffffff811681036104a8579167ffffffffffffffff916024358381116104a85782613fd891600401613c4e565b939093926044359182116104a857613ff291600401613c4e565b9091565b6004359061ffff821682036104a857565b359061ffff821682036104a857565b906011821015610ecd5752565b906006821015610ecd5752565b61403b828251614016565b60208101511515602083015260408101511515604083015261ffff80606083015116606084015261407460808301516080850190614023565b60a08201511660a083015262ffffff60c08201511660c083015260e0810151600190810b60e084015261010080830151820b9084015261012080830151820b9084015261014080830151820b9084015261016080830151820b9084015261018080830151820b908401526101a09081830151900b908301526140ff6101c08083015190840190613c7f565b63ffffffff6101e08092015116910152565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc906020828201126104a8576004359167ffffffffffffffff83116104a85782610240920301126104a85760040190565b90815180825260208080930193019160005b828110614182575050505090565b9091929382610200826141986001948951614030565b01950193929101614174565b90600182811c921680156141ed575b60208310146141be57565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b91607f16916141b3565b601f8111614203575050565b60009061012e82527fbdaadd9f750d0166045bf387a364eadd28ba243e04512a47282aa5147a68e37f906020601f850160051c8301941061425f575b601f0160051c01915b82811061425457505050565b818155600101614248565b909250829061423f565b6040519061427682613d75565b816101e06000918281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c08201520152565b6011821015610ecd5752565b6010821015610ecd5752565b91908110156143075760051b0190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b3561ffff811681036104a85790565b80518210156143075760209160051b010190565b9061436382613e27565b6143706040519182613de6565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe061439e8294613e27565b019060005b8281106143af57505050565b6020906143ba614269565b828285010152016143a3565b61ffff1680600052610136908160205260ff60406000205460081c16156143f95760005260205260ff6040600020541690565b602490604051907ffba27f870000000000000000000000000000000000000000000000000000000082526004820152fd5b91908201809211612d3757565b6000929161ffff82101561448e578160005261012f90816020526040600020548015614477575b906144689161442a565b91600052602052604060002055565b61013060205260406000204290556001955061445e565b60046040517f3315a06b000000000000000000000000000000000000000000000000000000008152fd5b906144c282613e27565b6144cf6040519182613de6565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06144fd8294613e27565b0190602036910137565b61ffff1680600052610136908160205260ff60406000205460081c16156143f957600052602052604060002090565b9035907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1813603018212156104a8570180359067ffffffffffffffff82116104a8576020019181360383136104a857565b601f82602094937fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0938186528686013760008582860101520116010190565b9054613ea894926145da8360ff8416614016565b60ff8260081c161515602084015260ff8260101c161515604084015263ffffffff61ffff92838160181c16606086015261461d6080860160ff8360281c16614023565b838160301c1660a086015262ffffff8160401c1660c086015260018160581c810b60e08701528160681c810b6101008701528160781c810b6101208701528160881c810b6101408701528160981c810b6101608701528160a81c810b6101808701528160b81c900b6101a086015261469f6101c0860160ff8360c81c16613c7f565b60d01c166101e08401521661020082015261024090816102208201520191614587565b35908160010b82036104a857565b90357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1823603018112156104a857016020813591019167ffffffffffffffff82116104a85781360383136104a857565b60e081019161472e83614336565b60009061ffff80911615614bd15773a73f74c0fbed265a656293a1a91a9506678e3d54908061475c87614336565b1683526101369560209187835260409081862094803b15614bcd578251907f98ebdd980000000000000000000000000000000000000000000000000000000082528360048301526147ac8a6146c2565b96600197880b60448401526147c2878c016146c2565b880b60648401526147d4858c016146c2565b880b60848401526147e760608c016146c2565b880b60a48401526147fa60808c016146c2565b880b60c484015261480d60a08c016146c2565b880b60e484015261482060c08c016146c2565b880b6101048401528361483287614007565b166101248401526101008b01356011811015614bc95761485790610144850190614016565b6101208b0135801515809103614bc9576101648401526101408b01356010811015614bc95761488b90610184850190613c7f565b6101608b013563ffffffff8116809103614bc9576101a4840152836148b36101808d01614007565b166101c48401526101a08b01356006811015614bc9576148d8906101e4850190614023565b836148e66101c08d01614007565b166102048401526101e08b013562ffffff8116809103614bc95792809281808c948f9761022483015261497961020089019861494861493c6149288c846146d0565b610240610244890152610284880191614587565b916102208101906146d0565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffbc86840301610264870152614587565b90602483015203915af48015614bbf57614b73575b506149b3906149bb969798999a836149a587614336565b168a5286528389209a614536565b959093614336565b168652610134835285209467ffffffffffffffff8411614b46576149df86546141a4565b601f8111614afd575b508092601f8511600114614a60575092939291849182614a35575b50507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff91921b9260031b1c1916179055565b013591507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff38614a03565b868252808220939185917fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0831691905b88838310614ae35750505010614aab575b505050811b019055565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60f88560031b161c19910135169055388080614aa1565b868601358855909601959384019387935090810190614a90565b8660005283600020601f860160051c810191858710614b3c575b601f0160051c019086905b828110614b305750506149e8565b60008155018690614b22565b9091508190614b17565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526041600452fd5b67ffffffffffffffff819b989b11614b925783529598956149b361498e565b60248b7f4e487b710000000000000000000000000000000000000000000000000000000081526041600452fd5b84513d8a823e3d90fd5b8980fd5b8680fd5b60046040517f3f6cc768000000000000000000000000000000000000000000000000000000008152fd5b90614c0582613e27565b614c126040519182613de6565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0614c408294613e27565b019060005b828110614c5157505050565b806060602080938501015201614c45565b91908110156143075760051b810135907ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdc1813603018212156104a8570190565b90614cb590606083526060830190614162565b906020918181038383015282808551928381520194019060005b818110614d575750505060408184039101528251908183528083019281808460051b8301019501936000915b848310614d0b5750505050505090565b9091929394958480614d47837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe086600196030187528a51613caf565b9801930193019194939290614cfb565b825161ffff1686529484019491840191600101614ccf565b60e0810161ffff614d838161052184614336565b15614e955780614d9283614336565b16906000918252610136908160205260ff604084205416610100860135906011821015614e91576011811015614e645714159384614e06575b50505050614ddc57613ea890614720565b60046040517f537d379e000000000000000000000000000000000000000000000000000000008152fd5b614e139192939450614336565b16825260205260ff604082205416906011821015614e375750151538808080614dcb565b807f4e487b7100000000000000000000000000000000000000000000000000000000602492526021600452fd5b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526021600452fd5b8480fd5b614ea0602492614336565b6040517ffba27f8700000000000000000000000000000000000000000000000000000000815291166004820152fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114612d375760010190565b908160209103126104a8575180151581036104a85790565b73ffffffffffffffffffffffffffffffffffffffff60fb54163303614f3557565b60046040517f6db2465f000000000000000000000000000000000000000000000000000000008152fd5b60fb549073ffffffffffffffffffffffffffffffffffffffff80911691827fffffffffffffffffffffffff000000000000000000000000000000000000000082161760fb55167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b803b156150345773ffffffffffffffffffffffffffffffffffffffff7f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91167fffffffffffffffffffffffff0000000000000000000000000000000000000000825416179055565b60046040517f71ab98ae000000000000000000000000000000000000000000000000000000008152fd5b73ffffffffffffffffffffffffffffffffffffffff1690811561509857600052606560205260406000209060005260205260406000205490565b60046040517fb487c631000000000000000000000000000000000000000000000000000000008152fd5b919073ffffffffffffffffffffffffffffffffffffffff80931615808115615251575b8115615249575b5061524457805190815b61513e5750505061013154161561510957565b617a69460361511457565b60046040517f7a47c9a2000000000000000000000000000000000000000000000000000000008152fd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff809201918261516e8184614345565b51600090815261012f6020818152604093848420549561518e828b614345565b518088039780891161521757918a989796959493916151b493146151bf575b5088614345565b5183525220556150f6565b610132907fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff75ffff000000000000000000000000000000000000000083549260a09061ffff85831c1601901b169116179055386151ad565b6024877f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b505050565b9050386150ec565b83511591506150e5565b919073ffffffffffffffffffffffffffffffffffffffff809316158081156153ba575b81156153b2575b5061524457929190835193845b6152a757505090915061013154161561510957565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff809501906152d68282614345565b5195600096875261012f60209781895260409182822054996152f88789614345565b5194858c03958c87116153855788999a9b9c9897981461532d575b5061531e8688614345565b51835252205594939291615292565b610132907fffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffffff75ffff000000000000000000000000000000000000000083549260a09061ffff85831c1601901b16911617905538615313565b6024857f4e487b710000000000000000000000000000000000000000000000000000000081526011600452fd5b905038615285565b835115915061527e565b92919073ffffffffffffffffffffffffffffffffffffffff8094169081158015615616575b801561560b575b61560457841680159081156155f8575b50156154a05750805190815b615420575050505b61013154161561510957565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80920191826154508184614345565b51600090815261012f60208181526040938484205495615470828b614345565b518088039780891161521757918a9897969594939161549593146151bf575088614345565b51835252205561540c565b908092505191826000935b61556f575050816154e7575b50156154145760046040517fd72db536000000000000000000000000000000000000000000000000000000008152fd5b90508161013854168015918215615501575b5050386154b7565b60209192506024604051809481937fe934302400000000000000000000000000000000000000000000000000000000835260048301525afa90811561049c57600091615551575b501538806154f9565b615569915060203d8111610495576104878183613de6565b38615548565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff016155b761559e8284614345565b5160005261013660205260ff60406000205460081c1690565b806155d1575b6155c8575b806154ab565b600193506155c2565b506155dc8183614345565b5160005261013660205260ff60406000205460101c16156155bd565b61dead91501438615400565b5050505050565b5084811682146153f0565b508351156153e9565b9091615636613ea893604084526040840190613f37565b916020818403910152613f37565b908160209103126104a857517fffffffff00000000000000000000000000000000000000000000000000000000811681036104a85790565b60009060033d1161568957565b905060046000803e60005160e01c90565b600060443d10613ea8576040517ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc91823d016004833e815167ffffffffffffffff918282113d6024840111176157165781840194855193841161571e573d850101602084870101116157165750613ea892910160200190613de6565b949350505050565b50949350505050565b919390803b615737575050505050565b6157ac9360006020946040518097819682957ff23a6e61000000000000000000000000000000000000000000000000000000009b8c855273ffffffffffffffffffffffffffffffffffffffff80961660048601528660248601526044850152606484015260a0608484015260a4830190613caf565b0393165af1600091816157f8575b506157c757612bcd61567c565b7fffffffff000000000000000000000000000000000000000000000000000000001603610bb2573880808080615604565b61581191925060203d8111610c0457610bf58183613de6565b90386157ba565b91939290803b615829575050505050565b6157ac936000602094604051809781968295612ba461589a7fbc197c81000000000000000000000000000000000000000000000000000000009d8e875273ffffffffffffffffffffffffffffffffffffffff809816600488015288602488015260a0604488015260a4870190613f37565b7ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc9384878303016064880152613f37565b604051906158d882613dae565b60018252602082016020368237825115614307575290565b909190156158fc575090565b815115612c145750805190602001fdfea2646970667358221220ea3843fb29b5d60d55d66e48ae35709fc8238a867c345c7f16ad6499097d31a564736f6c63430008140033
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Validator ID :
0 FTM
Amount Staked
0
Amount Delegated
0
Staking Total
0
Staking Start Epoch
0
Staking Start Time
0
Proof of Importance
0
Origination Score
0
Validation Score
0
Active
0
Online
0
Downtime
0 s
Address | Amount | claimed Rewards | Created On Epoch | Created On |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.