Source Code
Overview
S Balance
S Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
EstforLibrary
Compiler Version
v0.8.28+commit.7893614a
Optimization Enabled:
Yes with 9999999 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {IPlayers} from "./interfaces/IPlayers.sol";
// solhint-disable-next-line no-global-import
import "./globals/all.sol";
// This file contains methods for interacting with generic functions like trimming strings, lowercase etc.
// Also has some shared functions for rewards
library EstforLibrary {
error RandomRewardsMustBeInOrder(uint16 chance1, uint16 chance2);
error RandomRewardNoDuplicates();
error GuaranteedRewardsNoDuplicates();
error TooManyGuaranteedRewards();
error TooManyRandomRewards();
function isWhitespace(bytes1 _char) internal pure returns (bool) {
return
_char == 0x20 || // Space
_char == 0x09 || // Tab
_char == 0x0a || // Line feed
_char == 0x0D || // Carriage return
_char == 0x0B || // Vertical tab
_char == 0x00; // empty byte
}
function leftTrim(string memory str) internal pure returns (string memory) {
bytes memory b = bytes(str);
uint256 strLen = b.length;
uint256 start = type(uint256).max;
// Find the index of the first non-whitespace character
for (uint256 i = 0; i < strLen; ++i) {
bytes1 char = b[i];
if (!isWhitespace(char)) {
start = i;
break;
}
}
if (start == type(uint256).max) {
return "";
}
// Copy the remainder to a new string
bytes memory trimmedBytes = new bytes(strLen - start);
for (uint256 i = start; i < strLen; ++i) {
trimmedBytes[i - start] = b[i];
}
return string(trimmedBytes);
}
function rightTrim(string calldata str) internal pure returns (string memory) {
bytes memory b = bytes(str);
uint256 strLen = b.length;
if (strLen == 0) {
return "";
}
int end = -1;
// Find the index of the last non-whitespace character
for (int i = int(strLen) - 1; i >= 0; --i) {
bytes1 char = b[uint256(i)];
if (!isWhitespace(char)) {
end = i;
break;
}
}
if (end == -1) {
return "";
}
bytes memory trimmedBytes = new bytes(uint256(end) + 1);
for (uint256 i = 0; i <= uint256(end); ++i) {
trimmedBytes[i] = b[i];
}
return string(trimmedBytes);
}
function trim(string calldata str) external pure returns (string memory) {
return leftTrim(rightTrim(str));
}
// Assumes the string is already trimmed
function containsValidNameCharacters(string calldata name) external pure returns (bool) {
bytes memory b = bytes(name);
bool lastCharIsWhitespace;
for (uint256 i = 0; i < b.length; ++i) {
bytes1 char = b[i];
bool isUpperCaseLetter = (char >= 0x41) && (char <= 0x5A); // A-Z
bool isLowerCaseLetter = (char >= 0x61) && (char <= 0x7A); // a-z
bool isDigit = (char >= 0x30) && (char <= 0x39); // 0-9
bool isSpecialCharacter = (char == 0x2D) || (char == 0x5F) || (char == 0x2E) || (char == 0x20); // "-", "_", ".", and " "
bool _isWhitespace = isWhitespace(char);
bool hasMultipleWhitespaceInRow = lastCharIsWhitespace && _isWhitespace;
lastCharIsWhitespace = _isWhitespace;
if ((!isUpperCaseLetter && !isLowerCaseLetter && !isDigit && !isSpecialCharacter) || hasMultipleWhitespaceInRow) {
return false;
}
}
return true;
}
function containsValidDiscordCharacters(string calldata discord) external pure returns (bool) {
bytes memory discordBytes = bytes(discord);
for (uint256 i = 0; i < discordBytes.length; ++i) {
bytes1 char = discordBytes[i];
bool isUpperCaseLetter = (char >= 0x41) && (char <= 0x5A); // A-Z
bool isLowerCaseLetter = (char >= 0x61) && (char <= 0x7A); // a-z
bool isDigit = (char >= 0x30) && (char <= 0x39); // 0-9
if (!isUpperCaseLetter && !isLowerCaseLetter && !isDigit) {
return false;
}
}
return true;
}
function containsValidTelegramCharacters(string calldata telegram) external pure returns (bool) {
bytes memory telegramBytes = bytes(telegram);
for (uint256 i = 0; i < telegramBytes.length; ++i) {
bytes1 char = telegramBytes[i];
bool isUpperCaseLetter = (char >= 0x41) && (char <= 0x5A); // A-Z
bool isLowerCaseLetter = (char >= 0x61) && (char <= 0x7A); // a-z
bool isDigit = (char >= 0x30) && (char <= 0x39); // 0-9
bool isPlus = char == 0x2B; // "+"
if (!isUpperCaseLetter && !isLowerCaseLetter && !isDigit && !isPlus) {
return false;
}
}
return true;
}
function containsValidTwitterCharacters(string calldata twitter) external pure returns (bool) {
bytes memory twitterBytes = bytes(twitter);
for (uint256 i = 0; i < twitterBytes.length; ++i) {
bytes1 char = twitterBytes[i];
bool isUpperCaseLetter = (char >= 0x41) && (char <= 0x5A); // A-Z
bool isLowerCaseLetter = (char >= 0x61) && (char <= 0x7A); // a-z
bool isDigit = (char >= 0x30) && (char <= 0x39); // 0-9
if (!isUpperCaseLetter && !isLowerCaseLetter && !isDigit) {
return false;
}
}
return true;
}
function containsBaselineSocialNameCharacters(string calldata socialMediaName) external pure returns (bool) {
bytes memory socialMediaNameBytes = bytes(socialMediaName);
for (uint256 i = 0; i < socialMediaNameBytes.length; ++i) {
bytes1 char = socialMediaNameBytes[i];
bool isUpperCaseLetter = (char >= 0x41) && (char <= 0x5A); // A-Z
bool isLowerCaseLetter = (char >= 0x61) && (char <= 0x7A); // a-z
bool isDigit = (char >= 0x30) && (char <= 0x39); // 0-9
bool isUnderscore = char == 0x5F; // "_"
bool isPeriod = char == 0x2E; // "."
bool isPlus = char == 0x2B; // "+"
if (!isUpperCaseLetter && !isLowerCaseLetter && !isDigit && !isUnderscore && !isPeriod && !isPlus) {
return false;
}
}
return true;
}
function toLower(string memory str) internal pure returns (string memory) {
bytes memory lowerStr = abi.encodePacked(str);
for (uint256 i = 0; i < lowerStr.length; ++i) {
bytes1 char = lowerStr[i];
if ((char >= 0x41) && (char <= 0x5A)) {
// So we add 32 to make it lowercase
lowerStr[i] = bytes1(uint8(char) + 32);
}
}
return string(lowerStr);
}
// This should match the one below, useful when a calldata array is needed and for external testing
function _binarySearchMemory(uint64[] calldata array, uint256 target) internal pure returns (uint256) {
uint256 low = 0;
uint256 high = array.length - 1;
while (low <= high) {
uint256 mid = low + (high - low) / 2;
if (array[mid] == target) {
return mid; // Element found
} else if (array[mid] < target) {
low = mid + 1;
} else {
// Check to prevent underflow
if (mid != 0) {
high = mid - 1;
} else {
// If mid is 0 and _arr[mid] is not the target, the element is not in the array
break;
}
}
}
return type(uint256).max; // Element not found
}
function binarySearchMemory(uint64[] calldata array, uint256 target) external pure returns (uint256) {
return _binarySearchMemory(array, target);
}
// This should match the one above
function _binarySearch(uint64[] storage array, uint256 target) internal view returns (uint256) {
uint256 low = 0;
uint256 high = array.length - 1;
while (low <= high) {
uint256 mid = low + (high - low) / 2;
if (array[mid] == target) {
return mid; // Element found
} else if (array[mid] < target) {
low = mid + 1;
} else {
// Check to prevent underflow
if (mid != 0) {
high = mid - 1;
} else {
// If mid is 0 and _arr[mid] is not the target, the element is not in the array
break;
}
}
}
return type(uint256).max; // Element not found
}
function binarySearch(uint64[] storage array, uint256 target) external view returns (uint256) {
return _binarySearch(array, target);
}
function _shuffleArray(uint64[] memory array, uint256 randomNumber) internal pure returns (uint64[] memory output) {
for (uint256 i; i < array.length; ++i) {
uint256 n = i + (randomNumber % (array.length - i));
if (i != n) {
uint64 temp = array[n];
array[n] = array[i];
array[i] = temp;
}
}
return array;
}
function _getRandomInRange16(
uint256 randomWord,
uint256 shift,
int16 minValue,
int16 maxValue
) internal pure returns (int16) {
return int16(minValue + (int16(int256((randomWord >> shift) & 0xFFFF) % (maxValue - minValue + 1))));
}
function _getRandomFromArray16(
uint256 randomWord,
uint256 shift,
uint16[] storage arr,
uint256 arrLength
) internal view returns (uint16) {
return arr[_getRandomIndexFromArray16(randomWord, shift, arrLength)];
}
function _getRandomFrom3ElementArray16(
uint256 randomWord,
uint256 shift,
uint16[3] memory arr
) internal pure returns (uint16) {
return arr[_getRandomIndexFromArray16(randomWord, shift, arr.length)];
}
function _getRandomIndexFromArray16(
uint256 randomWord,
uint256 shift,
uint256 arrLength
) internal pure returns (uint16) {
return uint16(((randomWord >> shift) & 0xFFFF) % arrLength);
}
function setActionGuaranteedRewards(
GuaranteedReward[] calldata guaranteedRewards,
ActionRewards storage actionRewards
) external {
_setActionGuaranteedRewards(guaranteedRewards, actionRewards);
}
function setActionRandomRewards(RandomReward[] calldata randomRewards, ActionRewards storage actionRewards) external {
_setActionRandomRewards(randomRewards, actionRewards);
}
function _setActionGuaranteedRewards(
GuaranteedReward[] calldata guaranteedRewards,
ActionRewards storage actionRewards
) internal {
uint256 guaranteedRewardsLength = guaranteedRewards.length;
if (guaranteedRewardsLength != 0) {
actionRewards.guaranteedRewardTokenId1 = guaranteedRewards[0].itemTokenId;
actionRewards.guaranteedRewardRate1 = guaranteedRewards[0].rate;
}
if (guaranteedRewardsLength > 1) {
actionRewards.guaranteedRewardTokenId2 = guaranteedRewards[1].itemTokenId;
actionRewards.guaranteedRewardRate2 = guaranteedRewards[1].rate;
require(
actionRewards.guaranteedRewardTokenId1 != actionRewards.guaranteedRewardTokenId2,
GuaranteedRewardsNoDuplicates()
);
}
if (guaranteedRewardsLength > 2) {
actionRewards.guaranteedRewardTokenId3 = guaranteedRewards[2].itemTokenId;
actionRewards.guaranteedRewardRate3 = guaranteedRewards[2].rate;
uint256 bounds = guaranteedRewardsLength - 1;
for (uint256 i; i < bounds; ++i) {
require(
guaranteedRewards[i].itemTokenId != guaranteedRewards[guaranteedRewardsLength - 1].itemTokenId,
GuaranteedRewardsNoDuplicates()
);
}
}
require(guaranteedRewardsLength <= 3, TooManyGuaranteedRewards());
}
// Random rewards have most common one first
function _setActionRandomRewards(
RandomReward[] calldata randomRewards,
ActionRewards storage actionRewards
) internal {
uint256 randomRewardsLength = randomRewards.length;
if (randomRewardsLength != 0) {
actionRewards.randomRewardTokenId1 = randomRewards[0].itemTokenId;
actionRewards.randomRewardChance1 = randomRewards[0].chance;
actionRewards.randomRewardAmount1 = randomRewards[0].amount;
}
if (randomRewardsLength > 1) {
actionRewards.randomRewardTokenId2 = randomRewards[1].itemTokenId;
actionRewards.randomRewardChance2 = randomRewards[1].chance;
actionRewards.randomRewardAmount2 = randomRewards[1].amount;
require(
actionRewards.randomRewardChance2 <= actionRewards.randomRewardChance1,
RandomRewardsMustBeInOrder(randomRewards[0].chance, randomRewards[1].chance)
);
require(actionRewards.randomRewardTokenId1 != actionRewards.randomRewardTokenId2, RandomRewardNoDuplicates());
}
if (randomRewardsLength > 2) {
actionRewards.randomRewardTokenId3 = randomRewards[2].itemTokenId;
actionRewards.randomRewardChance3 = randomRewards[2].chance;
actionRewards.randomRewardAmount3 = randomRewards[2].amount;
require(
actionRewards.randomRewardChance3 <= actionRewards.randomRewardChance2,
RandomRewardsMustBeInOrder(randomRewards[1].chance, randomRewards[2].chance)
);
uint256 bounds = randomRewardsLength - 1;
for (uint256 i; i < bounds; ++i) {
require(
randomRewards[i].itemTokenId != randomRewards[randomRewardsLength - 1].itemTokenId,
RandomRewardNoDuplicates()
);
}
}
if (randomRewards.length > 3) {
actionRewards.randomRewardTokenId4 = randomRewards[3].itemTokenId;
actionRewards.randomRewardChance4 = randomRewards[3].chance;
actionRewards.randomRewardAmount4 = randomRewards[3].amount;
require(
actionRewards.randomRewardChance4 <= actionRewards.randomRewardChance3,
RandomRewardsMustBeInOrder(randomRewards[2].chance, randomRewards[3].chance)
);
uint256 bounds = randomRewards.length - 1;
for (uint256 i; i < bounds; ++i) {
require(
randomRewards[i].itemTokenId != randomRewards[randomRewards.length - 1].itemTokenId,
RandomRewardNoDuplicates()
);
}
}
require(randomRewards.length <= 4, TooManyRandomRewards());
}
function _get16bitSlice(bytes memory b, uint256 index) internal pure returns (uint16) {
uint256 key = index * 2;
return uint16(b[key] | (bytes2(b[key + 1]) >> 8));
}
// Helper function to get random value between min and max (inclusive) for uint8
function _getRandomInRange8(uint8 minValue, uint8 maxValue, uint8 randomness) internal pure returns (uint8) {
if (maxValue <= minValue) {
return minValue;
}
uint8 range = maxValue - minValue + 1;
// Use modulo to get value in range and add minValue
return uint8((uint16(randomness) % uint16(range)) + uint16(minValue));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {Skill, Attire, CombatStyle, CombatStats} from "./misc.sol";
import {GuaranteedReward, RandomReward} from "./rewards.sol";
enum ActionQueueStrategy {
OVERWRITE,
APPEND,
KEEP_LAST_IN_PROGRESS
}
struct QueuedActionInput {
Attire attire;
uint16 actionId;
uint16 regenerateId; // Food (combat), maybe something for non-combat later
uint16 choiceId; // Melee/Ranged/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
uint8 combatStyle; // CombatStyle specific style of combat
uint40 petId; // id of the pet (can be empty)
}
struct QueuedAction {
uint16 actionId;
uint16 regenerateId; // Food (combat), maybe something for non-combat later
uint16 choiceId; // Melee/Ranged/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
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
bytes1 packed; // 1st bit is isValid (not used yet), 2nd bit is for hasPet (decides if the 2nd storage slot is read)
uint8 combatStyle;
uint24 reserved;
// Next storage slot
uint40 petId; // id of the pet (can be empty)
}
// This is only used as an input arg (and events)
struct ActionInput {
uint16 actionId;
ActionInfo info;
GuaranteedReward[] guaranteedRewards;
RandomReward[] randomRewards;
CombatStats combatStats;
}
struct ActionInfo {
uint8 skill;
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
uint8 worldLocation; // 0 is the main starting world
bool isFullModeOnly;
bool isAvailable;
uint16 questPrerequisiteId;
}
uint16 constant ACTIONCHOICE_MELEE_BASIC_SWORD = 1500;
uint16 constant ACTIONCHOICE_MAGIC_SHADOW_BLAST = 2000;
uint16 constant ACTIONCHOICE_RANGED_BASIC_BOW = 3000;
// Allows for 2, 4 or 8 hour respawn time
uint256 constant SPAWN_MUL = 1000;
uint256 constant RATE_MUL = 1000;
uint256 constant GUAR_MUL = 10; // Guaranteeded reward multiplier (1 decimal, allows for 2 hour action times)
uint256 constant MAX_QUEUEABLE_ACTIONS = 3; // Available slots to queue actions// SPDX-License-Identifier: MIT pragma solidity ^0.8.28; import "./actions.sol"; import "./items.sol"; import "./misc.sol"; import "./players.sol"; import "./rewards.sol"; import "./quests.sol"; import "./promotions.sol"; import "./clans.sol"; import "./pets.sol";
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {IBank} from "../interfaces/IBank.sol";
enum ClanRank {
NONE, // Not in a clan
COMMONER, // Member of the clan
SCOUT, // Invite and kick commoners
COLONEL, // Can launch attacks and assign combatants
TREASURER, // Can withdraw from bank
LEADER, // Can edit clan details
OWNER // Can do everything and transfer ownership
}
enum BattleResultEnum {
DRAW,
WIN,
LOSE
}
struct ClanBattleInfo {
uint40 lastClanIdAttackOtherClanIdCooldownTimestamp;
uint8 numReattacks;
uint40 lastOtherClanIdAttackClanIdCooldownTimestamp;
uint8 numReattacksOtherClan;
}
// Packed for gas efficiency
struct Vault {
bool claimed; // Only applies to the first one, if it's claimed without the second one being claimed
uint40 timestamp;
uint80 amount;
uint40 timestamp1;
uint80 amount1;
}
struct VaultClanInfo {
IBank bank;
uint96 totalBrushLocked;
// New storage slot
uint40 attackingCooldownTimestamp;
uint40 assignCombatantsCooldownTimestamp;
bool currentlyAttacking;
uint24 defendingVaultsOffset;
uint40 blockAttacksTimestamp;
uint8 blockAttacksCooldownHours;
bool isInMMRArray;
uint40 superAttackCooldownTimestamp;
uint64[] playerIds;
Vault[] defendingVaults; // Append only, and use defendingVaultsOffset to decide where the real start is
}
uint256 constant MAX_CLAN_COMBATANTS = 20;
uint256 constant CLAN_WARS_GAS_PRICE_WINDOW_SIZE = 4;
bool constant XP_EMITTED_ELSEWHERE = true;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
uint16 constant NONE = 0;
uint16 constant COMBAT_BASE = 2048;
// Melee
uint16 constant SWORD_BASE = COMBAT_BASE;
uint16 constant BRONZE_SWORD = SWORD_BASE;
// Woodcutting (2816 - 3071)
uint16 constant WOODCUTTING_BASE = 2816;
uint16 constant BRONZE_AXE = WOODCUTTING_BASE;
// Firemaking (3328 - 3583)
uint16 constant FIRE_BASE = 3328;
uint16 constant MAGIC_FIRE_STARTER = FIRE_BASE;
uint16 constant FIRE_MAX = FIRE_BASE + 255;
// Fishing (3072 - 3327)
uint16 constant FISHING_BASE = 3072;
uint16 constant NET_STICK = FISHING_BASE;
// Mining (2560 - 2815)
uint16 constant MINING_BASE = 2560;
uint16 constant BRONZE_PICKAXE = MINING_BASE;
// Magic
uint16 constant STAFF_BASE = COMBAT_BASE + 50;
uint16 constant TOTEM_STAFF = STAFF_BASE;
// Ranged
uint16 constant BOW_BASE = COMBAT_BASE + 100;
uint16 constant BASIC_BOW = BOW_BASE;
// Cooked fish
uint16 constant COOKED_FISH_BASE = 11008;
uint16 constant COOKED_FEOLA = COOKED_FISH_BASE + 3;
// Scrolls
uint16 constant SCROLL_BASE = 12032;
uint16 constant SHADOW_SCROLL = SCROLL_BASE;
// 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 LUCKY_POTION = BOOST_BASE + 5;
uint16 constant LUCK_OF_THE_DRAW = BOOST_BASE + 6;
uint16 constant PRAY_TO_THE_BEARDIE = BOOST_BASE + 7;
uint16 constant PRAY_TO_THE_BEARDIE_2 = BOOST_BASE + 8;
uint16 constant PRAY_TO_THE_BEARDIE_3 = BOOST_BASE + 9;
uint16 constant BOOST_RESERVED_1 = BOOST_BASE + 10;
uint16 constant BOOST_RESERVED_2 = BOOST_BASE + 11;
uint16 constant BOOST_RESERVED_3 = BOOST_BASE + 12;
uint16 constant GO_OUTSIDE = BOOST_BASE + 13;
uint16 constant RAINING_RARES = BOOST_BASE + 14;
uint16 constant CLAN_BOOSTER = BOOST_BASE + 15;
uint16 constant CLAN_BOOSTER_2 = BOOST_BASE + 16;
uint16 constant CLAN_BOOSTER_3 = BOOST_BASE + 17;
uint16 constant BOOST_RESERVED_4 = BOOST_BASE + 18;
uint16 constant BOOST_RESERVED_5 = BOOST_BASE + 19;
uint16 constant BOOST_RESERVED_6 = BOOST_BASE + 20;
uint16 constant BOOST_MAX = 13055;
// Eggs
uint16 constant EGG_BASE = 12544;
uint16 constant SECRET_EGG_1_TIER1 = EGG_BASE;
uint16 constant SECRET_EGG_2_TIER1 = EGG_BASE + 1;
uint16 constant EGG_MAX = 12799;
// Miscs
uint16 constant MISC_BASE = 65535;
uint16 constant RAID_PASS = MISC_BASE - 1;
struct BulkTransferInfo {
uint256[] tokenIds;
uint256[] amounts;
address to;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
enum BoostType {
NONE,
ANY_XP,
COMBAT_XP,
NON_COMBAT_XP,
GATHERING,
ABSENCE,
PASSIVE_SKIP_CHANCE,
// Clan wars
PVP_BLOCK,
PVP_REATTACK,
PVP_SUPER_ATTACK,
// Combat stats
COMBAT_FIXED
}
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,
RANGED,
MAGIC,
DEFENCE,
HEALTH,
RESERVED_COMBAT,
MINING,
WOODCUTTING,
FISHING,
SMITHING,
THIEVING,
CRAFTING,
COOKING,
FIREMAKING,
FARMING,
ALCHEMY,
FLETCHING,
FORGING,
RESERVED2,
RESERVED3,
RESERVED4,
RESERVED5,
RESERVED6,
RESERVED7,
RESERVED8,
RESERVED9,
RESERVED10,
RESERVED11,
RESERVED12,
RESERVED13,
RESERVED14,
RESERVED15,
RESERVED16,
RESERVED17,
RESERVED18,
RESERVED19,
RESERVED20,
TRAVELING // Helper Skill for travelling
}
struct Attire {
uint16 head;
uint16 neck;
uint16 body;
uint16 arms;
uint16 legs;
uint16 feet;
uint16 ring;
uint16 reserved1;
}
struct CombatStats {
// From skill points
int16 meleeAttack;
int16 magicAttack;
int16 rangedAttack;
int16 health;
// These include equipment
int16 meleeDefence;
int16 magicDefence;
int16 rangedDefence;
}
enum CombatStyle {
NONE,
ATTACK,
DEFENCE
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {Skill} from "./misc.sol";
enum PetSkin {
NONE,
DEFAULT,
OG,
ONEKIN,
FROST,
CRYSTAL,
ANNIV1,
KRAGSTYR
}
enum PetEnhancementType {
NONE,
MELEE,
MAGIC,
RANGED,
DEFENCE,
HEALTH,
MELEE_AND_DEFENCE,
MAGIC_AND_DEFENCE,
RANGED_AND_DEFENCE
}
struct Pet {
Skill skillEnhancement1;
uint8 skillFixedEnhancement1;
uint8 skillPercentageEnhancement1;
Skill skillEnhancement2;
uint8 skillFixedEnhancement2;
uint8 skillPercentageEnhancement2;
uint40 lastAssignmentTimestamp;
address owner; // Will be used as an optimization to avoid having to look up the owner of the pet in another storage slot
bool isTransferable;
// New storage slot
uint24 baseId;
// These are used when training a pet
uint40 lastTrainedTimestamp;
uint8 skillFixedEnhancementMax1; // The maximum possible value for skillFixedEnhancement1 when training
uint8 skillFixedEnhancementMax2;
uint8 skillPercentageEnhancementMax1;
uint8 skillPercentageEnhancementMax2;
uint64 xp;
}
struct BasePetMetadata {
string description;
uint8 tier;
PetSkin skin;
PetEnhancementType enhancementType;
Skill skillEnhancement1;
uint8 skillFixedMin1;
uint8 skillFixedMax1;
uint8 skillFixedIncrement1;
uint8 skillPercentageMin1;
uint8 skillPercentageMax1;
uint8 skillPercentageIncrement1;
uint8 skillMinLevel1;
Skill skillEnhancement2;
uint8 skillFixedMin2;
uint8 skillFixedMax2;
uint8 skillFixedIncrement2;
uint8 skillPercentageMin2;
uint8 skillPercentageMax2;
uint8 skillPercentageIncrement2;
uint8 skillMinLevel2;
uint16 fixedStarThreshold;
uint16 percentageStarThreshold;
bool isTransferable;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {QueuedAction} from "./actions.sol";
import {Skill, BoostType, CombatStats, Equipment} from "./misc.sol";
import {PlayerQuest} from "./quests.sol";
// 4 bytes for each level. 0x00000000 is the first level, 0x00000054 is the second, etc.
bytes constant XP_BYTES = hex"0000000000000054000000AE0000010E00000176000001E60000025E000002DE00000368000003FD0000049B00000546000005FC000006C000000792000008730000096400000A6600000B7B00000CA400000DE100000F36000010A200001229000013CB0000158B0000176B0000196E00001B9400001DE20000205A000022FF000025D5000028DD00002C1E00002F99000033540000375200003B9A000040300000451900004A5C00004FFF0000560900005C810000637000006ADD000072D100007B570000847900008E42000098BE0000A3F90000B0020000BCE70000CAB80000D9860000E9630000FA6200010C990001201D0001350600014B6F0001637300017D2E000198C10001B64E0001D5F80001F7E600021C430002433B00026CFD000299BE0002C9B30002FD180003342B00036F320003AE730003F23D00043AE3000488BE0004DC2F0005359B000595700005FC2400066A360006E02D00075E990007E6160008774C000912EB0009B9B4000A6C74000B2C06000BF956000CD561000DC134000EBDF3000FCCD40010EF2400122648001373BF0014D9230016582C0017F2B00019AAA9001B8234001D7B95001F99390021DDBC00244BE60026E6B60029B15F002CAF51002FE43A0033540D00370303003AF5A4003F30CC0043B9B0004895E3004DCB600053609100595C53005FC6030066A585006E034D0075E86C007E5E980087703B0091287D009B935300A6BD8F00B2B4EE00BF882800CD470500DC026F00EBCC8500FCB8B7010EDBD5";
uint256 constant MAX_LEVEL = 140; // Original max level
uint256 constant MAX_LEVEL_1 = 160; // TODO: Update later
uint256 constant MAX_LEVEL_2 = 190; // TODO: Update later
enum EquipPosition {
NONE,
HEAD,
NECK,
BODY,
ARMS,
LEGS,
FEET,
RING,
SPARE2,
LEFT_HAND,
RIGHT_HAND,
BOTH_HANDS,
QUIVER,
MAGIC_BAG,
FOOD,
AUX, // wood, seeds etc..
BOOST_VIAL,
EXTRA_BOOST_VIAL,
GLOBAL_BOOST_VIAL,
CLAN_BOOST_VIAL,
PASSIVE_BOOST_VIAL,
LOCKED_VAULT,
TERRITORY
}
struct Player {
uint40 currentActionStartTimestamp; // The in-progress 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;
Skill currentActionProcessedSkill3;
uint24 currentActionProcessedXPGained3;
uint16 currentActionProcessedFoodConsumed;
uint16 currentActionProcessedBaseInputItemsConsumedNum; // e.g scrolls, crafting materials etc
Skill skillBoosted1; // The first skill that is boosted
Skill skillBoosted2; // The second skill that is boosted (if applicable)
uint48 totalXP;
uint16 totalLevel; // Doesn't not automatically add new skills to it
bytes1 packedData; // Contains worldLocation in first 6 bits (0 is the main starting randomnessBeacon), and full mode unlocked in the upper most bit
// TODO: Can be up to 7
QueuedAction[] actionQueue;
string name; // Raw name
}
struct Item {
EquipPosition equipPosition;
bytes1 packedData; // 0x1 exists, upper most bit is full mode
uint16 questPrerequisiteId;
// Can it be transferred?
bool isTransferable; // TODO: Move into packedData
// 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 meleeAttack;
int16 magicAttack;
int16 rangedAttack;
int16 meleeDefence;
int16 magicDefence;
int16 rangedDefence;
int16 health;
// Minimum requirements in this skill to use this item (can be NONE)
Skill skill;
uint32 minXP;
}
// Used for events
struct BoostInfo {
uint40 startTime;
uint24 duration;
uint16 value;
uint16 itemTokenId; // Get the effect of it
BoostType boostType;
}
struct PlayerBoostInfo {
uint40 startTime;
uint24 duration;
uint16 value;
uint16 itemTokenId; // Get the effect of it
BoostType boostType;
// Another boost slot (for global/clan boosts this is the "last", for users it is the "extra")
uint40 extraOrLastStartTime;
uint24 extraOrLastDuration;
uint16 extraOrLastValue;
uint16 extraOrLastItemTokenId;
BoostType extraOrLastBoostType;
uint40 cooldown; // Just put here for packing
}
// This is effectively a ratio to produce 1 of outputTokenId.
// Available choices that can be undertaken for an action
struct ActionChoiceInput {
uint8 skill; // Skill that this action choice is related to
uint24 rate; // Rate of output produced per hour (base 1000) 3 decimals
uint24 xpPerHour;
uint16[] inputTokenIds;
uint24[] inputAmounts;
uint16 outputTokenId;
uint8 outputAmount;
uint8 successPercent; // 0-100
uint16 handItemTokenIdRangeMin; // Inclusive
uint16 handItemTokenIdRangeMax; // Inclusive
bool isFullModeOnly;
bool isAvailable;
uint16 questPrerequisiteId;
uint8[] skills; // Skills required to do this action choice
uint32[] skillMinXPs; // Min XP in the corresponding skills to be able to do this action choice
int16[] skillDiffs; // How much the skill is increased/decreased by this action choice
}
struct ActionChoice {
uint8 skill; // Skill that this action choice is related to
uint24 rate; // Rate of output produced per hour (base 1000) 3 decimals
uint24 xpPerHour;
uint16 inputTokenId1;
uint24 inputAmount1;
uint16 inputTokenId2;
uint24 inputAmount2;
uint16 inputTokenId3;
uint24 inputAmount3;
uint16 outputTokenId;
uint8 outputAmount;
uint8 successPercent; // 0-100
uint8 skill1; // Skills required to do this action choice, commonly the same as skill
uint32 skillMinXP1; // Min XP in the skill to be able to do this action choice
int16 skillDiff1; // How much the skill is increased/decreased by this action choice
uint8 skill2;
uint32 skillMinXP2;
int16 skillDiff2;
uint8 skill3;
uint32 skillMinXP3;
int16 skillDiff3;
uint16 handItemTokenIdRangeMin; // Inclusive
uint16 handItemTokenIdRangeMax; // Inclusive
uint16 questPrerequisiteId;
// FullMode is last bit, first 6 bits is worldLocation,
// 2nd last bit is if there are other skills in next storage slot to check,
// 3rd last bit if the input amounts should be used
bytes1 packedData;
}
// Must be in the same order as Skill enum
struct PackedXP {
uint40 melee;
uint40 ranged;
uint40 magic;
uint40 defence;
uint40 health;
uint40 reservedCombat;
bytes2 packedDataIsMaxed; // 2 bits per skill to indicate whether the maxed skill is reached. I think this was added in case we added a new max level which a user had already passed so old & new levels are the same and it would not trigger a level up event.
// Next slot
uint40 mining;
uint40 woodcutting;
uint40 fishing;
uint40 smithing;
uint40 thieving;
uint40 crafting;
bytes2 packedDataIsMaxed1; // 2 bits per skill to indicate whether the maxed skill is reached
// Next slot
uint40 cooking;
uint40 firemaking;
uint40 farming;
uint40 alchemy;
uint40 fletching;
uint40 forging;
bytes2 packedDataIsMaxed2; // 2 bits per skill to indicate whether the maxed skill is reached
}
struct AvatarInfo {
string name;
string description;
string imageURI;
Skill[2] startSkills; // Can be NONE
}
struct PastRandomRewardInfo {
uint16 itemTokenId;
uint24 amount;
uint64 queueId;
}
struct PendingQueuedActionEquipmentState {
uint256[] consumedItemTokenIds;
uint256[] consumedAmounts;
uint256[] producedItemTokenIds;
uint256[] producedAmounts;
}
struct PendingQueuedActionMetadata {
uint32 xpGained; // total xp gained
uint32 rolls;
bool died;
uint16 actionId;
uint64 queueId;
uint24 elapsedTime;
uint24 xpElapsedTime;
uint8 checkpoint;
}
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 {
uint256[] consumedItemTokenIds;
uint256[] consumedAmounts;
uint256[] rewardItemTokenIds;
uint256[] rewardAmounts;
PlayerQuest[] activeQuestInfo;
uint256[] questsCompleted;
Skill[] skills; // Skills gained XP in
uint32[] xpGainedSkills; // XP gained in these skills
}
struct LotteryWinnerInfo {
uint16 lotteryId;
uint24 raffleId;
uint16 itemTokenId;
uint16 amount;
bool instantConsume;
uint64 playerId;
}
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;
PastRandomRewardInfo[] producedPastRandomRewards;
uint256[] xpRewardItemTokenIds;
uint256[] xpRewardAmounts;
uint256[] dailyRewardItemTokenIds;
uint256[] dailyRewardAmounts;
PendingQueuedActionProcessed processedData;
bytes32 dailyRewardMask;
QuestState quests;
uint256 numPastRandomRewardInstancesToRemove;
uint8 worldLocation;
LotteryWinnerInfo lotteryWinner;
}
struct FullAttireBonusInput {
Skill skill;
uint8 bonusXPPercent;
uint8 bonusRewardsPercent; // 3 = 3%
uint16[5] itemTokenIds; // 0 = head, 1 = body, 2 arms, 3 body, 4 = feet
}
// Contains everything you need to create an item
struct ItemInput {
CombatStats combatStats;
uint16 tokenId;
EquipPosition equipPosition;
bool isTransferable;
bool isFullModeOnly;
bool isAvailable;
uint16 questPrerequisiteId;
// 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;
}
/* Order head, neck, body, arms, legs, feet, ring, reserved1,
leftHandEquipment, rightHandEquipment,
Not used yet: input1, input2,input3, regenerate, reserved2, reserved3 */
struct CheckpointEquipments {
uint16[16] itemTokenIds;
uint16[16] balances;
}
struct ActivePlayerInfo {
uint64 playerId;
uint40 checkpoint;
uint24 timespan;
uint24 timespan1;
uint24 timespan2;
}
uint8 constant START_LEVEL = 17; // Needs updating when there is a new skill. Only useful for new heroes.
uint256 constant MAX_UNIQUE_TICKETS = 64;
// Used in a bunch of places
uint256 constant IS_FULL_MODE_BIT = 7;
// Passive/Instant/InstantVRF/Actions/ActionChoices/Item action
uint256 constant IS_AVAILABLE_BIT = 6;
// Passive actions
uint256 constant HAS_RANDOM_REWARDS_BIT = 5;
// The rest use world location for first 4 bits
// Queued action
uint256 constant HAS_PET_BIT = 2;
uint256 constant IS_VALID_BIT = 1;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
enum Promotion {
NONE,
STARTER,
HALLOWEEN_2023,
XMAS_2023,
HALLOWEEN_2024,
HOLIDAY4, // Just have placeholders for now
HOLIDAY5,
HOLIDAY6,
HOLIDAY7,
HOLIDAY8,
HOLIDAY9,
HOLIDAY10
}
enum PromotionMintStatus {
NONE,
SUCCESS,
PROMOTION_ALREADY_CLAIMED,
ORACLE_NOT_CALLED,
MINTING_OUTSIDE_AVAILABLE_DATE,
PLAYER_DOES_NOT_QUALIFY,
PLAYER_NOT_HIT_ENOUGH_CLAIMS_FOR_STREAK_BONUS,
DEPENDENT_QUEST_NOT_COMPLETED
}
struct PromotionInfoInput {
Promotion promotion;
uint40 startTime;
uint40 endTime; // Exclusive
uint8 numDailyRandomItemsToPick; // Number of items to pick
uint40 minTotalXP; // Minimum xp required to claim
uint256 tokenCost; // Cost in brush to start the promotion, max 16mil
// Special promotion specific (like 1kin)
uint8 redeemCodeLength; // Length of the redeem code
bool adminOnly; // Only admins can mint the promotion, like for 1kin (Not used yet)
bool promotionTiedToUser; // If the promotion is tied to a user
bool promotionTiedToPlayer; // If the promotion is tied to the player
bool promotionMustOwnPlayer; // Must own the player to get the promotion
// Evolution specific
bool evolvedHeroOnly; // Only allow evolved heroes to claim
// Multiday specific
bool isMultiday; // The promotion is multi-day
uint256 brushCostMissedDay; // Cost in brush to mint the promotion if they miss a day (in ether), max 25.6 (base 100)
uint8 numDaysHitNeededForStreakBonus; // How many days to hit for the streak bonus
uint8 numDaysClaimablePeriodStreakBonus; // If there is a streak bonus, how many days to claim it after the promotion ends. If no final day bonus, set to 0
uint8 numRandomStreakBonusItemsToPick1; // Number of items to pick for the streak bonus
uint8 numRandomStreakBonusItemsToPick2; // Number of random items to pick for the streak bonus
uint16[] randomStreakBonusItemTokenIds1;
uint32[] randomStreakBonusAmounts1;
uint16[] randomStreakBonusItemTokenIds2;
uint32[] randomStreakBonusAmounts2;
uint16[] guaranteedStreakBonusItemTokenIds;
uint16[] guaranteedStreakBonusAmounts;
// Single and multiday
uint16[] guaranteedItemTokenIds; // Guaranteed items for the promotions each day, if empty then they are handled in a specific way for the promotion like daily rewards
uint32[] guaranteedAmounts; // Corresponding amounts to the itemTokenIds
uint16[] randomItemTokenIds; // Possible items for the promotions each day, if empty then they are handled in a specific way for the promotion like daily rewards
uint32[] randomAmounts; // Corresponding amounts to the randomItemTokenIds
// Quests
uint16 questPrerequisiteId;
}
struct PromotionInfo {
Promotion promotion;
uint40 startTime;
uint8 numDays;
uint8 numDailyRandomItemsToPick; // Number of items to pick
uint40 minTotalXP; // Minimum xp required to claim
uint24 tokenCost; // Cost in brush to mint the promotion (in ether), max 16mil
// Quests
uint16 questPrerequisiteId;
// Special promotion specific (like 1kin), could pack these these later
uint8 redeemCodeLength; // Length of the redeem code
bool adminOnly; // Only admins can mint the promotion, like for 1kin
bool promotionTiedToUser; // If the promotion is tied to a user
bool promotionTiedToPlayer; // If the promotion is tied to the player
bool promotionMustOwnPlayer; // Must own the player to get the promotion
// Evolution specific
bool evolvedHeroOnly; // Only allow evolved heroes to claim
// Multiday specific
bool isMultiday; // The promotion is multi-day
uint8 brushCostMissedDay; // Cost in brush to mint the promotion if they miss a day (in ether), max 25.5, base 100
uint8 numDaysHitNeededForStreakBonus; // How many days to hit for the streak bonus
uint8 numDaysClaimablePeriodStreakBonus; // If there is a streak bonus, how many days to claim it after the promotion ends. If no final day bonus, set to 0
uint8 numRandomStreakBonusItemsToPick1; // Number of items to pick for the streak bonus
uint8 numRandomStreakBonusItemsToPick2; // Number of random items to pick for the streak bonus
// Misc
uint16[] randomStreakBonusItemTokenIds1;
uint32[] randomStreakBonusAmounts1;
uint16[] randomStreakBonusItemTokenIds2; // Not used yet
uint32[] randomStreakBonusAmounts2; // Not used yet
uint16[] guaranteedStreakBonusItemTokenIds; // Not used yet
uint16[] guaranteedStreakBonusAmounts; // Not used yet
// Single and multiday
uint16[] guaranteedItemTokenIds; // Guaranteed items for the promotions each day, if empty then they are handled in a specific way for the promotion like daily rewards
uint32[] guaranteedAmounts; // Corresponding amounts to the itemTokenIds
uint16[] randomItemTokenIds; // Possible items for the promotions each day, if empty then they are handled in a specific way for the promotion like daily rewards
uint32[] randomAmounts; // Corresponding amounts to the randomItemTokenIds
}
uint256 constant BRUSH_COST_MISSED_DAY_MUL = 10;// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {Skill} from "./misc.sol";
struct QuestInput {
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
uint24 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 isFullModeOnly; // If true this quest requires the user be evolved
uint8 worldLocation; // 0 is the main starting world
}
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
uint24 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 reserved; // Reserved for future use (previously was questId and cleared)
bytes1 packedData; // FullMode is last bit, first 6 bits is worldLocation
}
struct PlayerQuest {
uint32 questId;
uint16 actionCompletedNum1;
uint16 actionCompletedNum2;
uint16 actionChoiceCompletedNum;
uint16 burnCompletedAmount;
}
uint256 constant QUEST_PURSE_STRINGS = 5; // MAKE SURE THIS MATCHES definitions// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {BoostType, Equipment} from "./misc.sol";
struct GuaranteedReward {
uint16 itemTokenId;
uint16 rate; // num per hour (base 10, 1 decimal) for actions and num per duration for passive actions
}
struct RandomReward {
uint16 itemTokenId;
uint16 chance; // out of 65535
uint8 amount; // out of 255
}
struct PendingRandomReward {
uint16 actionId;
uint40 startTime;
uint24 xpElapsedTime;
uint16 boostItemTokenId;
uint24 elapsedTime;
uint40 boostStartTime; // When the boost was started
uint24 sentinelElapsedTime;
// Full equipment at the time this was generated
uint8 fullAttireBonusRewardsPercent;
uint64 queueId; // TODO: Could reduce this if more stuff is needed
}
struct ActionRewards {
uint16 guaranteedRewardTokenId1;
uint16 guaranteedRewardRate1; // Num per hour base 10 (1 decimal) for actions (Max 6553.5 per hour), num per duration for passive actions
uint16 guaranteedRewardTokenId2;
uint16 guaranteedRewardRate2;
uint16 guaranteedRewardTokenId3;
uint16 guaranteedRewardRate3;
// Random chance rewards
uint16 randomRewardTokenId1;
uint16 randomRewardChance1; // out of 65535
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 in this storage slot!
}
struct XPThresholdReward {
uint32 xpThreshold;
Equipment[] rewards;
}
enum InstantVRFActionType {
NONE,
GENERIC,
FORGING,
EGG
}
struct InstantVRFActionInput {
uint16 actionId;
uint16[] inputTokenIds;
uint24[] inputAmounts;
bytes data;
InstantVRFActionType actionType;
bool isFullModeOnly;
bool isAvailable;
uint16 questPrerequisiteId;
}
struct InstantVRFRandomReward {
uint16 itemTokenId;
uint16 chance; // out of 65535
uint16 amount; // out of 65535
}
uint256 constant MAX_GUARANTEED_REWARDS_PER_ACTION = 3;
uint256 constant MAX_RANDOM_REWARDS_PER_ACTION = 4;
uint256 constant MAX_REWARDS_PER_ACTION = MAX_GUARANTEED_REWARDS_PER_ACTION + MAX_RANDOM_REWARDS_PER_ACTION;
uint256 constant MAX_CONSUMED_PER_ACTION = 3;
uint256 constant MAX_QUEST_REWARDS = 2;
uint256 constant TIER_1_DAILY_REWARD_START_XP = 0;
uint256 constant TIER_2_DAILY_REWARD_START_XP = 7_650;
uint256 constant TIER_3_DAILY_REWARD_START_XP = 33_913;
uint256 constant TIER_4_DAILY_REWARD_START_XP = 195_864;
uint256 constant TIER_5_DAILY_REWARD_START_XP = 784_726;
uint256 constant TIER_6_DAILY_REWARD_START_XP = 2_219_451;
// 4 bytes for each threshold, starts at 500 xp in decimal
bytes constant XP_THRESHOLD_REWARDS = hex"00000000000001F4000003E8000009C40000138800002710000075300000C350000186A00001D4C0000493E0000557300007A120000927C0000B71B0000DBBA0000F424000124F800016E360001B7740001E8480002625A0002932E0002DC6C0003567E0003D0900004C4B40005B8D80006ACFC0007A1200008954400098968000A7D8C000B71B0000C65D4000D59F8000E4E1C0";// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
interface IBank {
function initialize() external;
function initializeAddresses(
uint256 clanId,
address bankRegistry,
address bankRelay,
address playerNFT,
address itemNFT,
address clans,
address players,
address lockedBankVaults,
address raids
) external;
function depositToken(address sender, address from, uint256 playerId, address token, uint256 amount) external;
function setAllowBreachedCapacity(bool allow) external;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import "../globals/misc.sol";
import "../globals/players.sol";
interface IPlayers {
function clearEverythingBeforeTokenTransfer(address from, uint256 tokenId) external;
function beforeTokenTransferTo(address to, uint256 tokenId) external;
function getURI(
uint256 playerId,
string calldata name,
string calldata avatarName,
string calldata avatarDescription,
string calldata imageURI
) external view returns (string memory);
function mintedPlayer(
address from,
uint256 playerId,
Skill[2] calldata startSkills,
bool makeActive,
uint256[] calldata startingItemTokenIds,
uint256[] calldata startingAmounts
) external;
function upgradePlayer(uint256 playerId) external;
function isPlayerEvolved(uint256 playerId) external view returns (bool);
function isOwnerOfPlayerAndActive(address from, uint256 playerId) external view returns (bool);
function getAlphaCombatParams() external view returns (uint8 alphaCombat, uint8 betaCombat, uint8 alphaCombatHealing);
function getActivePlayer(address owner) external view returns (uint256 playerId);
function getPlayerXP(uint256 playerId, Skill skill) external view returns (uint256 xp);
function getLevel(uint256 playerId, Skill skill) external view returns (uint256 level);
function getTotalXP(uint256 playerId) external view returns (uint256 totalXP);
function getTotalLevel(uint256 playerId) external view returns (uint256 totalLevel);
function getActiveBoost(uint256 playerId) external view returns (PlayerBoostInfo memory);
function modifyXP(address from, uint256 playerId, Skill skill, uint56 xp, bool skipEffects) external;
function beforeItemNFTTransfer(address from, address to, uint256[] calldata ids, uint256[] calldata amounts) external;
}{
"evmVersion": "cancun",
"optimizer": {
"enabled": true,
"runs": 9999999,
"details": {
"yul": true
}
},
"viaIR": true,
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"metadata": {
"useLiteralContent": true
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"name":"GuaranteedRewardsNoDuplicates","type":"error"},{"inputs":[],"name":"RandomRewardNoDuplicates","type":"error"},{"inputs":[{"internalType":"uint16","name":"chance1","type":"uint16"},{"internalType":"uint16","name":"chance2","type":"uint16"}],"name":"RandomRewardsMustBeInOrder","type":"error"},{"inputs":[],"name":"TooManyGuaranteedRewards","type":"error"},{"inputs":[],"name":"TooManyRandomRewards","type":"error"},{"inputs":[{"internalType":"uint64[]","name":"array","type":"uint64[]"},{"internalType":"uint256","name":"target","type":"uint256"}],"name":"binarySearchMemory","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"socialMediaName","type":"string"}],"name":"containsBaselineSocialNameCharacters","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"discord","type":"string"}],"name":"containsValidDiscordCharacters","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"name","type":"string"}],"name":"containsValidNameCharacters","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"telegram","type":"string"}],"name":"containsValidTelegramCharacters","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"twitter","type":"string"}],"name":"containsValidTwitterCharacters","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"trim","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"}]Contract Creation Code
60808060405234601b57611b6b90816100208239308160070152f35b5f80fdfe6080604052307f0000000000000000000000000000000000000000000000000000000000000000146004361015610034575f80fd5b5f3560e01c9081631a2bbf3d146107d05781631c39ceeb14610791578163252c8ce0146107965781632b6842cc1461079157816391ae2cdb1461077d57816391f221eb146101ce575080639f241ed0146101ba578063b2dad15514610152578063e1f5afdb146100ca5763f816bc3b146100ac575f80fd5b60206100c06100ba36610a92565b906111f9565b6040519015158152f35b60407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5760043567ffffffffffffffff811161014e573660238201121561014e57806004013567ffffffffffffffff811161014e573660248260051b8401011161014e57602091610146916024803592016119e6565b604051908152f35b5f80fd5b6020604061017061016b61016536610a92565b90611703565b6118a7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f835194859381855280519182918282880152018686015e5f85828601015201168101030190f35b60206100c06101c836610a92565b90610ff2565b61014e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5760043567ffffffffffffffff811161014e573660238201121561014e57806004013567ffffffffffffffff811161014e576024820191366024606084028301011161014e57602435821580156106e7575b600184116105f4575b5060028311610495575b6003831161029e575b5050600491501161027657005b7f3ee22d8c000000000000000000000000000000000000000000000000000000005f5260045ffd5b8260031015610468576102b461014483016113ae565b8154906101648401917effff00000000000000000000000000000000000000000000000000000000006102e6846113ae565b60e81b16907affffffffffffffffffffffffffffffffffffffffffffffffffffff7cffff0000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000006103536101848a01611671565b60f81b169460d81b16911617171780925583600210156104685761038661038061010461039c95016113ae565b916113ae565b9161ffff808260c01c169160e81c16111561167f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810191818311908161043b575f5b8481106103d85750610269565b826103ec6103e7838786611661565b6113ae565b9061043b5761ffff806104036103e7898988611661565b16911614610413576001016103cb565b7f4d588c95000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b8260021015610468576104aa60e483016113ae565b81549061010484019179ffff0000000000000000000000000000000000000000000000006104d7846113ae565b60c01b16907fffffffffff0000000000ffffffffffffffffffffffffffffffffffffffffffff77ffff000000000000000000000000000000000000000000007aff000000000000000000000000000000000000000000000000000061053f6101248a01611671565b60d01b169460b01b1691161717178083558460011015610468576105829161056c61038060a487016113ae565b9161ffff808260981c169160c01c16111561167f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83018381118061043b575f5b8281106105be57505050610260565b816105cd6103e783898b611661565b9061043b5761ffff806105e46103e7878b8d611661565b16911614610413576001016105af565b836001101561046857610609608484016113ae565b82549060a485019174ffff00000000000000000000000000000000000000610630846113ae565b60981b16907fffffffffffffffffffff0000000000ffffffffffffffffffffffffffffffffff72ffff000000000000000000000000000000000075ff00000000000000000000000000000000000000000061068d60c48b01611671565b60a81b169460881b16911617171791828455610468576106ce906106b6610380604487016113ae565b9061ffff8460701c1661ffff8560981c16111561167f565b61ffff808260881c169160601c16146104135784610256565b610468576106f4846113ae565b8154906fffff0000000000000000000000000000610714604486016113ae565b60701b165f927fffffffffffffffffffffffffffffff0000000000ffffffffffffffffffffffff6dffff00000000000000000000000070ff0000000000000000000000000000000061076860648a01611671565b60801b169460601b169116171717825561024d565b60206100c061078b36610a92565b90610d82565b610b01565b60407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5760206101466024356004356113f8565b61014e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5760043567ffffffffffffffff811161014e573660238201121561014e57806004013567ffffffffffffffff811161014e5760248201913660248360061b8301011161014e576024359082158015610a3c575b506001831161099e575b60028311610898575b5050600391501161087057005b7f0c6ebee1000000000000000000000000000000000000000000000000000000005f5260045ffd5b8260021015610468576108ad60a482016113ae565b907fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff69ffff00000000000000006bffff000000000000000000006108f560c4875495016113ae565b60501b169360401b169116171790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810191818311908161043b575f5b8481106109405750610863565b8261094f6103e783878661139e565b9061043b5761ffff806109666103e789898861139e565b1691161461097657600101610933565b7faa21ace3000000000000000000000000000000000000000000000000000000005f5260045ffd5b8260011015610468576109b3606482016113ae565b5f61ffff8085549365ffff0000000067ffff0000000000006109d7608489016113ae565b60301b169160201b167fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff8616171780875560201c169216170361085a577faa21ace3000000000000000000000000000000000000000000000000000000005f5260045ffd5b6104685761ffff610a4c856113ae565b168254907fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000063ffff0000610a82604486016113ae565b60101b1692161717825584610850565b9060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261014e5760043567ffffffffffffffff811161014e578260238201121561014e5780600401359267ffffffffffffffff841161014e576024848301011161014e576024019190565b60206100c0610b0f36610a92565b90610c01565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f604051930116820182811067ffffffffffffffff821117610b5957604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b67ffffffffffffffff8111610b5957601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b929192610bd4610bcf83610b86565b610b15565b938285528282011161014e57815f926020928387013784010152565b908151811015610468570160200190565b610c0c913691610bc0565b5f5b8151811015610d7b577fff00000000000000000000000000000000000000000000000000000000000000610c428284610bf0565b51167f41000000000000000000000000000000000000000000000000000000000000008110159081610d50575b7f61000000000000000000000000000000000000000000000000000000000000008110159182610d25575b7f30000000000000000000000000000000000000000000000000000000000000008210159182610cfa575b50159182610cf1575b5081610ce8575b50610ce257600101610c0e565b50505f90565b9050155f610cd5565b1591505f610cce565b7f3900000000000000000000000000000000000000000000000000000000000000101591505f610cc5565b7f7a000000000000000000000000000000000000000000000000000000000000008211159250610c9a565b7f5a000000000000000000000000000000000000000000000000000000000000008111159150610c6f565b5050600190565b610d8d913691610bc0565b5f5f5b8251811015610fea577fff00000000000000000000000000000000000000000000000000000000000000610dc48285610bf0565b51167f41000000000000000000000000000000000000000000000000000000000000008110159283610fbf575b7f61000000000000000000000000000000000000000000000000000000000000008210159182610f94575b7f300000000000000000000000000000000000000000000000000000000000000081101580610f6a575b7f2d000000000000000000000000000000000000000000000000000000000000008214918215610f40575b8215610f16575b8215610eec575b610e8890611547565b83610ee4575b95159384610edb575b5083610ed2575b5082610ec9575b508115610ec1575b50610eba57600101610d90565b5050505f90565b90505f610ead565b1591505f610ea5565b1592505f610e9e565b1593505f610e97565b925082610e8e565b7f200000000000000000000000000000000000000000000000000000000000000081149250610e7f565b7f2e0000000000000000000000000000000000000000000000000000000000000081149250610e78565b7f5f0000000000000000000000000000000000000000000000000000000000000081149250610e71565b507f3900000000000000000000000000000000000000000000000000000000000000811115610e46565b7f7a000000000000000000000000000000000000000000000000000000000000008111159250610e1c565b7f5a000000000000000000000000000000000000000000000000000000000000008211159350610df1565b505050600190565b610ffd913691610bc0565b5f5b8151811015610d7b577fff000000000000000000000000000000000000000000000000000000000000006110338284610bf0565b51167f410000000000000000000000000000000000000000000000000000000000000081101590816111ce575b7f610000000000000000000000000000000000000000000000000000000000000081101591826111a3575b7f30000000000000000000000000000000000000000000000000000000000000008210159081611178575b15928361116f575b5082611166575b508161113b575b81611110575b816110e5575b50610ce257600101610fff565b7f2b00000000000000000000000000000000000000000000000000000000000000915014155f6110d8565b7f2e0000000000000000000000000000000000000000000000000000000000000081141591506110d2565b7f5f0000000000000000000000000000000000000000000000000000000000000081141591506110cc565b1591505f6110c5565b1592505f6110be565b7f390000000000000000000000000000000000000000000000000000000000000083111591506110b6565b7f7a00000000000000000000000000000000000000000000000000000000000000821115925061108b565b7f5a000000000000000000000000000000000000000000000000000000000000008111159150611060565b611204913691610bc0565b5f5b8151811015610d7b577fff0000000000000000000000000000000000000000000000000000000000000061123a8284610bf0565b51167f41000000000000000000000000000000000000000000000000000000000000008110159081611373575b7f61000000000000000000000000000000000000000000000000000000000000008110159182611348575b7f3000000000000000000000000000000000000000000000000000000000000000821015908161131d575b159283611314575b508261130b575b50816112e0575b50610ce257600101611206565b7f2b00000000000000000000000000000000000000000000000000000000000000915014155f6112d3565b1591505f6112cc565b1592505f6112c5565b7f390000000000000000000000000000000000000000000000000000000000000083111591506112bd565b7f7a000000000000000000000000000000000000000000000000000000000000008211159250611292565b7f5a000000000000000000000000000000000000000000000000000000000000008111159150611267565b91908110156104685760061b0190565b3561ffff8116810361014e5790565b9190820391821161043b57565b9190820180921161043b57565b9190918054831015610468575f52601860205f208360021c019260031b1690565b91905f83547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161043b5793919092935b8084111561145e575b505050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b61147461146b85836113bd565b60011c856113ca565b938267ffffffffffffffff61148987876113d7565b90549060031b1c16145f1461149f575050505090565b8267ffffffffffffffff6114b8878799989596976113d7565b90549060031b1c16105f146114df57506001810180911161043b57905b939190929361142d565b9150801561153f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908111156114d5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b839450611436565b7fff00000000000000000000000000000000000000000000000000000000000000167f20000000000000000000000000000000000000000000000000000000000000008114908115611637575b811561160d575b81156115e3575b81156115b9575b81156115b3575090565b90501590565b7f0b00000000000000000000000000000000000000000000000000000000000000811491506115a9565b7f0d00000000000000000000000000000000000000000000000000000000000000811491506115a2565b7f0a000000000000000000000000000000000000000000000000000000000000008114915061159b565b7f090000000000000000000000000000000000000000000000000000000000000081149150611594565b9190811015610468576060020190565b3560ff8116810361014e5790565b15611688575050565b9061ffff80927f75904fdc000000000000000000000000000000000000000000000000000000005f52166004521660245260445ffd5b906116cb610bcf83610b86565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06116f98294610b86565b0190602036910137565b61170e913691610bc0565b80518015611805577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081810190811360011661043b575b5f811215611817575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611805576001810180821161043b5761178b906116be565b915f5b8281111561179c5750505090565b7fff000000000000000000000000000000000000000000000000000000000000006117c78284610bf0565b51165f1a6117d58286610bf0565b537fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461043b5760010161178e565b50506118116020610b15565b5f815290565b61184c7fff000000000000000000000000000000000000000000000000000000000000006118458386610bf0565b5116611547565b1561189f577f8000000000000000000000000000000000000000000000000000000000000000811461043b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611746565b90505f61174f565b9081517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905f5b81811061197e575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82146119705761191061190b83836113bd565b6116be565b91805b82811061192257509193505050565b807fff0000000000000000000000000000000000000000000000000000000000000061195060019389610bf0565b511661196961195f85846113bd565b915f1a9187610bf0565b5301611913565b505090506118116020610b15565b6119ac7fff000000000000000000000000000000000000000000000000000000000000006118458388610bf0565b156119b9576001016118ce565b91505f6118d6565b91908110156104685760051b0190565b3567ffffffffffffffff8116810361014e5790565b9291905f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820182811161043b579492919093945b80851115611a4d575b50505050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b611a63611a5a86836113bd565b60011c866113ca565b948367ffffffffffffffff611a81611a7c89878a6119c1565b6119d1565b1603611a8f57505050505090565b8367ffffffffffffffff611aad611a7c89878a9c9b9798999a6119c1565b161015611acd57506001810180911161043b57905b949291909394611a1b565b91508015611b2d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811115611ac2577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b849550611a2456fea2646970667358221220b8af321e682747d84dac15d7e027bf3fd3b1a99233a41f0e5b02025c9dbd410064736f6c634300081c0033
Deployed Bytecode
0x6080604052307f000000000000000000000000e3223eaf0e260b54a8ce777ac9f4a972310370c0146004361015610034575f80fd5b5f3560e01c9081631a2bbf3d146107d05781631c39ceeb14610791578163252c8ce0146107965781632b6842cc1461079157816391ae2cdb1461077d57816391f221eb146101ce575080639f241ed0146101ba578063b2dad15514610152578063e1f5afdb146100ca5763f816bc3b146100ac575f80fd5b60206100c06100ba36610a92565b906111f9565b6040519015158152f35b60407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5760043567ffffffffffffffff811161014e573660238201121561014e57806004013567ffffffffffffffff811161014e573660248260051b8401011161014e57602091610146916024803592016119e6565b604051908152f35b5f80fd5b6020604061017061016b61016536610a92565b90611703565b6118a7565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f835194859381855280519182918282880152018686015e5f85828601015201168101030190f35b60206100c06101c836610a92565b90610ff2565b61014e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5760043567ffffffffffffffff811161014e573660238201121561014e57806004013567ffffffffffffffff811161014e576024820191366024606084028301011161014e57602435821580156106e7575b600184116105f4575b5060028311610495575b6003831161029e575b5050600491501161027657005b7f3ee22d8c000000000000000000000000000000000000000000000000000000005f5260045ffd5b8260031015610468576102b461014483016113ae565b8154906101648401917effff00000000000000000000000000000000000000000000000000000000006102e6846113ae565b60e81b16907affffffffffffffffffffffffffffffffffffffffffffffffffffff7cffff0000000000000000000000000000000000000000000000000000007fff000000000000000000000000000000000000000000000000000000000000006103536101848a01611671565b60f81b169460d81b16911617171780925583600210156104685761038661038061010461039c95016113ae565b916113ae565b9161ffff808260c01c169160e81c16111561167f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810191818311908161043b575f5b8481106103d85750610269565b826103ec6103e7838786611661565b6113ae565b9061043b5761ffff806104036103e7898988611661565b16911614610413576001016103cb565b7f4d588c95000000000000000000000000000000000000000000000000000000005f5260045ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b8260021015610468576104aa60e483016113ae565b81549061010484019179ffff0000000000000000000000000000000000000000000000006104d7846113ae565b60c01b16907fffffffffff0000000000ffffffffffffffffffffffffffffffffffffffffffff77ffff000000000000000000000000000000000000000000007aff000000000000000000000000000000000000000000000000000061053f6101248a01611671565b60d01b169460b01b1691161717178083558460011015610468576105829161056c61038060a487016113ae565b9161ffff808260981c169160c01c16111561167f565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff83018381118061043b575f5b8281106105be57505050610260565b816105cd6103e783898b611661565b9061043b5761ffff806105e46103e7878b8d611661565b16911614610413576001016105af565b836001101561046857610609608484016113ae565b82549060a485019174ffff00000000000000000000000000000000000000610630846113ae565b60981b16907fffffffffffffffffffff0000000000ffffffffffffffffffffffffffffffffff72ffff000000000000000000000000000000000075ff00000000000000000000000000000000000000000061068d60c48b01611671565b60a81b169460881b16911617171791828455610468576106ce906106b6610380604487016113ae565b9061ffff8460701c1661ffff8560981c16111561167f565b61ffff808260881c169160601c16146104135784610256565b610468576106f4846113ae565b8154906fffff0000000000000000000000000000610714604486016113ae565b60701b165f927fffffffffffffffffffffffffffffff0000000000ffffffffffffffffffffffff6dffff00000000000000000000000070ff0000000000000000000000000000000061076860648a01611671565b60801b169460601b169116171717825561024d565b60206100c061078b36610a92565b90610d82565b610b01565b60407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5760206101466024356004356113f8565b61014e5760407ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc36011261014e5760043567ffffffffffffffff811161014e573660238201121561014e57806004013567ffffffffffffffff811161014e5760248201913660248360061b8301011161014e576024359082158015610a3c575b506001831161099e575b60028311610898575b5050600391501161087057005b7f0c6ebee1000000000000000000000000000000000000000000000000000000005f5260045ffd5b8260021015610468576108ad60a482016113ae565b907fffffffffffffffffffffffffffffffffffffffff00000000ffffffffffffffff69ffff00000000000000006bffff000000000000000000006108f560c4875495016113ae565b60501b169360401b169116171790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810191818311908161043b575f5b8481106109405750610863565b8261094f6103e783878661139e565b9061043b5761ffff806109666103e789898861139e565b1691161461097657600101610933565b7faa21ace3000000000000000000000000000000000000000000000000000000005f5260045ffd5b8260011015610468576109b3606482016113ae565b5f61ffff8085549365ffff0000000067ffff0000000000006109d7608489016113ae565b60301b169160201b167fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff8616171780875560201c169216170361085a577faa21ace3000000000000000000000000000000000000000000000000000000005f5260045ffd5b6104685761ffff610a4c856113ae565b168254907fffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000063ffff0000610a82604486016113ae565b60101b1692161717825584610850565b9060207ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc83011261014e5760043567ffffffffffffffff811161014e578260238201121561014e5780600401359267ffffffffffffffff841161014e576024848301011161014e576024019190565b60206100c0610b0f36610a92565b90610c01565b907fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f604051930116820182811067ffffffffffffffff821117610b5957604052565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b67ffffffffffffffff8111610b5957601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b929192610bd4610bcf83610b86565b610b15565b938285528282011161014e57815f926020928387013784010152565b908151811015610468570160200190565b610c0c913691610bc0565b5f5b8151811015610d7b577fff00000000000000000000000000000000000000000000000000000000000000610c428284610bf0565b51167f41000000000000000000000000000000000000000000000000000000000000008110159081610d50575b7f61000000000000000000000000000000000000000000000000000000000000008110159182610d25575b7f30000000000000000000000000000000000000000000000000000000000000008210159182610cfa575b50159182610cf1575b5081610ce8575b50610ce257600101610c0e565b50505f90565b9050155f610cd5565b1591505f610cce565b7f3900000000000000000000000000000000000000000000000000000000000000101591505f610cc5565b7f7a000000000000000000000000000000000000000000000000000000000000008211159250610c9a565b7f5a000000000000000000000000000000000000000000000000000000000000008111159150610c6f565b5050600190565b610d8d913691610bc0565b5f5f5b8251811015610fea577fff00000000000000000000000000000000000000000000000000000000000000610dc48285610bf0565b51167f41000000000000000000000000000000000000000000000000000000000000008110159283610fbf575b7f61000000000000000000000000000000000000000000000000000000000000008210159182610f94575b7f300000000000000000000000000000000000000000000000000000000000000081101580610f6a575b7f2d000000000000000000000000000000000000000000000000000000000000008214918215610f40575b8215610f16575b8215610eec575b610e8890611547565b83610ee4575b95159384610edb575b5083610ed2575b5082610ec9575b508115610ec1575b50610eba57600101610d90565b5050505f90565b90505f610ead565b1591505f610ea5565b1592505f610e9e565b1593505f610e97565b925082610e8e565b7f200000000000000000000000000000000000000000000000000000000000000081149250610e7f565b7f2e0000000000000000000000000000000000000000000000000000000000000081149250610e78565b7f5f0000000000000000000000000000000000000000000000000000000000000081149250610e71565b507f3900000000000000000000000000000000000000000000000000000000000000811115610e46565b7f7a000000000000000000000000000000000000000000000000000000000000008111159250610e1c565b7f5a000000000000000000000000000000000000000000000000000000000000008211159350610df1565b505050600190565b610ffd913691610bc0565b5f5b8151811015610d7b577fff000000000000000000000000000000000000000000000000000000000000006110338284610bf0565b51167f410000000000000000000000000000000000000000000000000000000000000081101590816111ce575b7f610000000000000000000000000000000000000000000000000000000000000081101591826111a3575b7f30000000000000000000000000000000000000000000000000000000000000008210159081611178575b15928361116f575b5082611166575b508161113b575b81611110575b816110e5575b50610ce257600101610fff565b7f2b00000000000000000000000000000000000000000000000000000000000000915014155f6110d8565b7f2e0000000000000000000000000000000000000000000000000000000000000081141591506110d2565b7f5f0000000000000000000000000000000000000000000000000000000000000081141591506110cc565b1591505f6110c5565b1592505f6110be565b7f390000000000000000000000000000000000000000000000000000000000000083111591506110b6565b7f7a00000000000000000000000000000000000000000000000000000000000000821115925061108b565b7f5a000000000000000000000000000000000000000000000000000000000000008111159150611060565b611204913691610bc0565b5f5b8151811015610d7b577fff0000000000000000000000000000000000000000000000000000000000000061123a8284610bf0565b51167f41000000000000000000000000000000000000000000000000000000000000008110159081611373575b7f61000000000000000000000000000000000000000000000000000000000000008110159182611348575b7f3000000000000000000000000000000000000000000000000000000000000000821015908161131d575b159283611314575b508261130b575b50816112e0575b50610ce257600101611206565b7f2b00000000000000000000000000000000000000000000000000000000000000915014155f6112d3565b1591505f6112cc565b1592505f6112c5565b7f390000000000000000000000000000000000000000000000000000000000000083111591506112bd565b7f7a000000000000000000000000000000000000000000000000000000000000008211159250611292565b7f5a000000000000000000000000000000000000000000000000000000000000008111159150611267565b91908110156104685760061b0190565b3561ffff8116810361014e5790565b9190820391821161043b57565b9190820180921161043b57565b9190918054831015610468575f52601860205f208360021c019260031b1690565b91905f83547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811161043b5793919092935b8084111561145e575b505050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b61147461146b85836113bd565b60011c856113ca565b938267ffffffffffffffff61148987876113d7565b90549060031b1c16145f1461149f575050505090565b8267ffffffffffffffff6114b8878799989596976113d7565b90549060031b1c16105f146114df57506001810180911161043b57905b939190929361142d565b9150801561153f577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8101908111156114d5577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b839450611436565b7fff00000000000000000000000000000000000000000000000000000000000000167f20000000000000000000000000000000000000000000000000000000000000008114908115611637575b811561160d575b81156115e3575b81156115b9575b81156115b3575090565b90501590565b7f0b00000000000000000000000000000000000000000000000000000000000000811491506115a9565b7f0d00000000000000000000000000000000000000000000000000000000000000811491506115a2565b7f0a000000000000000000000000000000000000000000000000000000000000008114915061159b565b7f090000000000000000000000000000000000000000000000000000000000000081149150611594565b9190811015610468576060020190565b3560ff8116810361014e5790565b15611688575050565b9061ffff80927f75904fdc000000000000000000000000000000000000000000000000000000005f52166004521660245260445ffd5b906116cb610bcf83610b86565b8281527fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe06116f98294610b86565b0190602036910137565b61170e913691610bc0565b80518015611805577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff9081810190811360011661043b575b5f811215611817575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611805576001810180821161043b5761178b906116be565b915f5b8281111561179c5750505090565b7fff000000000000000000000000000000000000000000000000000000000000006117c78284610bf0565b51165f1a6117d58286610bf0565b537fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461043b5760010161178e565b50506118116020610b15565b5f815290565b61184c7fff000000000000000000000000000000000000000000000000000000000000006118458386610bf0565b5116611547565b1561189f577f8000000000000000000000000000000000000000000000000000000000000000811461043b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611746565b90505f61174f565b9081517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff905f5b81811061197e575b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82146119705761191061190b83836113bd565b6116be565b91805b82811061192257509193505050565b807fff0000000000000000000000000000000000000000000000000000000000000061195060019389610bf0565b511661196961195f85846113bd565b915f1a9187610bf0565b5301611913565b505090506118116020610b15565b6119ac7fff000000000000000000000000000000000000000000000000000000000000006118458388610bf0565b156119b9576001016118ce565b91505f6118d6565b91908110156104685760051b0190565b3567ffffffffffffffff8116810361014e5790565b9291905f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820182811161043b579492919093945b80851115611a4d575b50505050507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff90565b611a63611a5a86836113bd565b60011c866113ca565b948367ffffffffffffffff611a81611a7c89878a6119c1565b6119d1565b1603611a8f57505050505090565b8367ffffffffffffffff611aad611a7c89878a9c9b9798999a6119c1565b161015611acd57506001810180911161043b57905b949291909394611a1b565b91508015611b2d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff810190811115611ac2577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b849550611a2456fea2646970667358221220b8af321e682747d84dac15d7e027bf3fd3b1a99233a41f0e5b02025c9dbd410064736f6c634300081c0033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.