Source Code
Overview
APE Balance
0 APE
More Info
ContractCreator
Latest 1 internal transaction
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
12966030 | 28 days ago | 0 APE |
Loading...
Loading
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 Name:
World
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 1000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// 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"; // TODO: Find alternate VRF provider import {SamWitchVRFConsumerUpgradeable} from "./SamWitchVRFConsumerUpgradeable.sol"; import {ISamWitchVRF} from "./interfaces/ISamWitchVRF.sol"; import {IOracleRewardCB} from "./interfaces/IOracleRewardCB.sol"; import {WorldLibrary} from "./WorldLibrary.sol"; // solhint-disable-next-line no-global-import import "./globals/all.sol"; contract World is SamWitchVRFConsumerUpgradeable, UUPSUpgradeable, OwnableUpgradeable { using UnsafeMath for U256; using UnsafeMath for uint; event RequestSent(uint requestId, uint32 numWords, uint lastRandomWordsUpdatedTime); event RequestFulfilled(uint requestId, uint randomWord); event AddActions(Action[] actions); event EditActions(Action[] actions); event AddActionChoices(uint16 actionId, uint16[] actionChoiceIds, ActionChoiceInput[] choices); event EditActionChoices(uint16 actionId, uint16[] actionChoiceIds, ActionChoiceInput[] choices); event RemoveActionChoices(uint16 actionId, uint16[] actionChoiceIds); error RandomWordsCannotBeUpdatedYet(); error CanOnlyRequestAfterTheNextCheckpoint(uint currentTime, uint checkpoint); error RequestAlreadyFulfilled(); error NoValidRandomWord(); error CanOnlyRequestAfter1DayHasPassed(); error ActionIdZeroNotAllowed(); error MinCannotBeGreaterThanMax(); error DynamicActionsCannotBeAdded(); error ActionAlreadyExists(uint16 actionId); error ActionDoesNotExist(); error ActionChoiceIdZeroNotAllowed(); error DynamicActionsCannotBeSet(); error LengthMismatch(); error NoActionChoices(); error ActionChoiceAlreadyExists(); error ActionChoiceDoesNotExist(); error NotAFactorOf3600(); error NonCombatWithActionChoicesCannotHaveBothGuaranteedAndRandomRewards(); error InvalidReward(); error TooManyRewardsInPool(); error CallbackGasLimitTooHigh(); // Past request ids uint[] public requestIds; // Each one is a set of random words for 1 day mapping(uint requestId => uint randomWord) public randomWords; uint40 public lastRandomWordsUpdatedTime; uint40 private startTime; uint40 private weeklyRewardCheckpoint; bytes8 public thisWeeksRandomWordSegment; // Every 8 bits is a random segment for the day uint24 private callbackGasLimit; uint32 private constant NUM_WORDS = 1; uint32 public constant MIN_RANDOM_WORDS_UPDATE_TIME = 1 days; uint32 private constant MIN_DYNAMIC_ACTION_UPDATE_TIME = 1 days; uint32 public constant NUM_DAYS_RANDOM_WORDS_INITIALIZED = 3; mapping(uint actionId => ActionInfo actionInfo) public actions; uint16[] private lastAddedDynamicActions; uint private lastDynamicUpdatedTime; /// @custom:oz-renamed-from dailyRewards bytes32 dummy; // Not clean mapping(uint actionId => mapping(uint16 choiceId => ActionChoice actionChoice)) private actionChoices; mapping(uint actionId => CombatStats combatStats) private actionCombatStats; mapping(uint actionId => ActionRewards actionRewards) private actionRewards; IOracleRewardCB private quests; mapping(uint tier => Equipment[]) public dailyRewardPool; mapping(uint tier => Equipment[]) public weeklyRewardPool; IOracleRewardCB private wishingWell; /// @custom:oz-upgrades-unsafe-allow constructor constructor() { _disableInitializers(); } function initialize(address _vrf) external initializer { __SamWitchVRFConsumerUpgradeable_init(ISamWitchVRF(_vrf)); __UUPSUpgradeable_init(); __Ownable_init(); startTime = uint40( (block.timestamp / MIN_RANDOM_WORDS_UPDATE_TIME) * MIN_RANDOM_WORDS_UPDATE_TIME - (NUM_DAYS_RANDOM_WORDS_INITIALIZED + 1) * 1 days ); // Floor to the nearest day 00:00 UTC lastRandomWordsUpdatedTime = uint40(startTime + NUM_DAYS_RANDOM_WORDS_INITIALIZED * 1 days); weeklyRewardCheckpoint = uint40((block.timestamp - 4 days) / 1 weeks) * 1 weeks + 4 days + 1 weeks; callbackGasLimit = 600_000; // Initialize a few days worth of random words so that we have enough data to fetch the first day for (U256 iter; iter.lt(NUM_DAYS_RANDOM_WORDS_INITIALIZED); 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[](1); _randomWords[0] = uint( blockhash(block.number - NUM_DAYS_RANDOM_WORDS_INITIALIZED + i) ^ 0x3632d8eba811d69784e6904a58de6e0ab55f32638189623b309895beaa6920c4 ); _fulfillRandomWords(requestId, _randomWords); } thisWeeksRandomWordSegment = bytes8(uint64(randomWords[0])); } function requestRandomWords() external returns (uint requestId) { // Last one has not been fulfilled yet if (requestIds.length != 0 && randomWords[requestIds[requestIds.length - 1]] == 0) { revert RandomWordsCannotBeUpdatedYet(); } uint40 newLastRandomWordsUpdatedTime = lastRandomWordsUpdatedTime + MIN_RANDOM_WORDS_UPDATE_TIME; if (newLastRandomWordsUpdatedTime > block.timestamp) { revert CanOnlyRequestAfterTheNextCheckpoint(block.timestamp, newLastRandomWordsUpdatedTime); } requestId = uint256(samWitchVRF.requestRandomWords(NUM_WORDS, callbackGasLimit)); requestIds.push(requestId); lastRandomWordsUpdatedTime = newLastRandomWordsUpdatedTime; emit RequestSent(requestId, NUM_WORDS, newLastRandomWordsUpdatedTime); return requestId; } function fulfillRandomWords(bytes32 _requestId, uint[] memory _randomWords) external onlySamWitchVRF { _fulfillRandomWords(uint(_requestId), _randomWords); } function getWeeklyReward(uint _tier, uint _playerId) public view returns (uint16 itemTokenId, uint24 amount) { uint day = 7; uint index = _getRewardIndex(_playerId, day, uint64(thisWeeksRandomWordSegment), weeklyRewardPool[_tier].length); Equipment storage equipment = weeklyRewardPool[_tier][index]; return (equipment.itemTokenId, equipment.amount); } function getSpecificDailyReward( uint _tier, uint _playerId, uint _day, uint _randomWord ) public view returns (uint16 itemTokenId, uint24 amount) { uint index = _getRewardIndex(_playerId, _day, _randomWord, dailyRewardPool[_tier].length); Equipment storage equipment = dailyRewardPool[_tier][index]; return (equipment.itemTokenId, equipment.amount); } function getDailyReward(uint _tier, uint _playerId) 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; return getSpecificDailyReward(_tier, _playerId, day, uint64(thisWeeksRandomWordSegment)); } function getActiveDailyAndWeeklyRewards( uint _tier, uint _playerId ) external view returns (Equipment[8] memory rewards) { for (uint i; i < 7; ++i) { (rewards[i].itemTokenId, rewards[i].amount) = getSpecificDailyReward( _tier, _playerId, i, uint64(thisWeeksRandomWordSegment) ); } (rewards[7].itemTokenId, rewards[7].amount) = getWeeklyReward(_tier, _playerId); } function _getRandomWordOffset(uint _timestamp) private view returns (int) { if (_timestamp < startTime) { return -1; } return int((_timestamp - startTime) / MIN_RANDOM_WORDS_UPDATE_TIME); } 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)]]; } 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 getMultipleWords(uint _timestamp) public view returns (uint[4] memory words) { for (U256 iter; iter.lt(4); iter = iter.inc()) { uint i = iter.asUint256(); words[i] = getRandomWord(_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 getActionInfo(uint _actionId) external view returns (ActionInfo memory info) { return actions[_actionId]; } 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 choice) { ActionChoice storage actionChoice = actionChoices[_actionId][_choiceId]; choice.skill = actionChoice.skill; choice.minXP = actionChoice.minXP; choice.skillDiff = actionChoice.skillDiff; choice.rate = actionChoice.rate; choice.xpPerHour = actionChoice.xpPerHour; choice.inputTokenId1 = actionChoice.inputTokenId1; choice.inputAmount1 = actionChoice.inputAmount1; choice.inputTokenId2 = actionChoice.inputTokenId2; choice.inputAmount2 = actionChoice.inputAmount2; choice.inputTokenId3 = actionChoice.inputTokenId3; choice.inputAmount3 = actionChoice.inputAmount3; choice.outputTokenId = actionChoice.outputTokenId; choice.outputAmount = actionChoice.outputAmount; choice.successPercent = actionChoice.successPercent; choice.handItemTokenIdRangeMin = actionChoice.handItemTokenIdRangeMin; choice.handItemTokenIdRangeMax = actionChoice.handItemTokenIdRangeMax; choice.packedData = actionChoice.packedData; // Only read second storage when needed if ( (uint8(choice.packedData >> ACTION_CHOICE_USE_NEW_MIN_SKILL_SECOND_STORAGE_SLOT_BIT) & 1 == 1) || (uint8(choice.packedData >> ACTION_CHOICE_USE_ALTERNATE_INPUTS_SECOND_STORAGE_SLOT) & 1 == 1) ) { choice.minSkill2 = actionChoice.minSkill2; choice.minXP2 = actionChoice.minXP2; choice.minSkill3 = actionChoice.minSkill3; choice.minXP3 = actionChoice.minXP3; choice.newInputAmount1 = actionChoice.newInputAmount1; choice.newInputAmount2 = actionChoice.newInputAmount2; choice.newInputAmount3 = actionChoice.newInputAmount3; } } 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 skill, uint numSpanwed, uint8 worldLocation) { return ( actionRewards[_actionId], actions[_actionId].skill, actions[_actionId].numSpawned, actions[_actionId].worldLocation ); } function getRandomBytes( uint _numTickets, uint _startTimestamp, uint _endTimestamp, uint _playerId ) external view returns (bytes memory b) { if (_numTickets <= 16) { // 32 bytes bytes32 word = bytes32(getRandomWord(_endTimestamp)); b = abi.encodePacked(_getRandomComponent(word, _startTimestamp, _endTimestamp, _playerId)); } else if (_numTickets <= MAX_UNIQUE_TICKETS_) { // 4 * 32 bytes uint[4] memory multipleWords = getMultipleWords(_endTimestamp); for (U256 iter; iter.lt(4); iter = iter.inc()) { uint i = iter.asUint256(); multipleWords[i] = uint( _getRandomComponent(bytes32(multipleWords[i]), _startTimestamp, _endTimestamp, _playerId) ); // XOR all the words with the first fresh random number to give more randomness to the existing random words if (i != 0) { multipleWords[i] = uint(keccak256(abi.encodePacked(multipleWords[i] ^ multipleWords[0]))); } } b = abi.encodePacked(multipleWords); } else { assert(false); } } function _addAction(Action calldata _action) private { if (_action.info.isDynamic) { revert DynamicActionsCannotBeAdded(); } if (actions[_action.actionId].skill != Skill.NONE) { revert ActionAlreadyExists(_action.actionId); } _setAction(_action); } function _getRewardIndex(uint _playerId, uint _day, uint _randomWord, uint _length) private pure returns (uint) { return uint(keccak256(abi.encodePacked(_randomWord, _playerId)) >> (_day * 8)) % _length; } function _setAction(Action calldata _action) private { if (_action.actionId == 0) { revert ActionIdZeroNotAllowed(); } if (_action.info.handItemTokenIdRangeMin > _action.info.handItemTokenIdRangeMax) { revert MinCannotBeGreaterThanMax(); } 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. Only care about the first one as it's used for correctly taking into account partial loots. 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]; delete actionRewards[_action.actionId]; WorldLibrary.setActionGuaranteedRewards(_action.guaranteedRewards, actionReward); WorldLibrary.setActionRandomRewards(_action.randomRewards, 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 && _action.info.actionChoiceRequired) { revert NonCombatWithActionChoicesCannotHaveBothGuaranteedAndRandomRewards(); } } } function _addActionChoice( uint16 _actionId, uint16 _actionChoiceId, ActionChoiceInput calldata _actionChoiceInput ) private view { if (_actionChoiceId == 0) { revert ActionChoiceIdZeroNotAllowed(); } if (actionChoices[_actionId][_actionChoiceId].skill != Skill.NONE) { revert ActionChoiceAlreadyExists(); } WorldLibrary.checkActionChoice(_actionChoiceInput); } function _editActionChoice( uint16 _actionId, uint16 _actionChoiceId, ActionChoiceInput calldata _actionChoiceInput ) private view { if (actionChoices[_actionId][_actionChoiceId].skill == Skill.NONE) { revert ActionChoiceDoesNotExist(); } WorldLibrary.checkActionChoice(_actionChoiceInput); } function _getRandomComponent( bytes32 _word, uint _startTimestamp, uint _endTimestamp, uint _playerId ) private pure returns (bytes32) { return keccak256(abi.encodePacked(_word, _startTimestamp, _endTimestamp, _playerId)); } function _packActionChoice( ActionChoiceInput calldata _actionChoiceInput ) private pure returns (ActionChoice memory actionChoice) { bytes1 packedData = bytes1(uint8(_actionChoiceInput.isFullModeOnly ? 1 << IS_FULL_MODE_BIT : 0)); if (_actionChoiceInput.minSkills.length > 1) { packedData |= bytes1(uint8(1)) << ACTION_CHOICE_USE_NEW_MIN_SKILL_SECOND_STORAGE_SLOT_BIT; } bool anyInputExceedsStandardAmount = (_actionChoiceInput.inputAmounts.length > 0 && _actionChoiceInput.inputAmounts[0] > 255) || (_actionChoiceInput.inputAmounts.length > 1 && _actionChoiceInput.inputAmounts[1] > 255) || (_actionChoiceInput.inputAmounts.length > 2 && _actionChoiceInput.inputAmounts[2] > 255); if (anyInputExceedsStandardAmount) { packedData |= bytes1(uint8(1)) << ACTION_CHOICE_USE_ALTERNATE_INPUTS_SECOND_STORAGE_SLOT; } actionChoice = ActionChoice({ skill: _actionChoiceInput.skill, minXP: _actionChoiceInput.minXPs.length != 0 ? _actionChoiceInput.minXPs[0] : 0, skillDiff: _actionChoiceInput.skillDiff, rate: _actionChoiceInput.rate, xpPerHour: _actionChoiceInput.xpPerHour, inputTokenId1: _actionChoiceInput.inputTokenIds.length > 0 ? _actionChoiceInput.inputTokenIds[0] : NONE, inputAmount1: _actionChoiceInput.inputAmounts.length > 0 && !anyInputExceedsStandardAmount ? uint8(_actionChoiceInput.inputAmounts[0]) : 0, inputTokenId2: _actionChoiceInput.inputTokenIds.length > 1 ? _actionChoiceInput.inputTokenIds[1] : NONE, inputAmount2: _actionChoiceInput.inputAmounts.length > 1 && !anyInputExceedsStandardAmount ? uint8(_actionChoiceInput.inputAmounts[1]) : 0, inputTokenId3: _actionChoiceInput.inputTokenIds.length > 2 ? _actionChoiceInput.inputTokenIds[2] : NONE, inputAmount3: _actionChoiceInput.inputAmounts.length > 2 && !anyInputExceedsStandardAmount ? uint8(_actionChoiceInput.inputAmounts[2]) : 0, outputTokenId: _actionChoiceInput.outputTokenId, outputAmount: _actionChoiceInput.outputAmount, successPercent: _actionChoiceInput.successPercent, handItemTokenIdRangeMin: _actionChoiceInput.handItemTokenIdRangeMin, handItemTokenIdRangeMax: _actionChoiceInput.handItemTokenIdRangeMax, packedData: packedData, reserved: bytes1(uint8(0)), // Second storage slot minSkill2: _actionChoiceInput.minSkills.length > 1 ? _actionChoiceInput.minSkills[1] : Skill.NONE, minXP2: _actionChoiceInput.minXPs.length > 1 ? _actionChoiceInput.minXPs[1] : 0, minSkill3: _actionChoiceInput.minSkills.length > 2 ? _actionChoiceInput.minSkills[2] : Skill.NONE, minXP3: _actionChoiceInput.minXPs.length > 2 ? _actionChoiceInput.minXPs[2] : 0, newInputAmount1: _actionChoiceInput.inputAmounts.length > 0 && anyInputExceedsStandardAmount ? _actionChoiceInput.inputAmounts[0] : 0, newInputAmount2: _actionChoiceInput.inputAmounts.length > 1 && anyInputExceedsStandardAmount ? _actionChoiceInput.inputAmounts[1] : 0, newInputAmount3: _actionChoiceInput.inputAmounts.length > 2 && anyInputExceedsStandardAmount ? _actionChoiceInput.inputAmounts[2] : 0 }); } function _fulfillRandomWords(uint _requestId, uint[] memory _randomWords) internal { if (randomWords[_requestId] != 0) { revert RequestAlreadyFulfilled(); } if (_randomWords.length != NUM_WORDS) { revert LengthMismatch(); } uint randomWord = _randomWords[0]; if (randomWord == 0) { // Not sure if 0 can be selected, but in case use previous block hash as pseudo random number randomWord = uint(blockhash(block.number - 1)); } randomWords[_requestId] = randomWord; if (address(quests) != address(0)) { quests.newOracleRandomWords(randomWord); } if (address(wishingWell) != address(0)) { wishingWell.newOracleRandomWords(randomWord); } emit RequestFulfilled(_requestId, randomWord); // Are we at the threshold for a new week if (weeklyRewardCheckpoint <= ((block.timestamp) / 1 days) * 1 days) { // Issue new daily rewards for each tier based on the new random words thisWeeksRandomWordSegment = bytes8(uint64(randomWord)); weeklyRewardCheckpoint = uint40((block.timestamp - 4 days) / 1 weeks) * 1 weeks + 4 days + 1 weeks; } } 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); } function addActionChoices( uint16 _actionId, uint16[] calldata _actionChoiceIds, ActionChoiceInput[] calldata _actionChoices ) public onlyOwner { emit AddActionChoices(_actionId, _actionChoiceIds, _actionChoices); U256 actionChoiceLength = _actionChoices.length.asU256(); if (actionChoiceLength.neq(_actionChoiceIds.length)) { revert LengthMismatch(); } if (_actionChoiceIds.length == 0) { revert NoActionChoices(); } for (U256 iter; iter < actionChoiceLength; iter = iter.inc()) { uint16 i = iter.asUint16(); _addActionChoice(_actionId, _actionChoiceIds[i], _actionChoices[i]); // TODO: Could set the first storage slot only in cases where appropriate (same as editing) actionChoices[_actionId][_actionChoiceIds[i]] = _packActionChoice(_actionChoices[i]); } } // actionId of 0 means it is not tied to a specific action (combat) function addBulkActionChoices( uint16[] calldata _actionIds, uint16[][] calldata _actionChoiceIds, ActionChoiceInput[][] 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]; addActionChoices(actionId, _actionChoiceIds[i], _actionChoices[i]); } } function editActionChoices( uint16 _actionId, uint16[] calldata _actionChoiceIds, ActionChoiceInput[] calldata _actionChoices ) external onlyOwner { if (_actionChoiceIds.length == 0) { revert NoActionChoices(); } if (_actionChoiceIds.length != _actionChoices.length) { revert LengthMismatch(); } U256 actionIdsLength = _actionChoiceIds.length.asU256(); for (U256 iter; iter < actionIdsLength; iter = iter.inc()) { uint16 i = iter.asUint16(); _editActionChoice(_actionId, _actionChoiceIds[i], _actionChoices[i]); actionChoices[_actionId][_actionChoiceIds[i]] = _packActionChoice(_actionChoices[i]); } emit EditActionChoices(_actionId, _actionChoiceIds, _actionChoices); } function removeActionChoices(uint16 _actionId, uint16[] calldata _actionChoiceIds) external onlyOwner { if (_actionChoiceIds.length == 0) { revert NoActionChoices(); } U256 length = _actionChoiceIds.length.asU256(); for (U256 iter; iter < length; iter = iter.inc()) { uint16 i = iter.asUint16(); delete actionChoices[_actionId][_actionChoiceIds[i]]; } emit RemoveActionChoices(_actionId, _actionChoiceIds); } function setQuests(IOracleRewardCB _quests) external onlyOwner { quests = _quests; } function setWishingWell(IOracleRewardCB _wishingWell) external onlyOwner { wishingWell = _wishingWell; } function setDailyRewardPool(uint _tier, Equipment[] calldata _dailyRewards) external onlyOwner { if (_dailyRewards.length > 255) { revert TooManyRewardsInPool(); } delete dailyRewardPool[_tier]; for (uint i = 0; i < _dailyRewards.length; ++i) { // Amount should be divisible by 10 to allow percentage increases to be applied (like clan bonuses) if (_dailyRewards[i].itemTokenId == 0 || _dailyRewards[i].amount == 0 || _dailyRewards[i].amount % 10 != 0) { revert InvalidReward(); } dailyRewardPool[_tier].push(_dailyRewards[i]); } } function setWeeklyRewardPool(uint _tier, Equipment[] calldata _weeklyRewards) external onlyOwner { if (_weeklyRewards.length > 255) { revert TooManyRewardsInPool(); } delete weeklyRewardPool[_tier]; for (uint i = 0; i < _weeklyRewards.length; ++i) { if (_weeklyRewards[i].itemTokenId == NONE || _weeklyRewards[i].amount == 0) { revert InvalidReward(); } weeklyRewardPool[_tier].push(_weeklyRewards[i]); } } function setCallbackGasLimit(uint _gasLimit) external onlyOwner { if (_gasLimit > 3_000_000) { revert CallbackGasLimitTooHigh(); } callbackGasLimit = uint24(_gasLimit); } function setVRF(address _vrf) external onlyOwner { samWitchVRF = ISamWitchVRF(_vrf); } // solhint-disable-next-line no-empty-blocks function _authorizeUpgrade(address newImplementation) internal override onlyOwner {} }
// 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 // 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 (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 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 } struct QueuedActionInputV2 { 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 CombatStyle combatStyle; // specific style of combat uint40 petId; // id of the pet (can be empty) } 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 CombatStyle combatStyle; // specific style of combat } struct QueuedActionExtra { uint40 petId; // id of the pet (can be empty) } // Can't extend this due to the actionQueue variable in Player struct 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 CombatStyle combatStyle; // specific style of combat 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; // isValid first bit (not used yet) and hasPet 2nd bit uint24 reserved; } struct QueuedActionV1 { 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 CombatStyle combatStyle; // specific style of combat 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 (and events) struct Action { uint16 actionId; ActionInfo info; GuaranteedReward[] guaranteedRewards; RandomReward[] randomRewards; CombatStats combatStats; } struct ActionV1 { uint16 actionId; ActionInfoV1 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 uint8 worldLocation; // 0 is the main starting world bool isFullModeOnly; } struct ActionInfoV1 { 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) uint constant ACTION_CHOICE_USE_NEW_MIN_SKILL_SECOND_STORAGE_SLOT_BIT = 6; uint constant ACTION_CHOICE_USE_ALTERNATE_INPUTS_SECOND_STORAGE_SLOT = 5;
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; // Types and constants, no external dependencies 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.20; import {IBank} from "../interfaces/IBank.sol"; enum ClanRank { NONE, // Not in a clan COMMONER, // Member of the clan SCOUT, // Invite and kick commoners 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; uint88 gasPaid; // TODO remove in migration uint24 defendingVaultsOffset; uint40 blockAttacksTimestamp; uint8 blockAttacksCooldownHours; bool isInMMRArray; uint48[] playerIds; Vault[] defendingVaults; // Append only, and use defendingVaultsOffset to decide where the real start is uint40 superAttackCooldownTimestamp; } uint constant MAX_CLAN_COMBATANTS = 20; uint constant CLAN_WARS_GAS_PRICE_WINDOW_SIZE = 4;
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; 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; struct BulkTransferInfo { uint[] tokenIds; uint[] amounts; address to; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; enum BoostType { NONE, ANY_XP, COMBAT_XP, NON_COMBAT_XP, GATHERING, ABSENCE, PASSIVE_SKIP_CHANCE, // Clan wars PVP_BLOCK, PVP_REATTACK, PVP_SUPER_ATTACK } 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, AGILITY, 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 melee; int16 magic; int16 ranged; int16 health; // These include equipment int16 meleeDefence; int16 magicDefence; int16 rangedDefence; } enum CombatStyle { NONE, ATTACK, DEFENCE }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; 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 optimzation to avoid having to look up the owner of the pet in another storage slot // 1 byte left in this storage slot uint24 baseId; } 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; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; 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"0000000000000054000000AE0000010E00000176000001E60000025E000002DE00000368000003FD0000049B00000546000005FC000006C000000792000008730000096400000A6600000B7B00000CA400000DE100000F36000010A200001229000013CB0000158B0000176B0000196E00001B9400001DE20000205A000022FF000025D5000028DD00002C1E00002F99000033540000375200003B9A000040300000451900004A5C00004FFF0000560900005C810000637000006ADD000072D100007B570000847900008E42000098BE0000A3F90000B0020000BCE70000CAB80000D9860000E9630000FA6200010C990001201D0001350600014B6F0001637300017D2E000198C10001B64E0001D5F80001F7E600021C430002433B00026CFD000299BE0002C9B30002FD180003342B00036F320003AE730003F23D00043AE3000488BE0004DC2F0005359B000595700005FC2400066A360006E02D00075E990007E6160008774C000912EB0009B9B4000A6C74000B2C06000BF956000CD561000DC134000EBDF3000FCCD40010EF24"; 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 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; bytes1 packedData; // Contains worldLocation in first 6 bits (0 is the main starting world), 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 // 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 ranged; int16 meleeDefence; int16 magicDefence; int16 rangedDefence; int16 health; // Minimum requirements in this skill to use this item (can be NONE) Skill skill; uint32 minXP; } struct ItemV1 { EquipPosition equipPosition; bool exists; bool isTransferable; uint16 healthRestored; BoostType boostType; uint16 boostValue; uint24 boostDuration; int16 melee; int16 magic; int16 ranged; int16 meleeDefence; int16 magicDefence; int16 rangedDefence; int16 health; Skill skill; uint32 minXP; } struct ItemOutput { EquipPosition equipPosition; bool isFullModeOnly; bool isTransferable; uint16 healthRestored; BoostType boostType; uint16 boostValue; uint24 boostDuration; int16 melee; int16 magic; int16 ranged; int16 meleeDefence; int16 magicDefence; int16 rangedDefence; int16 health; 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 { Skill skill; // Skill that this action choice is related to 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[] inputTokenIds; uint24[] inputAmounts; uint16 outputTokenId; uint8 outputAmount; uint8 successPercent; // 0-100 uint16 handItemTokenIdRangeMin; // Inclusive uint16 handItemTokenIdRangeMax; // Inclusive bool isFullModeOnly; Skill[] minSkills; // Skills required to do this action choice uint32[] minXPs; // Min XP in the corresponding skills to be able to do this action choice } struct ActionChoiceInputV3 { Skill skill; // Skill that this action choice is related to 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[] inputTokenIds; uint8[] inputAmounts; uint16 outputTokenId; uint8 outputAmount; uint8 successPercent; // 0-100 uint16 handItemTokenIdRangeMin; // Inclusive uint16 handItemTokenIdRangeMax; // Inclusive bool isFullModeOnly; Skill[] minSkills; // Skills required to do this action choice uint32[] minXPs; // Min XP in the corresponding skills to be able to do this action choice } struct ActionChoiceInputV2 { 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 uint16 handItemTokenIdRangeMin; // Inclusive uint16 handItemTokenIdRangeMax; // Inclusive bool isFullModeOnly; } 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 uint16 handItemTokenIdRangeMin; // Inclusive uint16 handItemTokenIdRangeMax; // Inclusive // 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; bytes1 reserved; // Second storage slot Skill minSkill2; uint32 minXP2; Skill minSkill3; uint32 minXP3; uint24 newInputAmount1; // alternative inputAmount1 which is larger uint24 newInputAmount2; // alternative inputAmount2 which is larger uint24 newInputAmount3; // alternative inputAmount3 which is larger } struct ActionChoiceV2 { 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 uint16 handItemTokenIdRangeMin; // Inclusive uint16 handItemTokenIdRangeMax; // Inclusive bytes1 packedData; // FullMode is last bit } struct ActionChoiceV1 { Skill skill; uint32 minXP; int16 skillDiff; uint24 rate; 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 enum struct PackedXP { uint40 melee; uint40 ranged; uint40 magic; uint40 defence; uint40 health; uint40 reservedCombat; bytes2 packedDataIsMaxed; // 2 bits per skill, 1 = first maxed level // Next slot uint40 mining; uint40 woodcutting; uint40 fishing; uint40 smithing; uint40 thieving; uint40 crafting; bytes2 packedDataIsMaxed1; // 2 bits per skill, 1 = first maxed level // Next slot uint40 cooking; uint40 firemaking; uint40 agility; uint40 alchemy; uint40 fletching; uint40 forging; bytes2 packedDataIsMaxed2; // 2 bits per skill, 1 = first maxed level } 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 LotteryWinnerInfo { uint16 lotteryId; uint24 raffleId; uint16 itemTokenId; uint16 amount; bool instantConsume; uint40 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; uint[] xpRewardItemTokenIds; uint[] xpRewardAmounts; uint[] dailyRewardItemTokenIds; uint[] dailyRewardAmounts; PendingQueuedActionProcessed processedData; bytes32 dailyRewardMask; QuestState quests; uint 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; // 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; } uint constant MAX_UNIQUE_TICKETS_ = 64; uint constant IS_FULL_MODE_BIT = 7; // Passive/InstantVRF action uint constant IS_AVAILABLE_BIT = 1; // Queued action uint constant HAS_PET_BIT = 1;
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; 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 } struct PromotionInfoInput { Promotion promotion; uint40 startTime; uint40 endTime; // Exclusive uint8 numDailyRandomItemsToPick; // Number of items to pick uint40 minTotalXP; // Minimum xp required to claim uint brushCost; // 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 uint 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 } struct PromotionInfo { Promotion promotion; uint40 startTime; uint8 numDays; uint8 numDailyRandomItemsToPick; // Number of items to pick uint40 minTotalXP; // Minimum xp required to claim uint24 brushCost; // Cost in brush to mint the promotion (in ether), max 16mil // 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 } uint constant BRUSH_COST_MISSED_DAY_MUL = 10;
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; 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 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 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 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 reserved; // Reserved for future use (previously was questId and cleared) bytes1 packedData; // FullMode is last bit, first 6 bits is worldLocation } struct QuestV1 { 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 isFullModeOnly; // Was requireActionsCompletedBeforeBurning before } struct PlayerQuest { uint32 questId; uint16 actionCompletedNum1; uint16 actionCompletedNum2; uint16 actionChoiceCompletedNum; uint16 burnCompletedAmount; bool isFixed; } uint constant QUEST_PURSE_STRINGS = 5; // MAKE SURE THIS MATCHES definitions
// 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) 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; uint64 queueId; uint16 boostItemTokenId; uint24 elapsedTime; uint24 sentinelElapsedTime; 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) 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! } 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; } struct InstantVRFRandomReward { uint16 itemTokenId; uint16 chance; // out of 65535 uint16 amount; // out of 65535 } 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; uint constant TIER_1_DAILY_REWARD_START_XP = 0; uint constant TIER_2_DAILY_REWARD_START_XP = 7_650; uint constant TIER_3_DAILY_REWARD_START_XP = 33_913; uint constant TIER_4_DAILY_REWARD_START_XP = 195_864; uint constant TIER_5_DAILY_REWARD_START_XP = 784_726; uint constant TIER_6_DAILY_REWARD_START_XP = 2_219_451; // 4 bytes for each threshold, starts at 500 xp in decimal bytes constant xpRewardBytes = hex"00000000000001F4000003E8000009C40000138800002710000075300000C350000186A00001D4C0000493E0000557300007A120000927C0000B71B0000DBBA0000F424000124F800016E360001B7740001E8480002625A0002932E0002DC6C0";
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IBank { function initialize(uint clanId, address bankRegistry) external; function depositToken(address from, uint playerId, address token, uint amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface IOracleRewardCB { function newOracleRandomWords(uint randomWord) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; interface ISamWitchVRF { function requestRandomWords(uint numWords, uint callbackGasLimit) external returns (bytes32 requestId); function fulfillRandomWords( bytes32 requestId, address oracle, address fulfillAddress, uint256 callbackGasLimit, uint256 numWords, uint256[2] calldata publicKey, uint256[4] calldata proof, uint256[2] calldata uPoint, uint256[4] calldata vComponents ) external returns (bool callSuccess); }
// 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) (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 assembly ("memory-safe") { 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 pragma solidity ^0.8.20; import {Initializable} from "./ozUpgradeable/proxy/utils/Initializable.sol"; import {ISamWitchVRF} from "./interfaces/ISamWitchVRF.sol"; // This is useful as a drop in replacement for the VRFConsumerBaseV2Upgradeable from Chainlink keeping storage compatibility abstract contract SamWitchVRFConsumerUpgradeable is Initializable { ISamWitchVRF internal samWitchVRF; error CallerNotSamWitchVRF(); /** * @dev Initializes the contract setting the deployer as the initial owner. */ // solhint-disable-next-line func-name-mixedcase function __SamWitchVRFConsumerUpgradeable_init(ISamWitchVRF _samWitchVRF) internal onlyInitializing { samWitchVRF = _samWitchVRF; } /// @dev Reverts if the caller is not the SamWitchVRF contract. modifier onlySamWitchVRF() { if (msg.sender != address(samWitchVRF)) { revert CallerNotSamWitchVRF(); } _; } }
// 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 InputAmountsMustBeInOrder(); error TooManyInputItems(); error InvalidInputTokenId(); error LengthMismatch(); error InputItemNoDuplicates(); error InvalidSkill(); error MinimumSkillsNoDuplicates(); error TooManyMinSkills(); error OutputAmountCannotBeZero(); error OutputSpecifiedWithoutAmount(); error OutputTokenIdCannotBeEmpty(); error RandomRewardsMustBeInOrder(uint16 chance1, uint16 chance2); error RandomRewardNoDuplicates(); error GuaranteedRewardsNoDuplicates(); error NotAFactorOf3600(); error TooManyGuaranteedRewards(); error TooManyRandomRewards(); error FirstMinSkillMustBeActionChoiceSkill(); function checkActionChoice(ActionChoiceInput calldata _actionChoiceInput) external pure { uint16[] calldata inputTokenIds = _actionChoiceInput.inputTokenIds; uint24[] calldata amounts = _actionChoiceInput.inputAmounts; if (inputTokenIds.length > 3) { revert TooManyInputItems(); } if (inputTokenIds.length != amounts.length) { revert LengthMismatch(); } if (_actionChoiceInput.outputTokenId != NONE && _actionChoiceInput.outputAmount == 0) { revert OutputAmountCannotBeZero(); } if (_actionChoiceInput.outputTokenId == NONE && _actionChoiceInput.outputAmount != 0) { revert OutputTokenIdCannotBeEmpty(); } for (uint i; i < inputTokenIds.length; ++i) { if (inputTokenIds[i] == 0) { revert InvalidInputTokenId(); } if (amounts[i] == 0) { revert InputSpecifiedWithoutAmount(); } if (i != inputTokenIds.length - 1) { if (amounts[i] > amounts[i + 1]) { revert InputAmountsMustBeInOrder(); } for (uint j; j < inputTokenIds.length; ++j) { if (j != i && inputTokenIds[i] == inputTokenIds[j]) { revert InputItemNoDuplicates(); } } } } // Check minimum xp Skill[] calldata minSkills = _actionChoiceInput.minSkills; uint32[] calldata minXPs = _actionChoiceInput.minXPs; // First minSkill must be the same as the action choice skill if (minSkills.length > 0 && minSkills[0] != _actionChoiceInput.skill) { revert FirstMinSkillMustBeActionChoiceSkill(); } if (minSkills.length > 3) { revert TooManyMinSkills(); } if (minSkills.length != minXPs.length) { revert LengthMismatch(); } for (uint i; i < minSkills.length; ++i) { if (minSkills[i] == Skill.NONE) { revert InvalidSkill(); } // Can only be 0 if it's the first one and there is more than one if (minXPs[i] == 0 && (i != 0 || minSkills.length == 1)) { revert InputSpecifiedWithoutAmount(); } if (i != minSkills.length - 1) { for (uint j; j < minSkills.length; ++j) { if (j != i && minSkills[i] == minSkills[j]) { revert MinimumSkillsNoDuplicates(); } } } } if (_actionChoiceInput.rate != 0) { // Check that it is a factor of 3600 if ((3600 * RATE_MUL) % _actionChoiceInput.rate != 0) { revert NotAFactorOf3600(); } } } function setActionGuaranteedRewards( GuaranteedReward[] calldata _guaranteedRewards, ActionRewards storage _actionRewards ) external { uint 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; if (_actionRewards.guaranteedRewardTokenId1 == _actionRewards.guaranteedRewardTokenId2) { revert GuaranteedRewardsNoDuplicates(); } } if (guaranteedRewardsLength > 2) { _actionRewards.guaranteedRewardTokenId3 = _guaranteedRewards[2].itemTokenId; _actionRewards.guaranteedRewardRate3 = _guaranteedRewards[2].rate; U256 bounds = guaranteedRewardsLength.dec().asU256(); for (U256 iter; iter < bounds; iter = iter.inc()) { uint i = iter.asUint256(); if (_guaranteedRewards[i].itemTokenId == _guaranteedRewards[guaranteedRewardsLength.dec()].itemTokenId) { revert GuaranteedRewardsNoDuplicates(); } } } if (guaranteedRewardsLength > 3) { revert TooManyGuaranteedRewards(); } } // Random rewards have most common one first function setActionRandomRewards(RandomReward[] calldata _randomRewards, ActionRewards storage actionReward) external { uint randomRewardsLength = _randomRewards.length; if (randomRewardsLength != 0) { actionReward.randomRewardTokenId1 = _randomRewards[0].itemTokenId; actionReward.randomRewardChance1 = _randomRewards[0].chance; actionReward.randomRewardAmount1 = _randomRewards[0].amount; } if (randomRewardsLength > 1) { actionReward.randomRewardTokenId2 = _randomRewards[1].itemTokenId; actionReward.randomRewardChance2 = _randomRewards[1].chance; actionReward.randomRewardAmount2 = _randomRewards[1].amount; if (actionReward.randomRewardChance2 > actionReward.randomRewardChance1) { revert RandomRewardsMustBeInOrder(_randomRewards[0].chance, _randomRewards[1].chance); } if (actionReward.randomRewardTokenId1 == actionReward.randomRewardTokenId2) { revert RandomRewardNoDuplicates(); } } if (randomRewardsLength > 2) { actionReward.randomRewardTokenId3 = _randomRewards[2].itemTokenId; actionReward.randomRewardChance3 = _randomRewards[2].chance; actionReward.randomRewardAmount3 = _randomRewards[2].amount; if (actionReward.randomRewardChance3 > actionReward.randomRewardChance2) { revert RandomRewardsMustBeInOrder(_randomRewards[1].chance, _randomRewards[2].chance); } U256 bounds = randomRewardsLength.dec().asU256(); for (U256 iter; iter < bounds; iter = iter.inc()) { uint i = iter.asUint256(); if (_randomRewards[i].itemTokenId == _randomRewards[randomRewardsLength.dec()].itemTokenId) { revert RandomRewardNoDuplicates(); } } } if (_randomRewards.length > 3) { actionReward.randomRewardTokenId4 = _randomRewards[3].itemTokenId; actionReward.randomRewardChance4 = _randomRewards[3].chance; actionReward.randomRewardAmount4 = _randomRewards[3].amount; if (actionReward.randomRewardChance4 > actionReward.randomRewardChance3) { revert RandomRewardsMustBeInOrder(_randomRewards[2].chance, _randomRewards[3].chance); } U256 bounds = _randomRewards.length.dec().asU256(); for (U256 iter; iter < bounds; iter = iter.inc()) { uint i = iter.asUint256(); if (_randomRewards[i].itemTokenId == _randomRewards[_randomRewards.length - 1].itemTokenId) { revert RandomRewardNoDuplicates(); } } } if (_randomRewards.length > 4) { revert TooManyRandomRewards(); } } }
{ "evmVersion": "paris", "optimizer": { "enabled": true, "runs": 1000, "details": { "yul": true } }, "viaIR": true, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": { "contracts/WorldLibrary.sol": { "WorldLibrary": "0x43da95dc00babae5d00ebea2c8088f3f7cd77832" } } }
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint16","name":"actionId","type":"uint16"}],"name":"ActionAlreadyExists","type":"error"},{"inputs":[],"name":"ActionChoiceAlreadyExists","type":"error"},{"inputs":[],"name":"ActionChoiceDoesNotExist","type":"error"},{"inputs":[],"name":"ActionChoiceIdZeroNotAllowed","type":"error"},{"inputs":[],"name":"ActionDoesNotExist","type":"error"},{"inputs":[],"name":"ActionIdZeroNotAllowed","type":"error"},{"inputs":[],"name":"AddressIsNotContract","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"BeaconImplementationIsNotAContract","type":"error"},{"inputs":[],"name":"CallbackGasLimitTooHigh","type":"error"},{"inputs":[],"name":"CallerIsNotOwner","type":"error"},{"inputs":[],"name":"CallerNotSamWitchVRF","type":"error"},{"inputs":[],"name":"CanOnlyRequestAfter1DayHasPassed","type":"error"},{"inputs":[{"internalType":"uint256","name":"currentTime","type":"uint256"},{"internalType":"uint256","name":"checkpoint","type":"uint256"}],"name":"CanOnlyRequestAfterTheNextCheckpoint","type":"error"},{"inputs":[],"name":"DynamicActionsCannotBeAdded","type":"error"},{"inputs":[],"name":"DynamicActionsCannotBeSet","type":"error"},{"inputs":[],"name":"FunctionMustBeCalledThroughActiveProxy","type":"error"},{"inputs":[],"name":"FunctionMustBeCalledThroughDelegateCall","type":"error"},{"inputs":[],"name":"FunctionMustNotBeCalledThroughDelegateCall","type":"error"},{"inputs":[],"name":"InvalidReward","type":"error"},{"inputs":[],"name":"IsInitializing","type":"error"},{"inputs":[],"name":"LengthMismatch","type":"error"},{"inputs":[],"name":"MinCannotBeGreaterThanMax","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":"NoActionChoices","type":"error"},{"inputs":[],"name":"NoValidRandomWord","type":"error"},{"inputs":[],"name":"NonCombatWithActionChoicesCannotHaveBothGuaranteedAndRandomRewards","type":"error"},{"inputs":[],"name":"NotAFactorOf3600","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[],"name":"RandomWordsCannotBeUpdatedYet","type":"error"},{"inputs":[],"name":"RequestAlreadyFulfilled","type":"error"},{"inputs":[],"name":"TooManyRewardsInPool","type":"error"},{"inputs":[],"name":"UnsupportedProxiableUUID","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"actionId","type":"uint16"},{"indexed":false,"internalType":"uint16[]","name":"actionChoiceIds","type":"uint16[]"},{"components":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"int16","name":"skillDiff","type":"int16"},{"internalType":"uint24","name":"rate","type":"uint24"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint16[]","name":"inputTokenIds","type":"uint16[]"},{"internalType":"uint24[]","name":"inputAmounts","type":"uint24[]"},{"internalType":"uint16","name":"outputTokenId","type":"uint16"},{"internalType":"uint8","name":"outputAmount","type":"uint8"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"bool","name":"isFullModeOnly","type":"bool"},{"internalType":"enum Skill[]","name":"minSkills","type":"uint8[]"},{"internalType":"uint32[]","name":"minXPs","type":"uint32[]"}],"indexed":false,"internalType":"struct ActionChoiceInput[]","name":"choices","type":"tuple[]"}],"name":"AddActionChoices","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint16","name":"actionId","type":"uint16"},{"components":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"bool","name":"isAvailable","type":"bool"},{"internalType":"bool","name":"isDynamic","type":"bool"},{"internalType":"bool","name":"actionChoiceRequired","type":"bool"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"uint24","name":"numSpawned","type":"uint24"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint8","name":"worldLocation","type":"uint8"},{"internalType":"bool","name":"isFullModeOnly","type":"bool"}],"internalType":"struct ActionInfo","name":"info","type":"tuple"},{"components":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint16","name":"rate","type":"uint16"}],"internalType":"struct GuaranteedReward[]","name":"guaranteedRewards","type":"tuple[]"},{"components":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint16","name":"chance","type":"uint16"},{"internalType":"uint8","name":"amount","type":"uint8"}],"internalType":"struct RandomReward[]","name":"randomRewards","type":"tuple[]"},{"components":[{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"ranged","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangedDefence","type":"int16"}],"internalType":"struct CombatStats","name":"combatStats","type":"tuple"}],"indexed":false,"internalType":"struct Action[]","name":"actions","type":"tuple[]"}],"name":"AddActions","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":"beacon","type":"address"}],"name":"BeaconUpgraded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"actionId","type":"uint16"},{"indexed":false,"internalType":"uint16[]","name":"actionChoiceIds","type":"uint16[]"},{"components":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"int16","name":"skillDiff","type":"int16"},{"internalType":"uint24","name":"rate","type":"uint24"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint16[]","name":"inputTokenIds","type":"uint16[]"},{"internalType":"uint24[]","name":"inputAmounts","type":"uint24[]"},{"internalType":"uint16","name":"outputTokenId","type":"uint16"},{"internalType":"uint8","name":"outputAmount","type":"uint8"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"bool","name":"isFullModeOnly","type":"bool"},{"internalType":"enum Skill[]","name":"minSkills","type":"uint8[]"},{"internalType":"uint32[]","name":"minXPs","type":"uint32[]"}],"indexed":false,"internalType":"struct ActionChoiceInput[]","name":"choices","type":"tuple[]"}],"name":"EditActionChoices","type":"event"},{"anonymous":false,"inputs":[{"components":[{"internalType":"uint16","name":"actionId","type":"uint16"},{"components":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"bool","name":"isAvailable","type":"bool"},{"internalType":"bool","name":"isDynamic","type":"bool"},{"internalType":"bool","name":"actionChoiceRequired","type":"bool"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"uint24","name":"numSpawned","type":"uint24"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint8","name":"worldLocation","type":"uint8"},{"internalType":"bool","name":"isFullModeOnly","type":"bool"}],"internalType":"struct ActionInfo","name":"info","type":"tuple"},{"components":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint16","name":"rate","type":"uint16"}],"internalType":"struct GuaranteedReward[]","name":"guaranteedRewards","type":"tuple[]"},{"components":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint16","name":"chance","type":"uint16"},{"internalType":"uint8","name":"amount","type":"uint8"}],"internalType":"struct RandomReward[]","name":"randomRewards","type":"tuple[]"},{"components":[{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"ranged","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangedDefence","type":"int16"}],"internalType":"struct CombatStats","name":"combatStats","type":"tuple"}],"indexed":false,"internalType":"struct Action[]","name":"actions","type":"tuple[]"}],"name":"EditActions","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":false,"internalType":"uint16","name":"actionId","type":"uint16"},{"indexed":false,"internalType":"uint16[]","name":"actionChoiceIds","type":"uint16[]"}],"name":"RemoveActionChoices","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"randomWord","type":"uint256"}],"name":"RequestFulfilled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"},{"indexed":false,"internalType":"uint32","name":"numWords","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"lastRandomWordsUpdatedTime","type":"uint256"}],"name":"RequestSent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"implementation","type":"address"}],"name":"Upgraded","type":"event"},{"inputs":[],"name":"MIN_RANDOM_WORDS_UPDATE_TIME","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NUM_DAYS_RANDOM_WORDS_INITIALIZED","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"actionId","type":"uint256"}],"name":"actions","outputs":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"bool","name":"isAvailable","type":"bool"},{"internalType":"bool","name":"isDynamic","type":"bool"},{"internalType":"bool","name":"actionChoiceRequired","type":"bool"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"uint24","name":"numSpawned","type":"uint24"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint8","name":"worldLocation","type":"uint8"},{"internalType":"bool","name":"isFullModeOnly","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_actionId","type":"uint16"},{"internalType":"uint16[]","name":"_actionChoiceIds","type":"uint16[]"},{"components":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"int16","name":"skillDiff","type":"int16"},{"internalType":"uint24","name":"rate","type":"uint24"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint16[]","name":"inputTokenIds","type":"uint16[]"},{"internalType":"uint24[]","name":"inputAmounts","type":"uint24[]"},{"internalType":"uint16","name":"outputTokenId","type":"uint16"},{"internalType":"uint8","name":"outputAmount","type":"uint8"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"bool","name":"isFullModeOnly","type":"bool"},{"internalType":"enum Skill[]","name":"minSkills","type":"uint8[]"},{"internalType":"uint32[]","name":"minXPs","type":"uint32[]"}],"internalType":"struct ActionChoiceInput[]","name":"_actionChoices","type":"tuple[]"}],"name":"addActionChoices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"actionId","type":"uint16"},{"components":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"bool","name":"isAvailable","type":"bool"},{"internalType":"bool","name":"isDynamic","type":"bool"},{"internalType":"bool","name":"actionChoiceRequired","type":"bool"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"uint24","name":"numSpawned","type":"uint24"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint8","name":"worldLocation","type":"uint8"},{"internalType":"bool","name":"isFullModeOnly","type":"bool"}],"internalType":"struct ActionInfo","name":"info","type":"tuple"},{"components":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint16","name":"rate","type":"uint16"}],"internalType":"struct GuaranteedReward[]","name":"guaranteedRewards","type":"tuple[]"},{"components":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint16","name":"chance","type":"uint16"},{"internalType":"uint8","name":"amount","type":"uint8"}],"internalType":"struct RandomReward[]","name":"randomRewards","type":"tuple[]"},{"components":[{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"ranged","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangedDefence","type":"int16"}],"internalType":"struct CombatStats","name":"combatStats","type":"tuple"}],"internalType":"struct Action[]","name":"_actions","type":"tuple[]"}],"name":"addActions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_actionIds","type":"uint16[]"},{"internalType":"uint16[][]","name":"_actionChoiceIds","type":"uint16[][]"},{"components":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"int16","name":"skillDiff","type":"int16"},{"internalType":"uint24","name":"rate","type":"uint24"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint16[]","name":"inputTokenIds","type":"uint16[]"},{"internalType":"uint24[]","name":"inputAmounts","type":"uint24[]"},{"internalType":"uint16","name":"outputTokenId","type":"uint16"},{"internalType":"uint8","name":"outputAmount","type":"uint8"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"bool","name":"isFullModeOnly","type":"bool"},{"internalType":"enum Skill[]","name":"minSkills","type":"uint8[]"},{"internalType":"uint32[]","name":"minXPs","type":"uint32[]"}],"internalType":"struct ActionChoiceInput[][]","name":"_actionChoices","type":"tuple[][]"}],"name":"addBulkActionChoices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tier","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"dailyRewardPool","outputs":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint24","name":"amount","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_actionId","type":"uint16"},{"internalType":"uint16[]","name":"_actionChoiceIds","type":"uint16[]"},{"components":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"int16","name":"skillDiff","type":"int16"},{"internalType":"uint24","name":"rate","type":"uint24"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint16[]","name":"inputTokenIds","type":"uint16[]"},{"internalType":"uint24[]","name":"inputAmounts","type":"uint24[]"},{"internalType":"uint16","name":"outputTokenId","type":"uint16"},{"internalType":"uint8","name":"outputAmount","type":"uint8"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"bool","name":"isFullModeOnly","type":"bool"},{"internalType":"enum Skill[]","name":"minSkills","type":"uint8[]"},{"internalType":"uint32[]","name":"minXPs","type":"uint32[]"}],"internalType":"struct ActionChoiceInput[]","name":"_actionChoices","type":"tuple[]"}],"name":"editActionChoices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint16","name":"actionId","type":"uint16"},{"components":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"bool","name":"isAvailable","type":"bool"},{"internalType":"bool","name":"isDynamic","type":"bool"},{"internalType":"bool","name":"actionChoiceRequired","type":"bool"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"uint24","name":"numSpawned","type":"uint24"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint8","name":"worldLocation","type":"uint8"},{"internalType":"bool","name":"isFullModeOnly","type":"bool"}],"internalType":"struct ActionInfo","name":"info","type":"tuple"},{"components":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint16","name":"rate","type":"uint16"}],"internalType":"struct GuaranteedReward[]","name":"guaranteedRewards","type":"tuple[]"},{"components":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint16","name":"chance","type":"uint16"},{"internalType":"uint8","name":"amount","type":"uint8"}],"internalType":"struct RandomReward[]","name":"randomRewards","type":"tuple[]"},{"components":[{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"ranged","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangedDefence","type":"int16"}],"internalType":"struct CombatStats","name":"combatStats","type":"tuple"}],"internalType":"struct Action[]","name":"_actions","type":"tuple[]"}],"name":"editActions","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_requestId","type":"bytes32"},{"internalType":"uint256[]","name":"_randomWords","type":"uint256[]"}],"name":"fulfillRandomWords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_actionId","type":"uint16"},{"internalType":"uint16","name":"_choiceId","type":"uint16"}],"name":"getActionChoice","outputs":[{"components":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"int16","name":"skillDiff","type":"int16"},{"internalType":"uint24","name":"rate","type":"uint24"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint16","name":"inputTokenId1","type":"uint16"},{"internalType":"uint8","name":"inputAmount1","type":"uint8"},{"internalType":"uint16","name":"inputTokenId2","type":"uint16"},{"internalType":"uint8","name":"inputAmount2","type":"uint8"},{"internalType":"uint16","name":"inputTokenId3","type":"uint16"},{"internalType":"uint8","name":"inputAmount3","type":"uint8"},{"internalType":"uint16","name":"outputTokenId","type":"uint16"},{"internalType":"uint8","name":"outputAmount","type":"uint8"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"bytes1","name":"packedData","type":"bytes1"},{"internalType":"bytes1","name":"reserved","type":"bytes1"},{"internalType":"enum Skill","name":"minSkill2","type":"uint8"},{"internalType":"uint32","name":"minXP2","type":"uint32"},{"internalType":"enum Skill","name":"minSkill3","type":"uint8"},{"internalType":"uint32","name":"minXP3","type":"uint32"},{"internalType":"uint24","name":"newInputAmount1","type":"uint24"},{"internalType":"uint24","name":"newInputAmount2","type":"uint24"},{"internalType":"uint24","name":"newInputAmount3","type":"uint24"}],"internalType":"struct ActionChoice","name":"choice","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_actionId","type":"uint256"}],"name":"getActionInfo","outputs":[{"components":[{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"bool","name":"isAvailable","type":"bool"},{"internalType":"bool","name":"isDynamic","type":"bool"},{"internalType":"bool","name":"actionChoiceRequired","type":"bool"},{"internalType":"uint24","name":"xpPerHour","type":"uint24"},{"internalType":"uint32","name":"minXP","type":"uint32"},{"internalType":"uint24","name":"numSpawned","type":"uint24"},{"internalType":"uint16","name":"handItemTokenIdRangeMin","type":"uint16"},{"internalType":"uint16","name":"handItemTokenIdRangeMax","type":"uint16"},{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint8","name":"worldLocation","type":"uint8"},{"internalType":"bool","name":"isFullModeOnly","type":"bool"}],"internalType":"struct ActionInfo","name":"info","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_actionId","type":"uint256"}],"name":"getActionRewards","outputs":[{"components":[{"internalType":"uint16","name":"guaranteedRewardTokenId1","type":"uint16"},{"internalType":"uint16","name":"guaranteedRewardRate1","type":"uint16"},{"internalType":"uint16","name":"guaranteedRewardTokenId2","type":"uint16"},{"internalType":"uint16","name":"guaranteedRewardRate2","type":"uint16"},{"internalType":"uint16","name":"guaranteedRewardTokenId3","type":"uint16"},{"internalType":"uint16","name":"guaranteedRewardRate3","type":"uint16"},{"internalType":"uint16","name":"randomRewardTokenId1","type":"uint16"},{"internalType":"uint16","name":"randomRewardChance1","type":"uint16"},{"internalType":"uint8","name":"randomRewardAmount1","type":"uint8"},{"internalType":"uint16","name":"randomRewardTokenId2","type":"uint16"},{"internalType":"uint16","name":"randomRewardChance2","type":"uint16"},{"internalType":"uint8","name":"randomRewardAmount2","type":"uint8"},{"internalType":"uint16","name":"randomRewardTokenId3","type":"uint16"},{"internalType":"uint16","name":"randomRewardChance3","type":"uint16"},{"internalType":"uint8","name":"randomRewardAmount3","type":"uint8"},{"internalType":"uint16","name":"randomRewardTokenId4","type":"uint16"},{"internalType":"uint16","name":"randomRewardChance4","type":"uint16"},{"internalType":"uint8","name":"randomRewardAmount4","type":"uint8"}],"internalType":"struct ActionRewards","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_actionId","type":"uint16"}],"name":"getActionSuccessPercentAndMinXP","outputs":[{"internalType":"uint8","name":"successPercent","type":"uint8"},{"internalType":"uint32","name":"minXP","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tier","type":"uint256"},{"internalType":"uint256","name":"_playerId","type":"uint256"}],"name":"getActiveDailyAndWeeklyRewards","outputs":[{"components":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint24","name":"amount","type":"uint24"}],"internalType":"struct Equipment[8]","name":"rewards","type":"tuple[8]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_actionId","type":"uint16"}],"name":"getCombatStats","outputs":[{"components":[{"internalType":"int16","name":"melee","type":"int16"},{"internalType":"int16","name":"magic","type":"int16"},{"internalType":"int16","name":"ranged","type":"int16"},{"internalType":"int16","name":"health","type":"int16"},{"internalType":"int16","name":"meleeDefence","type":"int16"},{"internalType":"int16","name":"magicDefence","type":"int16"},{"internalType":"int16","name":"rangedDefence","type":"int16"}],"internalType":"struct CombatStats","name":"stats","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tier","type":"uint256"},{"internalType":"uint256","name":"_playerId","type":"uint256"}],"name":"getDailyReward","outputs":[{"internalType":"uint256","name":"itemTokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getMultipleWords","outputs":[{"internalType":"uint256[4]","name":"words","type":"uint256[4]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_actionId","type":"uint16"}],"name":"getNumSpawn","outputs":[{"internalType":"uint256","name":"numSpawned","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_numTickets","type":"uint256"},{"internalType":"uint256","name":"_startTimestamp","type":"uint256"},{"internalType":"uint256","name":"_endTimestamp","type":"uint256"},{"internalType":"uint256","name":"_playerId","type":"uint256"}],"name":"getRandomBytes","outputs":[{"internalType":"bytes","name":"b","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"getRandomWord","outputs":[{"internalType":"uint256","name":"randomWord","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_actionId","type":"uint16"}],"name":"getRewardsHelper","outputs":[{"components":[{"internalType":"uint16","name":"guaranteedRewardTokenId1","type":"uint16"},{"internalType":"uint16","name":"guaranteedRewardRate1","type":"uint16"},{"internalType":"uint16","name":"guaranteedRewardTokenId2","type":"uint16"},{"internalType":"uint16","name":"guaranteedRewardRate2","type":"uint16"},{"internalType":"uint16","name":"guaranteedRewardTokenId3","type":"uint16"},{"internalType":"uint16","name":"guaranteedRewardRate3","type":"uint16"},{"internalType":"uint16","name":"randomRewardTokenId1","type":"uint16"},{"internalType":"uint16","name":"randomRewardChance1","type":"uint16"},{"internalType":"uint8","name":"randomRewardAmount1","type":"uint8"},{"internalType":"uint16","name":"randomRewardTokenId2","type":"uint16"},{"internalType":"uint16","name":"randomRewardChance2","type":"uint16"},{"internalType":"uint8","name":"randomRewardAmount2","type":"uint8"},{"internalType":"uint16","name":"randomRewardTokenId3","type":"uint16"},{"internalType":"uint16","name":"randomRewardChance3","type":"uint16"},{"internalType":"uint8","name":"randomRewardAmount3","type":"uint8"},{"internalType":"uint16","name":"randomRewardTokenId4","type":"uint16"},{"internalType":"uint16","name":"randomRewardChance4","type":"uint16"},{"internalType":"uint8","name":"randomRewardAmount4","type":"uint8"}],"internalType":"struct ActionRewards","name":"","type":"tuple"},{"internalType":"enum Skill","name":"skill","type":"uint8"},{"internalType":"uint256","name":"numSpanwed","type":"uint256"},{"internalType":"uint8","name":"worldLocation","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_actionId","type":"uint256"}],"name":"getSkill","outputs":[{"internalType":"enum Skill","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tier","type":"uint256"},{"internalType":"uint256","name":"_playerId","type":"uint256"},{"internalType":"uint256","name":"_day","type":"uint256"},{"internalType":"uint256","name":"_randomWord","type":"uint256"}],"name":"getSpecificDailyReward","outputs":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint24","name":"amount","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tier","type":"uint256"},{"internalType":"uint256","name":"_playerId","type":"uint256"}],"name":"getWeeklyReward","outputs":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint24","name":"amount","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_actionId","type":"uint16"},{"internalType":"uint16","name":"_actionChoiceId","type":"uint16"}],"name":"getXPPerHour","outputs":[{"internalType":"uint24","name":"xpPerHour","type":"uint24"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_timestamp","type":"uint256"}],"name":"hasRandomWord","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_vrf","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastRandomWordsUpdatedTime","outputs":[{"internalType":"uint40","name":"","type":"uint40"}],"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":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"randomWords","outputs":[{"internalType":"uint256","name":"randomWord","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_actionId","type":"uint16"},{"internalType":"uint16[]","name":"_actionChoiceIds","type":"uint16[]"}],"name":"removeActionChoices","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requestRandomWords","outputs":[{"internalType":"uint256","name":"requestId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_gasLimit","type":"uint256"}],"name":"setCallbackGasLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tier","type":"uint256"},{"components":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint24","name":"amount","type":"uint24"}],"internalType":"struct Equipment[]","name":"_dailyRewards","type":"tuple[]"}],"name":"setDailyRewardPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOracleRewardCB","name":"_quests","type":"address"}],"name":"setQuests","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vrf","type":"address"}],"name":"setVRF","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tier","type":"uint256"},{"components":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint24","name":"amount","type":"uint24"}],"internalType":"struct Equipment[]","name":"_weeklyRewards","type":"tuple[]"}],"name":"setWeeklyRewardPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IOracleRewardCB","name":"_wishingWell","type":"address"}],"name":"setWishingWell","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"thisWeeksRandomWordSegment","outputs":[{"internalType":"bytes8","name":"","type":"bytes8"}],"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":"tier","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"weeklyRewardPool","outputs":[{"internalType":"uint16","name":"itemTokenId","type":"uint16"},{"internalType":"uint24","name":"amount","type":"uint24"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a080604052346200009e57306080526000549060ff8260081c166200008f575060ff8082161062000053575b6040516159f69081620000a4823960805181818161277e0152818161287501526130bc0152f35b60ff90811916176000557f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498602060405160ff8152a1386200002c565b63ce446e0f60e01b8152600490fd5b600080fdfe610220604052600436101561001357600080fd5b60003560e01c80631929f7b31461335757806322793d2814613340578063264c73521461326b5780632dc918c2146132285780633659cfe61461309657806336f15ed71461304e5780634a2f04a114612f575780634ad8c52914612b0a5780634f1ef286146127f857806352d1902d14612763578063582e5452146125ff5780635f9e245e146125135780636528f09a146124f557806371315901146124b2578063715018a61461245757806374db3052146123d7578063770d0441146123bb5780637fe4cf6b1461227a57806381ab74511461223d57806383240f83146121775780638693ef18146120565780638796ba8c1461201f57806388b33c5b14611f855780638a54942f14611ee65780638da5cb5b14611ebf5780638eafc36414611e8d57806395016e4b14611e56578063b8987a6e14611973578063bbea74f41461147b578063bd880fae14611445578063be52e34f14611378578063beff730f1461134c578063c4d66de814610fa2578063cc3172a114610dd0578063cc76b91114610daa578063d42da17214610c72578063d623d54c14610c16578063dd56f38b14610b4d578063debde28414610b28578063e0c8628914610940578063e5df71fc146108f9578063e63e9b91146107aa578063e87df97214610767578063f2fde38b14610702578063f5a62e191461069f578063f691689c146103325763fb2bbc7f1461022257600080fd5b3461032d5761023036613651565b919061023a61586f565b60ff8311610303578160005260d590602082815261025b60406000206157bd565b60005b85811061026757005b61ffff61027d6102788389876142cd565b614278565b161580156102e2575b6102b8576102b390856000528483526102ae60406000206102a8838a886142cd565b906157f2565b613843565b61025e565b60046040517f28829e82000000000000000000000000000000000000000000000000000000008152fd5b5062ffffff6102fc836102f6848a886142cd565b01614287565b1615610286565b60046040517f2862b710000000000000000000000000000000000000000000000000000000008152fd5b600080fd5b3461032d57604036600319011261032d5761032061034e613395565b6103566133a6565b61ffff610361613b22565b921660005260d060205261ffff604060002091166000526020526040600020805461038f60ff821684613b16565b63ffffffff8160081c1660208401528060281c60010b604084015262ffffff8160381c16606084015262ffffff8160501c16608084015261ffff8160681c1660a084015260ff8160781c1660c084015261ffff8160801c1660e084015260ff8160901c1661010084015261ffff8160981c1661012084015260ff8160a81c1661014084015261ffff8160b01c1661016084015260ff8160c01c1661018084015260ff8160c81c166101a084015261ffff8160d01c166101c084015261ffff8160e01c166101e08401526001600160f81b03198160081b166102008401526001808260f61c161490811561068e575b50610618575b5060405190610493828251613581565b63ffffffff6020820151166020830152604081015160010b604083015262ffffff606082015116606083015262ffffff608082015116608083015261ffff60a08201511660a083015260ff60c08201511660c083015261ffff60e08201511660e083015260ff6101008201511661010083015261ffff6101208201511661012083015260ff6101408201511661014083015261ffff6101608201511661016083015260ff6101808201511661018083015260ff6101a0820151166101a083015261ffff6101c0820151166101c083015261ffff6101e0820151166101e08301526001600160f81b0319610200820151166102008301526102206001600160f81b03198183015116908301526105b16102408083015190840190613581565b61026063ffffffff8183015116908301526105d56102808083015190840190613581565b6102a063ffffffff8183015116908301526102c062ffffff8183015116908301526102e062ffffff81830151169083015262ffffff610300809201511690820152f35b600162ffffff91015461063260ff82166102408501613b16565b63ffffffff8160081c1661026084015261065660ff8260281c166102808501613b16565b63ffffffff8160301c166102a0840152818160501c166102c0840152818160681c166102e084015260801c1661030082015282610483565b60019150819060f51c16148461047d565b3461032d57602036600319011261032d576106b86133f7565b6106c061586f565b75ffffffffffffffffffffffffffffffffffffffff00001975ffffffffffffffffffffffffffffffffffffffff00006000549260101b16911617600055600080f35b3461032d57602036600319011261032d5761071b6133f7565b61072361586f565b6001600160a01b0381161561073d5761073b906158ad565b005b60046040517f7448fbae000000000000000000000000000000000000000000000000000000008152fd5b3461032d57602036600319011261032d576004356001600160a01b03811680910361032d5761079461586f565b6001600160a01b031960d654161760d655600080f35b3461032d5760208060031936011261032d5760043567ffffffffffffffff811161032d576107dc9036906004016133c6565b906107e561586f565b81805b610822576040517fe0c485464feab584463337a60a5f3b30eeae5d466aa5ce2d973b306518e576a6908061081d868683613f74565b0390a1005b6000190161ffff6108368183168585613eb2565b906108436060830161426b565b6108cf578061085183614278565b1660005260cc865260ff6040600020541660288110156108b95761087f575061087a8291614358565b6107e8565b61088a602492614278565b6040517fd44e9bef00000000000000000000000000000000000000000000000000000000815291166004820152fd5b634e487b7160e01b600052602160045260246000fd5b60046040517fccdd1ab5000000000000000000000000000000000000000000000000000000008152fd5b3461032d5760208060031936011261032d5761091660043561392a565b604051916000835b6004821061092b57608085f35b8280600192865181520194019101909261091e565b3461032d57600036600319011261032d5760c9548015159081610af6575b50610acc5760cb5464ffffffffff6201518081831601818111610ab6571690428211610a7f576000916001600160a01b03835460101c1662ffffff604051937f1b739ef10000000000000000000000000000000000000000000000000000000085526001600486015260b81c1660248401528260448160209687945af1918215610a7357600092610a43575b5060607f643b454d39972ed209afefa4a771c7a9057229bc7e6b66566f5be8441bf9b1e291610a1884613706565b8064ffffffffff1960cb54161760cb55604051908482526001868301526040820152a1604051908152f35b9091508281813d8311610a6c575b610a5b8183613543565b8101031261032d57519060606109ea565b503d610a51565b6040513d6000823e3d90fd5b604482604051907f1351c9400000000000000000000000000000000000000000000000000000000082524260048301526024820152fd5b634e487b7160e01b600052601160045260246000fd5b60046040517f974b4f8a000000000000000000000000000000000000000000000000000000008152fd5b600019810191508111610ab657610b0c906135ec565b90549060031b1c60005260ca602052604060002054158161095e565b3461032d57600036600319011261032d57602064ffffffffff60cb5416604051908152f35b3461032d57610b5b36613651565b9190610b6561586f565b60ff8311610303578160005260d4906020828152610b8660406000206157bd565b60005b858110610b9257005b61ffff610ba36102788389876142cd565b16158015610bfb575b8015610bda575b6102b857610bd590856000528483526102ae60406000206102a8838a886142cd565b610b89565b5062ffffff600a81610bf1856102f6868c8a6142cd565b1606161515610bb3565b5062ffffff610c0f836102f6848a886142cd565b1615610bac565b3461032d57610c243661337f565b9060005260d56020526040600020805482101561032d57610c6e91610c4891613639565b50546040805161ffff8316815260109290921c62ffffff16602083015290918291820190565b0390f35b3461032d57610c803661337f565b6040519167ffffffffffffffff61010080850182811186821017610d945760405260005b818110610d6657505060cb5460781c1660005b60078110610d225784610cca858561374f565b60e08301519262ffffff9384602093168382015261ffff8094169052604051938491906000925b60088410610cff5761020087f35b846040600192848387518b81511684520151168382015201930193019291610cf1565b8061ffff610d3584610d619488886137c5565b9190610d41848a613852565b519262ffffff6020610d53878d613852565b510191169052169052613843565b610cb7565b60405190604082019180831085841117610d9457602092604052600081526000838201528188015201610ca4565b634e487b7160e01b600052604160045260246000fd5b3461032d57602036600319011261032d576020610dc86004356138dd565b604051908152f35b3461032d57602036600319011261032d576000610160604051610df281613498565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201528261012082015282610140820152015260043560005260cc602052610180604060002060ff60405191610e5883613498565b54610e6582821684613b16565b818160081c1615156020840152818160101c1615156040840152818160181c161515606084015262ffffff8160201c16608084015263ffffffff8160381c1660a084015262ffffff8160581c1660c084015261ffff8160701c1660e084015261ffff8160801c16610100840152818160901c16610120840152818160981c1661014084015260a01c16151561016082015261016060405191610f08838251613581565b60208101511515602084015260408101511515604084015260608101511515606084015262ffffff608082015116608084015263ffffffff60a08201511660a084015262ffffff60c08201511660c084015261ffff60e08201511660e084015261ffff6101008201511661010084015260ff6101208201511661012084015260ff6101408201511661014084015201511515610160820152f35b3461032d5760208060031936011261032d57610fbc6133f7565b906000549160ff8360081c16159081809261133f575b8015611328575b156112fe57600193828560ff198316176000556112ec575b5060005460ff8160081c16156112c25775ffffffffffffffffffffffffffffffffffffffff00001975ffffffffffffffffffffffffffffffffffffffff000060ff9360101b169116178060005560081c16156112c257611050336158ad565b620151808042049080820291808304821490151715610ab657620545ff19828101928311610ab65760cb92835469ffffffffff0000000000602892831b169064ffffffffff936203f480858469ffffffffff000000000019851617861c160190858211610ab6574201428111610ab657790927c00000000000000000000000000000000000000000000000937fffffffffffff000000ffffffffffffffff0000000000000000000000000000006effffffffff0000000000000000000061113161112c6111278b62093a8081989e9c9e04166136de565b6136ae565b6136c6565b60501b1694161791161717178455600090600219430192438411925b600381106111ea575050505050506000805260ca83526040600020547fffffffffffffffffff0000000000000000ffffffffffffffffffffffffffffff76ffffffffffffffff00000000000000000000000000000083549260781b1691161790556111b457005b7f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989161ff001960005416600055604051908152a1005b60c890808201809211610ab65761120082613706565b828854881c16848202828104861483151715610ab65761121f916136f9565b848101809111610ab65760608b7f643b454d39972ed209afefa4a771c7a9057229bc7e6b66566f5be8441bf9b1e2928e604051928784528301526040820152a16040519161126c8361350b565b8b8352858b3681860137610ab6578b926112bc917f3632d8eba811d69784e6904a58de6e0ab55f32638189623b309895beaa6920c46112ab858b6136f9565b40186112b683613742565b52613c27565b0161114d565b60046040517fd7e6bcf8000000000000000000000000000000000000000000000000000000008152fd5b61ffff19166101011760005584610ff1565b60046040517f0dc149f0000000000000000000000000000000000000000000000000000000008152fd5b50303b158015610fd95750600160ff851614610fd9565b50600160ff851610610fd2565b3461032d57602036600319011261032d5760043560005260ca6020526020604060002054604051908152f35b3461032d57604036600319011261032d5767ffffffffffffffff60243581811161032d573660238201121561032d578060040135918211610d94578160051b90604051916020936113cb85830185613543565b83526024848401918301019136831161032d57602401905b82821061143657836001600160a01b0360005460101c16330361140c5761073b90600435613c27565b60046040517f580ae425000000000000000000000000000000000000000000000000000000008152fd5b813581529084019084016113e3565b3461032d57602036600319011261032d5760043560005260cc602052602060ff604060002054166114796040518092613581565bf35b3461032d576114893661340d565b61149493919361586f565b7fa3ae391b4ec3b8276739f8c31c7074ec8a45be9b7f9663574f58fa257b49a060604051806114c7848888888c86614a69565b0390a182810361194957821561191f5760005b8181106114e357005b6114f561027861ffff83168686614cfb565b61ffff6115058184168589614d0b565b911680156118f55761ffff881660005260d060205260406000209060005260205260ff6040600020541660288110156108b9576118cb577343da95dc00babae5d00ebea2c8088f3f7cd778323b1561032d5760006115779160405180938192632ae2d1eb60e01b835260048301614d2e565b03817343da95dc00babae5d00ebea2c8088f3f7cd778325af48015610a73576118bc575b506115b36115ae61ffff83168488614d0b565b614fb1565b9061ffff871660005260d0602052604060002061ffff6115d96102788285168989614cfb565b1660005260205260406000209180519260288410156108b95761160466ffff000000000094826142dd565b6020820151815464ffffffff00191660089190911b64ffffffff001617815563ffffffff916040810151825469ffffff00000000000000606084015160381b169169ffffffffff00000000001997889160281b1691161717825562ffffff608061168c828285015116859062ffffff60501b82549160501b169062ffffff60501b1916179055565b60a0830151845460c08086015160e087015171ffffffffff0000000000000000000000000019909316606894851b6effff00000000000000000000000000161760789190911b60ff60781b161760809290921b61ffff60801b169190911786559094600191610100860151825460ff60901b191660909190911b60ff60901b16178255856101208101519183549060ff60a81b61014084015160a81b169060ff60c01b61ffff60b01b61016086015160b01b1691610180860151901b1660ff60c81b6101a086015160c81b169161ffff60d01b6101c087015160d01b169361ffff60e01b6101e088015160e01b169572ffffffffffffffffffffffffffffffffffffff61ffff60981b6001600160f81b031961022060ff60f01b6102008d015160081c169b0151169a60981b169116171717171717171717815501946102408401519060288210156108b9576117e561180692886142dd565b610260850151875464ffffffff001916911660081b64ffffffff0016178655565b6102808301519060288210156108b95761189472ffffffffffff0000000000000000000000000019936fffffff000000000000000000000000009360019a89549065ff000000000069ffffffff0000000000006102a08b015160301b169360281b169116171788556102c086015116879062ffffff60501b82549160501b169062ffffff60501b1916179055565b62ffffff60801b6102e0850151916103008854960151901b16941b16911617179055016114da565b6118c590613484565b8661159b565b60046040517fa7f589fe000000000000000000000000000000000000000000000000000000008152fd5b60046040517f665991b7000000000000000000000000000000000000000000000000000000008152fd5b60046040517f96ac6b94000000000000000000000000000000000000000000000000000000008152fd5b60046040517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b3461032d57606036600319011261032d5767ffffffffffffffff60043581811161032d576119a59036906004016133c6565b60243583811161032d576119bd9036906004016133c6565b92909360443590811161032d576119d89036906004016133c6565b9190926119e361586f565b82810361194957801561191f5760005b8181106119fc57005b61ffff8116611a0f610278828587614cfb565b90611a28611a1e828a8c6157a6565b919092888a6157a6565b611a3393919361586f565b7fa3ae391b4ec3b8276739f8c31c7074ec8a45be9b7f9663574f58fa257b49a06060405180611a66848888888c86614a69565b0390a182810361194957821561191f5760005b818110611a8e575050505050506001016119f3565b611aa061027861ffff83168686614cfb565b611aaf61ffff83168488614d0b565b9061ffff8116156118f55761ffff881660005260d060205261ffff6040600020911660005260205260ff6040600020541660288110156108b9576118cb577343da95dc00babae5d00ebea2c8088f3f7cd778323b1561032d576000611b289160405180938192632ae2d1eb60e01b835260048301614d2e565b03817343da95dc00babae5d00ebea2c8088f3f7cd778325af48015610a7357611e47575b50611b5f6115ae61ffff83168488614d0b565b9061ffff871660005260d0602052604060002061ffff611b856102788285168989614cfb565b1660005260205260406000209180519260288410156108b957611bb066ffff000000000094826142dd565b6020820151815464ffffffff00191660089190911b64ffffffff001617815563ffffffff916040810151825469ffffff00000000000000606084015160381b169169ffffffffff00000000001997889160281b1691161717825562ffffff6080611c38828285015116859062ffffff60501b82549160501b169062ffffff60501b1916179055565b60a0830151845460c08086015160e087015171ffffffffff0000000000000000000000000019909316606894851b6effff00000000000000000000000000161760789190911b60ff60781b161760809290921b61ffff60801b169190911786559094600191610100860151825460ff60901b191660909190911b60ff60901b16178255856101208101519183549060ff60a81b61014084015160a81b169060ff60c01b61ffff60b01b61016086015160b01b1691610180860151901b1660ff60c81b6101a086015160c81b169161ffff60d01b6101c087015160d01b169361ffff60e01b6101e088015160e01b169572ffffffffffffffffffffffffffffffffffffff61ffff60981b6001600160f81b031961022060ff60f01b6102008d015160081c169b0151169a60981b169116171717171717171717815501946102408401519060288210156108b9576117e5611d9192886142dd565b6102808301519060288210156108b957611e1f72ffffffffffff0000000000000000000000000019936fffffff000000000000000000000000009360019a89549065ff000000000069ffffffff0000000000006102a08b015160301b169360281b169116171788556102c086015116879062ffffff60501b82549160501b169062ffffff60501b1916179055565b62ffffff60801b6102e0850151916103008854960151901b16941b1691161717905501611a79565b611e5090613484565b8d611b4c565b3461032d57611e70611e673661358e565b929190916137c5565b6040805161ffff93909316835262ffffff91909116602083015290f35b3461032d57611e9b3661337f565b9060005260d46020526040600020805482101561032d57610c6e91610c4891613639565b3461032d57600036600319011261032d5760206001600160a01b0360975416604051908152f35b3461032d57602036600319011261032d57600435611f0261586f565b622dc6c08111611f5b577fffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffff79ffffff000000000000000000000000000000000000000000000060cb549260b81b1691161760cb55600080f35b60046040517fbfbc293b000000000000000000000000000000000000000000000000000000008152fd5b3461032d57611f933661337f565b620545ff194201428111610ab65762093a80809104818102918183041490151715610ab657620546008101809111610ab65762015180928342049284840293808504861490151715610ab657604094611ff361200b9462ffffff966136a1565b049067ffffffffffffffff60cb5460781c16926137c5565b61ffff849392935193168352166020820152f35b3461032d57602036600319011261032d5760043560c95481101561032d576120486020916135ec565b90546040519160031b1c8152f35b3461032d57602036600319011261032d5761206f6139b4565b5060043560005260d260205261024061208b6040600020613a38565b611479604051809261ffff8082511683528060208301511660208401528060408301511660408401528060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c08401528060e08301511660e084015261010060ff818401511690840152610120818184015116908401526101408181840151169084015261016060ff818401511690840152610180818184015116908401526101a0818184015116908401526101c060ff8184015116908401526101e0818184015116908401526102009081830151169083015260ff6102208092015116910152565b3461032d57602036600319011261032d5760043560005260cc6020526101806040600020546040519060ff906121af83838316613581565b818160081c1615156020840152818160101c1615156040840152818160181c161515606084015262ffffff808260201c16608085015263ffffffff8260381c1660a08501528160581c1660c084015261ffff808260701c1660e08501528160801c16610100840152818160901c16610120840152818160981c1661014084015260a01c161515610160820152f35b3461032d57602036600319011261032d5761ffff612259613395565b1660005260cc602052602062ffffff60406000205460581c16604051908152f35b3461032d576122883661358e565b9092909190601081116122d7575090826122ad926122a8610c6e956138dd565b613bf7565b604051906020820152602081526122c38161350b565b6040519182916020835260208301906135ac565b9091906040106123a5576122ea8361392a565b9260005b6004811061233e57505050506040519060208083016000905b600482106123295750505050806080610c6e925261232481613527565b6122c3565b82806001928651815201940191019092612307565b806123578484876123516001968b613919565b51613bf7565b6123618288613919565b528061236e575b016122ee565b6123788187613919565b51865118604051602080820192835281526123928161350b565b51902061239f8288613919565b52612368565b634e487b7160e01b600052600160045260246000fd5b3461032d57600036600319011261032d57602060405160038152f35b3461032d57604036600319011261032d576123f0613395565b61ffff806123fc6133a6565b16918215612437571660005260d0602052604060002090600052602052602062ffffff60406000205460501c165b62ffffff60405191168152f35b9091501660005260cc602052602062ffffff604060002054821c1661242a565b3461032d57600036600319011261032d5761247061586f565b60006001600160a01b036097546001600160a01b03198116609755167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461032d57600036600319011261032d5760207fffffffffffffffff00000000000000000000000000000000000000000000000060cb5460481b16604051908152f35b3461032d57600036600319011261032d576020604051620151808152f35b3461032d5760208060031936011261032d5760043567ffffffffffffffff811161032d576125459036906004016133c6565b9061254e61586f565b60005b828110612589576040517fb7bd806d66ef5249b63740995dc2366b90a3e2b78344eb5c0d573daa91971c68908061081d868683613f74565b61ffff61259a610278838686613eb2565b1660005260cc845260ff6040600020541660288110156108b957156125d557806102ae6125cb6125d0938686613eb2565b614358565b612551565b60046040517fdbab6626000000000000000000000000000000000000000000000000000000008152fd5b3461032d57602036600319011261032d5761ffff61261b613395565b6126236139b4565b501660005260d26020526102a0604060002060cc60205260ff61264b60406000205492613a38565b91612738604051809461ffff8082511683528060208301511660208401528060408301511660408401528060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c08401528060e08301511660e084015261010060ff818401511690840152610120818184015116908401526101408181840151169084015261016060ff818401511690840152610180818184015116908401526101a0818184015116908401526101c060ff8184015116908401526101e0818184015116908401526102009081830151169083015260ff6102208092015116910152565b6127486102408401838316613581565b62ffffff8160581c1661026084015260981c16610280820152f35b3461032d57600036600319011261032d576001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001630036127ce5760206040517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b60046040517f7251afea000000000000000000000000000000000000000000000000000000008152fd5b604036600319011261032d5761280c6133f7565b60243567ffffffffffffffff811161032d573660238201121561032d5780600401359061283882613565565b6128456040519182613543565b82815260209283820192366024838301011161032d578160009260248793018637830101526001600160a01b03807f00000000000000000000000000000000000000000000000000000000000000001690813014612ae0577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc918183541603612ab6576128d061586f565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561290857505050505061073b906158f5565b8516906040516352d1902d60e01b81528581600481865afa60009181612a87575b5061293f57600460405163081007d160e41b8152fd5b03612a5d5761294d856158f5565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a2815115801590612a55575b61298757005b843b15612a2d575061073b93600092839251915af43d15612a25573d906129ad82613565565b916129bb6040519384613543565b82523d60008484013e5b7f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c604051936129f3856134ef565b602785528401527f206661696c6564000000000000000000000000000000000000000000000000006040840152615962565b6060906129c5565b807f1fdb1d6d0000000000000000000000000000000000000000000000000000000060049252fd5b506001612981565b60046040517f8ae7e94c000000000000000000000000000000000000000000000000000000008152fd5b9091508681813d8311612aaf575b612a9f8183613543565b8101031261032d57519088612929565b503d612a95565b60046040517f36a15c6e000000000000000000000000000000000000000000000000000000008152fd5b60046040517f0ce7e818000000000000000000000000000000000000000000000000000000008152fd5b3461032d57612b183661340d565b909391612b2361586f565b801561191f578181036119495760005b818110612b6e5750907fbb9be5d1d0efdcb294acb14cca55a27436b316199041eb8cef7cac3d121a14c89461081d9260405195869586614a69565b612b8061027861ffff83168488614cfb565b612b8f61ffff83168589614d0b565b9061ffff861660005260d060205261ffff6040600020911660005260205260ff6040600020541660288110156108b95715612f2d577343da95dc00babae5d00ebea2c8088f3f7cd778323b1561032d576000612bff9160405180938192632ae2d1eb60e01b835260048301614d2e565b03817343da95dc00babae5d00ebea2c8088f3f7cd778325af48015610a7357612f1e575b50612c366115ae61ffff83168589614d0b565b9061ffff851660005260d0602052604060002061ffff612c5c610278828516878b614cfb565b1660005260205260406000209180519260288410156108b957612c8766ffff000000000094826142dd565b6020820151815464ffffffff00191660089190911b64ffffffff001617815563ffffffff916040810151825469ffffff00000000000000606084015160381b169169ffffffffff00000000001997889160281b1691161717825562ffffff6080612d0f828285015116859062ffffff60501b82549160501b169062ffffff60501b1916179055565b60a0830151845460c08086015160e087015171ffffffffff0000000000000000000000000019909316606894851b6effff00000000000000000000000000161760789190911b60ff60781b161760809290921b61ffff60801b169190911786559094600191610100860151825460ff60901b191660909190911b60ff60901b16178255856101208101519183549060ff60a81b61014084015160a81b169060ff60c01b61ffff60b01b61016086015160b01b1691610180860151901b1660ff60c81b6101a086015160c81b169161ffff60d01b6101c087015160d01b169361ffff60e01b6101e088015160e01b169572ffffffffffffffffffffffffffffffffffffff61ffff60981b6001600160f81b031961022060ff60f01b6102008d015160081c169b0151169a60981b169116171717171717171717815501946102408401519060288210156108b9576117e5612e6892886142dd565b6102808301519060288210156108b957612ef672ffffffffffff0000000000000000000000000019936fffffff000000000000000000000000009360019a89549065ff000000000069ffffffff0000000000006102a08b015160301b169360281b169116171788556102c086015116879062ffffff60501b82549160501b169062ffffff60501b1916179055565b62ffffff60801b6102e0850151916103008854960151901b16941b1691161717905501612b33565b612f2790613484565b86612c23565b60046040517f510fec52000000000000000000000000000000000000000000000000000000008152fd5b3461032d5760208060031936011261032d5760e09061ffff612f77613395565b600060c0604051612f8781613468565b82815282868201528260408201528260608201528260808201528260a082015201521660005260d18152604060002060405190612fc382613468565b5460019181830b93848252808201908360101c850b82526040830184821c860b815260608401918560301c870b835260808501938660401c880b855260c060a08701968860501c8a0b8852019660601c880b875260405198895251870b9088015251850b604087015251840b606086015251830b608085015251820b60a084015251900b60c0820152f35b3461032d57602036600319011261032d5761ffff61306a613395565b1660005260cc6020526040806000205463ffffffff82519160ff8160901c16835260381c166020820152f35b3461032d5760208060031936011261032d576130b06133f7565b906001600160a01b03807f000000000000000000000000000000000000000000000000000000000000000016803014612ae0577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc908282541603612ab65761311661586f565b604051908382019282841067ffffffffffffffff851117610d9457836040526000835260ff7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143541660001461317357505050505061073b906158f5565b8516906040516352d1902d60e01b81528581600481865afa600091816131f9575b506131aa57600460405163081007d160e41b8152fd5b03612a5d576131b8856158f5565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a28151158015906131f15761298757005b506000612981565b9091508681813d8311613221575b6132118183613543565b8101031261032d57519088613194565b503d613207565b3461032d57602036600319011261032d576004356001600160a01b03811680910361032d5761325561586f565b6001600160a01b031960d354161760d355600080f35b3461032d57604036600319011261032d57613284613395565b60243567ffffffffffffffff811161032d576132a49036906004016133c6565b90916132ae61586f565b811561191f5761ffff9081169060005b83811061330557505061081d7f32fe84254806f7c0fd6cbd970048ace22c87c23fb04b33e52b3115d7ff485a5a9360405193849384526040602085015260408401916149f3565b60019083600052602060d08152604060002090846133296102788286168a8c614cfb565b1660005252600082604082208281550155016132be565b3461032d57611e706133513661337f565b9061374f565b3461032d57602036600319011261032d576020613375600435613863565b1515604051908152f35b604090600319011261032d576004359060243590565b6004359061ffff8216820361032d57565b6024359061ffff8216820361032d57565b359061ffff8216820361032d57565b9181601f8401121561032d5782359167ffffffffffffffff831161032d576020808501948460051b01011161032d57565b600435906001600160a01b038216820361032d57565b90606060031983011261032d5760043561ffff8116810361032d579167ffffffffffffffff9160243583811161032d578261344a916004016133c6565b9390939260443591821161032d57613464916004016133c6565b9091565b60e0810190811067ffffffffffffffff821117610d9457604052565b67ffffffffffffffff8111610d9457604052565b610180810190811067ffffffffffffffff821117610d9457604052565b610240810190811067ffffffffffffffff821117610d9457604052565b610320810190811067ffffffffffffffff821117610d9457604052565b6060810190811067ffffffffffffffff821117610d9457604052565b6040810190811067ffffffffffffffff821117610d9457604052565b60a0810190811067ffffffffffffffff821117610d9457604052565b90601f8019910116810190811067ffffffffffffffff821117610d9457604052565b67ffffffffffffffff8111610d9457601f01601f191660200190565b9060288210156108b95752565b608090600319011261032d5760043590602435906044359060643590565b919082519283825260005b8481106135d8575050826000602080949584010152601f8019910116010190565b6020818301810151848301820152016135b7565b60c9548110156136235760c96000527f66be4f155c5ef2ebd3772b228f2f00681e4ed5826cdb3b1943cc11ad15ad1d280190600090565b634e487b7160e01b600052603260045260246000fd5b80548210156136235760005260206000200190600090565b604060031982011261032d576004359160243567ffffffffffffffff9283821161032d578060238301121561032d57816004013593841161032d5760248460061b8301011161032d576024019190565b91908203918211610ab657565b906205460064ffffffffff80931601918211610ab657565b9062093a8064ffffffffff80931601918211610ab657565b9062093a8064ffffffffff80931602918216918203610ab657565b91908201809211610ab657565b60c95468010000000000000000811015610d945780600161372a920160c9556135ec565b819291549060031b91821b91600019901b1916179055565b8051156136235760200190565b61379e6137b19267ffffffffffffffff60cb5460781c168360005260d5602052604060002054916040519060208201928352604082015260408152613793816134ef565b51902060381c613bd7565b9060005260d56020526040600020613639565b50549062ffffff61ffff83169260101c1690565b9193929360009483865260d460205260408620549260405190602082019283526040820152604081526137f7816134ef565b519020908060031b908082046008149015171561382f576040926137b1959692613821921c613bd7565b92815260d460205220613639565b602486634e487b7160e01b81526011600452fd5b6000198114610ab65760010190565b9060088110156136235760051b0190565b61386c906138ae565b6000811280156138a2575b61389c57613884906135ec565b90549060031b1c60005260ca60205260406000205490565b50600090565b508060c9541115613877565b64ffffffffff60cb5460281c16908181106138d55762015180916138d1916136a1565b0490565b505060001990565b6138e690613863565b9081156138ef57565b60046040517fb4190460000000000000000000000000000000000000000000000000000000008152fd5b9060048110156136235760051b0190565b6040516080810181811067ffffffffffffffff821117610d945760405260803682378091600090815b6004808210156139ac576201518090818302918383041483151715613999575090613988613983600193856136a1565b6138dd565b6139928287613919565b5201613953565b846011602492634e487b7160e01b835252fd5b505050505090565b604051906139c1826134b5565b816102206000918281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e0820152826102008201520152565b90604051613a45816134b5565b61022081935461ffff8082168452808260101c166020850152808260201c166040850152808260301c166060850152808260401c166080850152808260501c1660a0850152808260601c1660c0850152808260701c1660e085015260ff8260801c16610100850152808260881c16610120850152808260981c1661014085015260ff8260a81c16610160850152808260b01c16610180850152808260c01c166101a085015260ff8260d01c166101c0850152808260d81c166101e08501528160e81c1661020084015260f81c910152565b60288210156108b95752565b60405190613b2f826134d2565b816103006000918281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e08201528261020082015282610220820152826102408201528261026082015282610280820152826102a0820152826102c0820152826102e08201520152565b8115613be1570690565b634e487b7160e01b600052601260045260246000fd5b929091604051926020840194855260408401526060830152608082015260808152613c2181613527565b51902090565b9060009082825260ca60205260409081832054613e89576001815103613e6057613c5090613742565b51928315613e37575b80835260ca60205283828420556001600160a01b038060d3541680613de7575b5060d6541680613d86575b50907f5c69e7026b653d8606b5613bb00fd8c4b0504b1cbe8db600c406faac180924d5918151908152846020820152a160cb54906201518090814204828102928184041490151715613d725764ffffffffff91828460501c161115613cea575b50505050565b620545ff19420190428211613d7257506effffffffff00000000000000000000613d5961112c6111277fffffffffffffffffff00000000000000000000000000ffffffffffffffffffff9562093a8076ffffffffffffffff0000000000000000000000000000009604166136de565b60501b169360781b169116171760cb5538808080613ce4565b80634e487b7160e01b602492526011600452fd5b803b15613de35783809160248551809481936327fe556d60e21b83528a60048401525af18015613dd657908491613dbe575b50613c84565b613dc790613484565b613dd2578238613db8565b8280fd5b50505051903d90823e3d90fd5b8380fd5b803b15613e335784809160248651809481936327fe556d60e21b83528b60048401525af18015613e295715613c7957613e2290949194613484565b9238613c79565b84513d87823e3d90fd5b8480fd5b92506000194301438111613e4c574092613c59565b602483634e487b7160e01b81526011600452fd5b600482517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b600482517f533d99dd000000000000000000000000000000000000000000000000000000008152fd5b91908110156136235760051b810135906102be198136030182121561032d570190565b3590811515820361032d57565b359062ffffff8216820361032d57565b359063ffffffff8216820361032d57565b359060ff8216820361032d57565b602090613f2f8261ffff9283613f26826133b7565b168652016133b7565b16910152565b60ff613f2f6040809361ffff80613f4b836133b7565b168752613f5a602083016133b7565b16602087015201613f03565b35908160010b820361032d57565b91602090808285018386525260409182850194838360051b82010195856000925b858410613fa757505050505050505090565b9091929394959697603f1982820301845288356102be198436030181121561032d576102c09190840161ffff83830181613fe0846133b7565b16845289830135602881101561032d57613ffd908b860190613581565b6140088c8401613ed5565b15158c85015260609161401c838501613ed5565b151583860152608061402f818601613ed5565b15159086015262ffffff60a081614047828801613ee2565b169087015260c063ffffffff61405e828801613ef2565b169087015260e090614071828701613ee2565b1690860152610100816140858287016133b7565b1690860152610120906140998286016133b7565b169085015260ff610140816140af828701613f03565b1690860152610160906140c3828601613f03565b16908501526101806140d6818501613ed5565b15159085015236839003601e19016101a0848101358281121561032d578501908c823592019367ffffffffffffffff9889841161032d578360061b3603861361032d578392890152528d6102e0870193916000915b81831061424e57505050506101c090818501359081121561032d578401918b8335930196831161032d578383023603871361032d5780869594928d97889303908701528381520195916000915b81831061422757505050509282916001946101e0614197818301613f66565b870b90830152856102006141ac838201613f66565b820b908401526102206141c0818401613f66565b820b908401526102406141d4818401613f66565b820b908401526102606141e8818401613f66565b820b908401526102806141fc818401613f66565b820b908401526142106102a0809301613f66565b900b9101529a019401940192969594939190613f95565b808093959697508861423d869a60019597613f35565b019701930190918b95949392614178565b808661425f86986001959697613f11565b0195019201908f61412b565b35801515810361032d5790565b3561ffff8116810361032d5790565b3562ffffff8116810361032d5790565b903590601e198136030182121561032d570180359067ffffffffffffffff821161032d57602001918160061b3603831361032d57565b91908110156136235760061b0190565b9060288110156108b95760ff80198354169116179055565b3563ffffffff8116810361032d5790565b3560ff8116810361032d5790565b903590601e198136030182121561032d570180359067ffffffffffffffff821161032d5760200191606082023603831361032d57565b358060010b810361032d5790565b61436181614278565b61ffff916000918316156149c95761010081019161437e83614278565b610120830190858061438f84614278565b1691161161499f5760e083019162ffffff806143aa85614287565b161561493d576143b984614287565b168015614929576236ee80066148ff575b856143d485614278565b16815260209460cc865260409283832087870135916028831015613e33576143fc83836142dd565b61440788870161426b565b15158254946060988a8c8b820161441d9061426b565b1515608083019961442d8b61426b565b151560181b63ff000000169260a0850161444690614287565b901b66ffffff00000000169360c00161445e906142f5565b60381b6affffffff00000000000000169461447890614287565b60581b6dffffff0000000000000000000000169561449590614278565b60701b6fffff0000000000000000000000000000169660081b61ff0016907fffffffffffffffffffffffffffffffff000000000000000000000000000000ff16179060101b62ff00001617171717171782556144f090614278565b81547fffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff1660809190911b61ffff60801b161781556145316101408801614306565b815460ff60901b191660909190911b60ff60901b161781556145566101608801614306565b81546145656101808a0161426b565b151560a01b74ff0000000000000000000000000000000000000000169160981b73ff0000000000000000000000000000000000000016907fffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff1617179055876145cc87614278565b16835260d28752838320886145e088614278565b16845283858120557343da95dc00babae5d00ebea2c8088f3f7cd77832916101a088019161460e838a614297565b90853b156148fb579087895180937f1a2bbf3d00000000000000000000000000000000000000000000000000000000825283604483018d600485015252606482019093835b8d8282106148d857505050819293508560248301520381885af480156148ce576148bb575b506101c0890193614689858b614314565b92823b156148b75791899189938c8685519788967f91f221eb000000000000000000000000000000000000000000000000000000008852604488019060048901525260648601939187905b82821061488d575050505083918291602483015203915af480156148835790869161486f575b50506001036147f45750505081908661471286614278565b16815260d1865220946147286101e0850161434a565b94865461020086016147399061434a565b60101b9161474a610220880161434a565b901b9261475a610240880161434a565b60301b9461476b610260890161434a565b901b9561477b610280890161434a565b60501b976102a00161478c9061434a565b901b6dffff000000000000000000000000169716906dffffffffffffffffffffffffffff1916179063ffff000016179065ffff0000000016179067ffff00000000000016179069ffff00000000000000001617906bffff000000000000000000001617179055565b91959650929650614815935061480b915085614297565b9050151593614314565b905082614865575b5081614855575b5061482c5750565b600490517fb28b6f38000000000000000000000000000000000000000000000000000000008152fd5b61485f915061426b565b38614824565b151591503861481d565b61487890613484565b613e335784386146fa565b87513d88823e3d90fd5b91948291949698508397506148a481600195613f35565b0195019101908694928c9694928f6146d4565b8880fd5b6148c790969196613484565b9438614678565b88513d89823e3d90fd5b919450925080826148eb60019488613f11565b0194019101928a92859294614653565b8780fd5b60046040517ffbf84394000000000000000000000000000000000000000000000000000000008152fd5b602482634e487b7160e01b81526012600452fd5b506101a0840161494d8186614297565b905061495a575b506143ca565b6149649085614297565b1561498b576149766020889201614278565b16801561492957618ca0066148ff5738614954565b602482634e487b7160e01b81526032600452fd5b60046040517f3ab272e6000000000000000000000000000000000000000000000000000000008152fd5b60046040517fc78a7d8b000000000000000000000000000000000000000000000000000000008152fd5b91908082526020809201929160005b828110614a10575050505090565b90919293828060019261ffff614a25896133b7565b16815201950193929101614a02565b9035601e198236030181121561032d57016020813591019167ffffffffffffffff821161032d578160051b3603831361032d57565b949192909461ffff8096168152614a8d6060946020938685850152868401916149f3565b906040908181840391015283825282820194838560051b84010197876000945b878610614ac1575050505050505050505090565b90919293949596979899601f19828203018a528a356101be198436030181121561032d57830190602882358181101561032d5791614b00818c94613581565b614b0b838501613f66565b91600192830b8483015262ffffff80614b258c8801613ee2565b168b84015280614b368b8801613ee2565b168a840152614b5e6080614b4c81890189614a34565b90916101c080918801528601916149f3565b60a09186614b6e848a018a614a34565b939094878203908801528381520192916000915b818310614cd4575050505060c089614b9b8289016133b7565b169084015260ff60e081614bb0828a01613f03565b169085015261010090614bc4828901613f03565b169084015261012089614bd88289016133b7565b169084015261014089614bec8289016133b7565b1690840152610160614bff818801613ed5565b1515908401526101809185614c1684890189614a34565b939094868203908701528381520192916000915b818310614ca357505050508390614c476101a09687810190614a34565b9390968183039101528281520193916000915b808310614c7d5750505050806001929c019a019601949392919097969597614aad565b919380849663ffffffff614c918597613ef2565b168152019501930190918b9392614c5a565b919390928095975035908282101561032d578f81614cc382938a95613581565b019501930190918e96949392614c2a565b9193978084979984614ce78b9597613ee2565b168152019601930190918f97959392614b82565b91908110156136235760051b0190565b91908110156136235760051b810135906101be198136030182121561032d570190565b60208082526101e0820190602884358181101561032d57614d559083869594960190613581565b614d60848601613f66565b92600193840b604082015262ffffff9586614d7d60408301613ee2565b16606083015286614d9060608301613ee2565b166080830152614da36080820182614a34565b806101c0999299968760a0870152526102008401989060005b818110614f5357505050614dd360a0830183614a34565b601f19858b03810160c0870152818b52998901926000905b828210614f2b5750505050614e7d614e6b61ffff80614e0c60c087016133b7565b1660e0870152614e5b81614e4b60ff614e3b81614e2b60e08c01613f03565b1661010090818d01528a01613f03565b1661012090818b015288016133b7565b16610140908189015286016133b7565b1661016090818701528401613ed5565b15156101809081860152830183614a34565b8483038a016101a086810191909152818452928901956000905b828210614efa575050505081614eb291889594930190614a34565b9490978284030191015282815201939260005b828110614ed457505050505090565b9091928280869763ffffffff614eea8599613ef2565b1681520196019493929101614ec5565b90919296879a98999a35908282101561032d578981614f1b82938f95613581565b9a9c9b9a01980193920190614e97565b90919293988a80829c9a9b84614f4089613ee2565b1681529a9c9b9a01950193920190614deb565b909199978980829b999a61ffff614f698f6133b7565b168152019b989a999801929101614dbc565b903590601e198136030182121561032d570180359067ffffffffffffffff821161032d57602001918160051b3603831361032d57565b614fb9613b22565b50614fc7610160820161426b565b6000901561579757506001600160f81b031960805b60f81b1680610200526001614ff5610180840184614f7b565b90501161576b575b5061500b60a0820182614f7b565b9050151580615742575b80156156fa575b8060a052156156ab575b60a05161567c575b60288135101561032d576150466101a0820182614f7b565b6000608052159050615677576150606101a0820182614f7b565b156136235761506e906142f5565b6080525b61507e6020820161434a565b60c05261508d60408201614287565b60e05261509c60608201614287565b906150aa6080820182614f7b565b600091501561567157506150c16080820182614f7b565b15613623576150cf90614278565b915b6150de60a0830183614f7b565b9050151580615667575b6000901561566157506150fe60a0830183614f7b565b156136235761510e60ff91614287565b16905b61511e6080840184614f7b565b600091506001101561565b57506151386080840184614f7b565b6001101561362357602061514c9101614278565b925b600161515d60a0830183614f7b565b90501180615651575b6000901561564b575061517c60a0820182614f7b565b6001101561362357615192602060ff9201614287565b16925b6151a26080830183614f7b565b600091506002101561564557506151bc6080830183614f7b565b600210156136235760406151d09101614278565b945b60026151e160a0850185614f7b565b9050118061563b575b60009015615635575061520060a0840184614f7b565b6002101561362357615216604060ff9201614287565b16935b61522560c08501614278565b9061523260e08601614306565b916152406101008701614306565b9461524e6101208801614278565b9761525c6101408901614278565b9a600161526d6101808b018b614f7b565b9050600061010052116000146156305761528b6101808a018a614f7b565b600110156136235760200135602881101561032d57610100525b60016152b56101a08b018b614f7b565b90506000610120521160001461562b576152d36101a08a018a614f7b565b600110156136235760206152e791016142f5565b610120525b60026152fc6101808b018b614f7b565b9050600061016052116000146156265761531a6101808a018a614f7b565b600210156136235760400135602881101561032d57610160525b60026153446101a08b018b614f7b565b905060006101405211600014615621576153626101a08a018a614f7b565b6002101561362357604061537691016142f5565b610140525b61538860a08a018a614f7b565b9050151580615618575b60006101805215615613576153aa60a08a018a614f7b565b15613623576153b890614287565b610180525b60016153cc60a08b018b614f7b565b9050118061560a575b60006101a05215615605576153ed60a08a018a614f7b565b600110156136235760206154019101614287565b6101a0525b600261541560a08b018b614f7b565b905011806155fc575b60006101c052156155d75761543660a08a018a614f7b565b600292919210156136235760ff61ffff9e9c8f829c9a819f849c9883869a9262ffffff829e61548c8a9661546d6040879f01614287565b6101c0525b615482604051806101e0526134d2565b356101e051613b16565b63ffffffff6080511660206101e051015260c05160010b60406101e05101528160e0511660606101e05101521660806101e05101521660a06101e05101521660c06101e05101521660e06101e0510152166101006101e0510152166101206101e0510152166101406101e0510152166101606101e0510152166101806101e0510152166101a06101e0510152166101c06101e0510152166101e0805101526001600160f81b031961020051166102006101e051015260006102206101e0510152615560610100516102406101e05101613b16565b63ffffffff61012051166102606101e0510152615587610160516102806101e05101613b16565b63ffffffff61014051166102a06101e051015262ffffff61018051166102c06101e051015262ffffff6101a051166102e06101e051015262ffffff6101c051166103006101e05101526101e05190565b61ffff9c9060ff8e9c8d829c9a83809c9883809c9862ffffff829a61548c869e615472565b5060a05161541e565b615406565b5060a0516153d5565b6153bd565b5060a051615392565b61537b565b615334565b6152ec565b6152a5565b93615219565b5060a051156151ea565b946151d2565b92615195565b5060a05115615166565b9261514e565b90615111565b5060a051156150e8565b916150d1565b615072565b7f200000000000000000000000000000000000000000000000000000000000000061020051176102005261502e565b60026156ba60a0830183614f7b565b905011806156cb575b60a052615026565b506156d960a0820182614f7b565b600210156136235762ffffff6156f3604060ff9301614287565b16116156c3565b50600161570a60a0830183614f7b565b905011801561501c575061572160a0820182614f7b565b600110156136235762ffffff61573b602060ff9301614287565b161161501c565b5061575060a0820182614f7b565b156136235762ffffff61576460ff92614287565b1611615015565b7f4000000000000000000000000000000000000000000000000000000000000000176102005238614ffd565b6001600160f81b031990614fdc565b90821015613623576134649160051b810190614f7b565b805490600090818155826157d057505050565b815260208120918201915b8281106157e757505050565b8181556001016157db565b805468010000000000000000811015610d945761581491600182018155613639565b9190916158595761ffff61582782614278565b1664ffffff000061584660208554948461ffff19871617875501614287565b60101b169164ffffffffff191617179055565b634e487b7160e01b600052600060045260246000fd5b6001600160a01b0360975416330361588357565b60046040517f6db2465f000000000000000000000000000000000000000000000000000000008152fd5b609754906001600160a01b0380911691826001600160a01b0319821617609755167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b803b15615938576001600160a01b037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91166001600160a01b0319825416179055565b60046040517f71ab98ae000000000000000000000000000000000000000000000000000000008152fd5b9091901561596e575090565b81511561597e5750805190602001fd5b6159bc906040519182917f08c379a00000000000000000000000000000000000000000000000000000000083526020600484015260248301906135ac565b0390fdfea26469706673582212203a8c6106c01cc9fed6bfcfd415a98ad454ebc5441c507e78519a1853359a96d564736f6c63430008140033
Deployed Bytecode
0x610220604052600436101561001357600080fd5b60003560e01c80631929f7b31461335757806322793d2814613340578063264c73521461326b5780632dc918c2146132285780633659cfe61461309657806336f15ed71461304e5780634a2f04a114612f575780634ad8c52914612b0a5780634f1ef286146127f857806352d1902d14612763578063582e5452146125ff5780635f9e245e146125135780636528f09a146124f557806371315901146124b2578063715018a61461245757806374db3052146123d7578063770d0441146123bb5780637fe4cf6b1461227a57806381ab74511461223d57806383240f83146121775780638693ef18146120565780638796ba8c1461201f57806388b33c5b14611f855780638a54942f14611ee65780638da5cb5b14611ebf5780638eafc36414611e8d57806395016e4b14611e56578063b8987a6e14611973578063bbea74f41461147b578063bd880fae14611445578063be52e34f14611378578063beff730f1461134c578063c4d66de814610fa2578063cc3172a114610dd0578063cc76b91114610daa578063d42da17214610c72578063d623d54c14610c16578063dd56f38b14610b4d578063debde28414610b28578063e0c8628914610940578063e5df71fc146108f9578063e63e9b91146107aa578063e87df97214610767578063f2fde38b14610702578063f5a62e191461069f578063f691689c146103325763fb2bbc7f1461022257600080fd5b3461032d5761023036613651565b919061023a61586f565b60ff8311610303578160005260d590602082815261025b60406000206157bd565b60005b85811061026757005b61ffff61027d6102788389876142cd565b614278565b161580156102e2575b6102b8576102b390856000528483526102ae60406000206102a8838a886142cd565b906157f2565b613843565b61025e565b60046040517f28829e82000000000000000000000000000000000000000000000000000000008152fd5b5062ffffff6102fc836102f6848a886142cd565b01614287565b1615610286565b60046040517f2862b710000000000000000000000000000000000000000000000000000000008152fd5b600080fd5b3461032d57604036600319011261032d5761032061034e613395565b6103566133a6565b61ffff610361613b22565b921660005260d060205261ffff604060002091166000526020526040600020805461038f60ff821684613b16565b63ffffffff8160081c1660208401528060281c60010b604084015262ffffff8160381c16606084015262ffffff8160501c16608084015261ffff8160681c1660a084015260ff8160781c1660c084015261ffff8160801c1660e084015260ff8160901c1661010084015261ffff8160981c1661012084015260ff8160a81c1661014084015261ffff8160b01c1661016084015260ff8160c01c1661018084015260ff8160c81c166101a084015261ffff8160d01c166101c084015261ffff8160e01c166101e08401526001600160f81b03198160081b166102008401526001808260f61c161490811561068e575b50610618575b5060405190610493828251613581565b63ffffffff6020820151166020830152604081015160010b604083015262ffffff606082015116606083015262ffffff608082015116608083015261ffff60a08201511660a083015260ff60c08201511660c083015261ffff60e08201511660e083015260ff6101008201511661010083015261ffff6101208201511661012083015260ff6101408201511661014083015261ffff6101608201511661016083015260ff6101808201511661018083015260ff6101a0820151166101a083015261ffff6101c0820151166101c083015261ffff6101e0820151166101e08301526001600160f81b0319610200820151166102008301526102206001600160f81b03198183015116908301526105b16102408083015190840190613581565b61026063ffffffff8183015116908301526105d56102808083015190840190613581565b6102a063ffffffff8183015116908301526102c062ffffff8183015116908301526102e062ffffff81830151169083015262ffffff610300809201511690820152f35b600162ffffff91015461063260ff82166102408501613b16565b63ffffffff8160081c1661026084015261065660ff8260281c166102808501613b16565b63ffffffff8160301c166102a0840152818160501c166102c0840152818160681c166102e084015260801c1661030082015282610483565b60019150819060f51c16148461047d565b3461032d57602036600319011261032d576106b86133f7565b6106c061586f565b75ffffffffffffffffffffffffffffffffffffffff00001975ffffffffffffffffffffffffffffffffffffffff00006000549260101b16911617600055600080f35b3461032d57602036600319011261032d5761071b6133f7565b61072361586f565b6001600160a01b0381161561073d5761073b906158ad565b005b60046040517f7448fbae000000000000000000000000000000000000000000000000000000008152fd5b3461032d57602036600319011261032d576004356001600160a01b03811680910361032d5761079461586f565b6001600160a01b031960d654161760d655600080f35b3461032d5760208060031936011261032d5760043567ffffffffffffffff811161032d576107dc9036906004016133c6565b906107e561586f565b81805b610822576040517fe0c485464feab584463337a60a5f3b30eeae5d466aa5ce2d973b306518e576a6908061081d868683613f74565b0390a1005b6000190161ffff6108368183168585613eb2565b906108436060830161426b565b6108cf578061085183614278565b1660005260cc865260ff6040600020541660288110156108b95761087f575061087a8291614358565b6107e8565b61088a602492614278565b6040517fd44e9bef00000000000000000000000000000000000000000000000000000000815291166004820152fd5b634e487b7160e01b600052602160045260246000fd5b60046040517fccdd1ab5000000000000000000000000000000000000000000000000000000008152fd5b3461032d5760208060031936011261032d5761091660043561392a565b604051916000835b6004821061092b57608085f35b8280600192865181520194019101909261091e565b3461032d57600036600319011261032d5760c9548015159081610af6575b50610acc5760cb5464ffffffffff6201518081831601818111610ab6571690428211610a7f576000916001600160a01b03835460101c1662ffffff604051937f1b739ef10000000000000000000000000000000000000000000000000000000085526001600486015260b81c1660248401528260448160209687945af1918215610a7357600092610a43575b5060607f643b454d39972ed209afefa4a771c7a9057229bc7e6b66566f5be8441bf9b1e291610a1884613706565b8064ffffffffff1960cb54161760cb55604051908482526001868301526040820152a1604051908152f35b9091508281813d8311610a6c575b610a5b8183613543565b8101031261032d57519060606109ea565b503d610a51565b6040513d6000823e3d90fd5b604482604051907f1351c9400000000000000000000000000000000000000000000000000000000082524260048301526024820152fd5b634e487b7160e01b600052601160045260246000fd5b60046040517f974b4f8a000000000000000000000000000000000000000000000000000000008152fd5b600019810191508111610ab657610b0c906135ec565b90549060031b1c60005260ca602052604060002054158161095e565b3461032d57600036600319011261032d57602064ffffffffff60cb5416604051908152f35b3461032d57610b5b36613651565b9190610b6561586f565b60ff8311610303578160005260d4906020828152610b8660406000206157bd565b60005b858110610b9257005b61ffff610ba36102788389876142cd565b16158015610bfb575b8015610bda575b6102b857610bd590856000528483526102ae60406000206102a8838a886142cd565b610b89565b5062ffffff600a81610bf1856102f6868c8a6142cd565b1606161515610bb3565b5062ffffff610c0f836102f6848a886142cd565b1615610bac565b3461032d57610c243661337f565b9060005260d56020526040600020805482101561032d57610c6e91610c4891613639565b50546040805161ffff8316815260109290921c62ffffff16602083015290918291820190565b0390f35b3461032d57610c803661337f565b6040519167ffffffffffffffff61010080850182811186821017610d945760405260005b818110610d6657505060cb5460781c1660005b60078110610d225784610cca858561374f565b60e08301519262ffffff9384602093168382015261ffff8094169052604051938491906000925b60088410610cff5761020087f35b846040600192848387518b81511684520151168382015201930193019291610cf1565b8061ffff610d3584610d619488886137c5565b9190610d41848a613852565b519262ffffff6020610d53878d613852565b510191169052169052613843565b610cb7565b60405190604082019180831085841117610d9457602092604052600081526000838201528188015201610ca4565b634e487b7160e01b600052604160045260246000fd5b3461032d57602036600319011261032d576020610dc86004356138dd565b604051908152f35b3461032d57602036600319011261032d576000610160604051610df281613498565b8281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e0820152826101008201528261012082015282610140820152015260043560005260cc602052610180604060002060ff60405191610e5883613498565b54610e6582821684613b16565b818160081c1615156020840152818160101c1615156040840152818160181c161515606084015262ffffff8160201c16608084015263ffffffff8160381c1660a084015262ffffff8160581c1660c084015261ffff8160701c1660e084015261ffff8160801c16610100840152818160901c16610120840152818160981c1661014084015260a01c16151561016082015261016060405191610f08838251613581565b60208101511515602084015260408101511515604084015260608101511515606084015262ffffff608082015116608084015263ffffffff60a08201511660a084015262ffffff60c08201511660c084015261ffff60e08201511660e084015261ffff6101008201511661010084015260ff6101208201511661012084015260ff6101408201511661014084015201511515610160820152f35b3461032d5760208060031936011261032d57610fbc6133f7565b906000549160ff8360081c16159081809261133f575b8015611328575b156112fe57600193828560ff198316176000556112ec575b5060005460ff8160081c16156112c25775ffffffffffffffffffffffffffffffffffffffff00001975ffffffffffffffffffffffffffffffffffffffff000060ff9360101b169116178060005560081c16156112c257611050336158ad565b620151808042049080820291808304821490151715610ab657620545ff19828101928311610ab65760cb92835469ffffffffff0000000000602892831b169064ffffffffff936203f480858469ffffffffff000000000019851617861c160190858211610ab6574201428111610ab657790927c00000000000000000000000000000000000000000000000937fffffffffffff000000ffffffffffffffff0000000000000000000000000000006effffffffff0000000000000000000061113161112c6111278b62093a8081989e9c9e04166136de565b6136ae565b6136c6565b60501b1694161791161717178455600090600219430192438411925b600381106111ea575050505050506000805260ca83526040600020547fffffffffffffffffff0000000000000000ffffffffffffffffffffffffffffff76ffffffffffffffff00000000000000000000000000000083549260781b1691161790556111b457005b7f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989161ff001960005416600055604051908152a1005b60c890808201809211610ab65761120082613706565b828854881c16848202828104861483151715610ab65761121f916136f9565b848101809111610ab65760608b7f643b454d39972ed209afefa4a771c7a9057229bc7e6b66566f5be8441bf9b1e2928e604051928784528301526040820152a16040519161126c8361350b565b8b8352858b3681860137610ab6578b926112bc917f3632d8eba811d69784e6904a58de6e0ab55f32638189623b309895beaa6920c46112ab858b6136f9565b40186112b683613742565b52613c27565b0161114d565b60046040517fd7e6bcf8000000000000000000000000000000000000000000000000000000008152fd5b61ffff19166101011760005584610ff1565b60046040517f0dc149f0000000000000000000000000000000000000000000000000000000008152fd5b50303b158015610fd95750600160ff851614610fd9565b50600160ff851610610fd2565b3461032d57602036600319011261032d5760043560005260ca6020526020604060002054604051908152f35b3461032d57604036600319011261032d5767ffffffffffffffff60243581811161032d573660238201121561032d578060040135918211610d94578160051b90604051916020936113cb85830185613543565b83526024848401918301019136831161032d57602401905b82821061143657836001600160a01b0360005460101c16330361140c5761073b90600435613c27565b60046040517f580ae425000000000000000000000000000000000000000000000000000000008152fd5b813581529084019084016113e3565b3461032d57602036600319011261032d5760043560005260cc602052602060ff604060002054166114796040518092613581565bf35b3461032d576114893661340d565b61149493919361586f565b7fa3ae391b4ec3b8276739f8c31c7074ec8a45be9b7f9663574f58fa257b49a060604051806114c7848888888c86614a69565b0390a182810361194957821561191f5760005b8181106114e357005b6114f561027861ffff83168686614cfb565b61ffff6115058184168589614d0b565b911680156118f55761ffff881660005260d060205260406000209060005260205260ff6040600020541660288110156108b9576118cb577343da95dc00babae5d00ebea2c8088f3f7cd778323b1561032d5760006115779160405180938192632ae2d1eb60e01b835260048301614d2e565b03817343da95dc00babae5d00ebea2c8088f3f7cd778325af48015610a73576118bc575b506115b36115ae61ffff83168488614d0b565b614fb1565b9061ffff871660005260d0602052604060002061ffff6115d96102788285168989614cfb565b1660005260205260406000209180519260288410156108b95761160466ffff000000000094826142dd565b6020820151815464ffffffff00191660089190911b64ffffffff001617815563ffffffff916040810151825469ffffff00000000000000606084015160381b169169ffffffffff00000000001997889160281b1691161717825562ffffff608061168c828285015116859062ffffff60501b82549160501b169062ffffff60501b1916179055565b60a0830151845460c08086015160e087015171ffffffffff0000000000000000000000000019909316606894851b6effff00000000000000000000000000161760789190911b60ff60781b161760809290921b61ffff60801b169190911786559094600191610100860151825460ff60901b191660909190911b60ff60901b16178255856101208101519183549060ff60a81b61014084015160a81b169060ff60c01b61ffff60b01b61016086015160b01b1691610180860151901b1660ff60c81b6101a086015160c81b169161ffff60d01b6101c087015160d01b169361ffff60e01b6101e088015160e01b169572ffffffffffffffffffffffffffffffffffffff61ffff60981b6001600160f81b031961022060ff60f01b6102008d015160081c169b0151169a60981b169116171717171717171717815501946102408401519060288210156108b9576117e561180692886142dd565b610260850151875464ffffffff001916911660081b64ffffffff0016178655565b6102808301519060288210156108b95761189472ffffffffffff0000000000000000000000000019936fffffff000000000000000000000000009360019a89549065ff000000000069ffffffff0000000000006102a08b015160301b169360281b169116171788556102c086015116879062ffffff60501b82549160501b169062ffffff60501b1916179055565b62ffffff60801b6102e0850151916103008854960151901b16941b16911617179055016114da565b6118c590613484565b8661159b565b60046040517fa7f589fe000000000000000000000000000000000000000000000000000000008152fd5b60046040517f665991b7000000000000000000000000000000000000000000000000000000008152fd5b60046040517f96ac6b94000000000000000000000000000000000000000000000000000000008152fd5b60046040517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b3461032d57606036600319011261032d5767ffffffffffffffff60043581811161032d576119a59036906004016133c6565b60243583811161032d576119bd9036906004016133c6565b92909360443590811161032d576119d89036906004016133c6565b9190926119e361586f565b82810361194957801561191f5760005b8181106119fc57005b61ffff8116611a0f610278828587614cfb565b90611a28611a1e828a8c6157a6565b919092888a6157a6565b611a3393919361586f565b7fa3ae391b4ec3b8276739f8c31c7074ec8a45be9b7f9663574f58fa257b49a06060405180611a66848888888c86614a69565b0390a182810361194957821561191f5760005b818110611a8e575050505050506001016119f3565b611aa061027861ffff83168686614cfb565b611aaf61ffff83168488614d0b565b9061ffff8116156118f55761ffff881660005260d060205261ffff6040600020911660005260205260ff6040600020541660288110156108b9576118cb577343da95dc00babae5d00ebea2c8088f3f7cd778323b1561032d576000611b289160405180938192632ae2d1eb60e01b835260048301614d2e565b03817343da95dc00babae5d00ebea2c8088f3f7cd778325af48015610a7357611e47575b50611b5f6115ae61ffff83168488614d0b565b9061ffff871660005260d0602052604060002061ffff611b856102788285168989614cfb565b1660005260205260406000209180519260288410156108b957611bb066ffff000000000094826142dd565b6020820151815464ffffffff00191660089190911b64ffffffff001617815563ffffffff916040810151825469ffffff00000000000000606084015160381b169169ffffffffff00000000001997889160281b1691161717825562ffffff6080611c38828285015116859062ffffff60501b82549160501b169062ffffff60501b1916179055565b60a0830151845460c08086015160e087015171ffffffffff0000000000000000000000000019909316606894851b6effff00000000000000000000000000161760789190911b60ff60781b161760809290921b61ffff60801b169190911786559094600191610100860151825460ff60901b191660909190911b60ff60901b16178255856101208101519183549060ff60a81b61014084015160a81b169060ff60c01b61ffff60b01b61016086015160b01b1691610180860151901b1660ff60c81b6101a086015160c81b169161ffff60d01b6101c087015160d01b169361ffff60e01b6101e088015160e01b169572ffffffffffffffffffffffffffffffffffffff61ffff60981b6001600160f81b031961022060ff60f01b6102008d015160081c169b0151169a60981b169116171717171717171717815501946102408401519060288210156108b9576117e5611d9192886142dd565b6102808301519060288210156108b957611e1f72ffffffffffff0000000000000000000000000019936fffffff000000000000000000000000009360019a89549065ff000000000069ffffffff0000000000006102a08b015160301b169360281b169116171788556102c086015116879062ffffff60501b82549160501b169062ffffff60501b1916179055565b62ffffff60801b6102e0850151916103008854960151901b16941b1691161717905501611a79565b611e5090613484565b8d611b4c565b3461032d57611e70611e673661358e565b929190916137c5565b6040805161ffff93909316835262ffffff91909116602083015290f35b3461032d57611e9b3661337f565b9060005260d46020526040600020805482101561032d57610c6e91610c4891613639565b3461032d57600036600319011261032d5760206001600160a01b0360975416604051908152f35b3461032d57602036600319011261032d57600435611f0261586f565b622dc6c08111611f5b577fffffffffffff000000ffffffffffffffffffffffffffffffffffffffffffffff79ffffff000000000000000000000000000000000000000000000060cb549260b81b1691161760cb55600080f35b60046040517fbfbc293b000000000000000000000000000000000000000000000000000000008152fd5b3461032d57611f933661337f565b620545ff194201428111610ab65762093a80809104818102918183041490151715610ab657620546008101809111610ab65762015180928342049284840293808504861490151715610ab657604094611ff361200b9462ffffff966136a1565b049067ffffffffffffffff60cb5460781c16926137c5565b61ffff849392935193168352166020820152f35b3461032d57602036600319011261032d5760043560c95481101561032d576120486020916135ec565b90546040519160031b1c8152f35b3461032d57602036600319011261032d5761206f6139b4565b5060043560005260d260205261024061208b6040600020613a38565b611479604051809261ffff8082511683528060208301511660208401528060408301511660408401528060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c08401528060e08301511660e084015261010060ff818401511690840152610120818184015116908401526101408181840151169084015261016060ff818401511690840152610180818184015116908401526101a0818184015116908401526101c060ff8184015116908401526101e0818184015116908401526102009081830151169083015260ff6102208092015116910152565b3461032d57602036600319011261032d5760043560005260cc6020526101806040600020546040519060ff906121af83838316613581565b818160081c1615156020840152818160101c1615156040840152818160181c161515606084015262ffffff808260201c16608085015263ffffffff8260381c1660a08501528160581c1660c084015261ffff808260701c1660e08501528160801c16610100840152818160901c16610120840152818160981c1661014084015260a01c161515610160820152f35b3461032d57602036600319011261032d5761ffff612259613395565b1660005260cc602052602062ffffff60406000205460581c16604051908152f35b3461032d576122883661358e565b9092909190601081116122d7575090826122ad926122a8610c6e956138dd565b613bf7565b604051906020820152602081526122c38161350b565b6040519182916020835260208301906135ac565b9091906040106123a5576122ea8361392a565b9260005b6004811061233e57505050506040519060208083016000905b600482106123295750505050806080610c6e925261232481613527565b6122c3565b82806001928651815201940191019092612307565b806123578484876123516001968b613919565b51613bf7565b6123618288613919565b528061236e575b016122ee565b6123788187613919565b51865118604051602080820192835281526123928161350b565b51902061239f8288613919565b52612368565b634e487b7160e01b600052600160045260246000fd5b3461032d57600036600319011261032d57602060405160038152f35b3461032d57604036600319011261032d576123f0613395565b61ffff806123fc6133a6565b16918215612437571660005260d0602052604060002090600052602052602062ffffff60406000205460501c165b62ffffff60405191168152f35b9091501660005260cc602052602062ffffff604060002054821c1661242a565b3461032d57600036600319011261032d5761247061586f565b60006001600160a01b036097546001600160a01b03198116609755167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08280a3005b3461032d57600036600319011261032d5760207fffffffffffffffff00000000000000000000000000000000000000000000000060cb5460481b16604051908152f35b3461032d57600036600319011261032d576020604051620151808152f35b3461032d5760208060031936011261032d5760043567ffffffffffffffff811161032d576125459036906004016133c6565b9061254e61586f565b60005b828110612589576040517fb7bd806d66ef5249b63740995dc2366b90a3e2b78344eb5c0d573daa91971c68908061081d868683613f74565b61ffff61259a610278838686613eb2565b1660005260cc845260ff6040600020541660288110156108b957156125d557806102ae6125cb6125d0938686613eb2565b614358565b612551565b60046040517fdbab6626000000000000000000000000000000000000000000000000000000008152fd5b3461032d57602036600319011261032d5761ffff61261b613395565b6126236139b4565b501660005260d26020526102a0604060002060cc60205260ff61264b60406000205492613a38565b91612738604051809461ffff8082511683528060208301511660208401528060408301511660408401528060608301511660608401528060808301511660808401528060a08301511660a08401528060c08301511660c08401528060e08301511660e084015261010060ff818401511690840152610120818184015116908401526101408181840151169084015261016060ff818401511690840152610180818184015116908401526101a0818184015116908401526101c060ff8184015116908401526101e0818184015116908401526102009081830151169083015260ff6102208092015116910152565b6127486102408401838316613581565b62ffffff8160581c1661026084015260981c16610280820152f35b3461032d57600036600319011261032d576001600160a01b037f000000000000000000000000c6f268ddf4f9122cf47988dbd46fa0b103b8770f1630036127ce5760206040517f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc8152f35b60046040517f7251afea000000000000000000000000000000000000000000000000000000008152fd5b604036600319011261032d5761280c6133f7565b60243567ffffffffffffffff811161032d573660238201121561032d5780600401359061283882613565565b6128456040519182613543565b82815260209283820192366024838301011161032d578160009260248793018637830101526001600160a01b03807f000000000000000000000000c6f268ddf4f9122cf47988dbd46fa0b103b8770f1690813014612ae0577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc918183541603612ab6576128d061586f565b7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd91435460ff161561290857505050505061073b906158f5565b8516906040516352d1902d60e01b81528581600481865afa60009181612a87575b5061293f57600460405163081007d160e41b8152fd5b03612a5d5761294d856158f5565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a2815115801590612a55575b61298757005b843b15612a2d575061073b93600092839251915af43d15612a25573d906129ad82613565565b916129bb6040519384613543565b82523d60008484013e5b7f416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c604051936129f3856134ef565b602785528401527f206661696c6564000000000000000000000000000000000000000000000000006040840152615962565b6060906129c5565b807f1fdb1d6d0000000000000000000000000000000000000000000000000000000060049252fd5b506001612981565b60046040517f8ae7e94c000000000000000000000000000000000000000000000000000000008152fd5b9091508681813d8311612aaf575b612a9f8183613543565b8101031261032d57519088612929565b503d612a95565b60046040517f36a15c6e000000000000000000000000000000000000000000000000000000008152fd5b60046040517f0ce7e818000000000000000000000000000000000000000000000000000000008152fd5b3461032d57612b183661340d565b909391612b2361586f565b801561191f578181036119495760005b818110612b6e5750907fbb9be5d1d0efdcb294acb14cca55a27436b316199041eb8cef7cac3d121a14c89461081d9260405195869586614a69565b612b8061027861ffff83168488614cfb565b612b8f61ffff83168589614d0b565b9061ffff861660005260d060205261ffff6040600020911660005260205260ff6040600020541660288110156108b95715612f2d577343da95dc00babae5d00ebea2c8088f3f7cd778323b1561032d576000612bff9160405180938192632ae2d1eb60e01b835260048301614d2e565b03817343da95dc00babae5d00ebea2c8088f3f7cd778325af48015610a7357612f1e575b50612c366115ae61ffff83168589614d0b565b9061ffff851660005260d0602052604060002061ffff612c5c610278828516878b614cfb565b1660005260205260406000209180519260288410156108b957612c8766ffff000000000094826142dd565b6020820151815464ffffffff00191660089190911b64ffffffff001617815563ffffffff916040810151825469ffffff00000000000000606084015160381b169169ffffffffff00000000001997889160281b1691161717825562ffffff6080612d0f828285015116859062ffffff60501b82549160501b169062ffffff60501b1916179055565b60a0830151845460c08086015160e087015171ffffffffff0000000000000000000000000019909316606894851b6effff00000000000000000000000000161760789190911b60ff60781b161760809290921b61ffff60801b169190911786559094600191610100860151825460ff60901b191660909190911b60ff60901b16178255856101208101519183549060ff60a81b61014084015160a81b169060ff60c01b61ffff60b01b61016086015160b01b1691610180860151901b1660ff60c81b6101a086015160c81b169161ffff60d01b6101c087015160d01b169361ffff60e01b6101e088015160e01b169572ffffffffffffffffffffffffffffffffffffff61ffff60981b6001600160f81b031961022060ff60f01b6102008d015160081c169b0151169a60981b169116171717171717171717815501946102408401519060288210156108b9576117e5612e6892886142dd565b6102808301519060288210156108b957612ef672ffffffffffff0000000000000000000000000019936fffffff000000000000000000000000009360019a89549065ff000000000069ffffffff0000000000006102a08b015160301b169360281b169116171788556102c086015116879062ffffff60501b82549160501b169062ffffff60501b1916179055565b62ffffff60801b6102e0850151916103008854960151901b16941b1691161717905501612b33565b612f2790613484565b86612c23565b60046040517f510fec52000000000000000000000000000000000000000000000000000000008152fd5b3461032d5760208060031936011261032d5760e09061ffff612f77613395565b600060c0604051612f8781613468565b82815282868201528260408201528260608201528260808201528260a082015201521660005260d18152604060002060405190612fc382613468565b5460019181830b93848252808201908360101c850b82526040830184821c860b815260608401918560301c870b835260808501938660401c880b855260c060a08701968860501c8a0b8852019660601c880b875260405198895251870b9088015251850b604087015251840b606086015251830b608085015251820b60a084015251900b60c0820152f35b3461032d57602036600319011261032d5761ffff61306a613395565b1660005260cc6020526040806000205463ffffffff82519160ff8160901c16835260381c166020820152f35b3461032d5760208060031936011261032d576130b06133f7565b906001600160a01b03807f000000000000000000000000c6f268ddf4f9122cf47988dbd46fa0b103b8770f16803014612ae0577f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc908282541603612ab65761311661586f565b604051908382019282841067ffffffffffffffff851117610d9457836040526000835260ff7f4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143541660001461317357505050505061073b906158f5565b8516906040516352d1902d60e01b81528581600481865afa600091816131f9575b506131aa57600460405163081007d160e41b8152fd5b03612a5d576131b8856158f5565b604051907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b600080a28151158015906131f15761298757005b506000612981565b9091508681813d8311613221575b6132118183613543565b8101031261032d57519088613194565b503d613207565b3461032d57602036600319011261032d576004356001600160a01b03811680910361032d5761325561586f565b6001600160a01b031960d354161760d355600080f35b3461032d57604036600319011261032d57613284613395565b60243567ffffffffffffffff811161032d576132a49036906004016133c6565b90916132ae61586f565b811561191f5761ffff9081169060005b83811061330557505061081d7f32fe84254806f7c0fd6cbd970048ace22c87c23fb04b33e52b3115d7ff485a5a9360405193849384526040602085015260408401916149f3565b60019083600052602060d08152604060002090846133296102788286168a8c614cfb565b1660005252600082604082208281550155016132be565b3461032d57611e706133513661337f565b9061374f565b3461032d57602036600319011261032d576020613375600435613863565b1515604051908152f35b604090600319011261032d576004359060243590565b6004359061ffff8216820361032d57565b6024359061ffff8216820361032d57565b359061ffff8216820361032d57565b9181601f8401121561032d5782359167ffffffffffffffff831161032d576020808501948460051b01011161032d57565b600435906001600160a01b038216820361032d57565b90606060031983011261032d5760043561ffff8116810361032d579167ffffffffffffffff9160243583811161032d578261344a916004016133c6565b9390939260443591821161032d57613464916004016133c6565b9091565b60e0810190811067ffffffffffffffff821117610d9457604052565b67ffffffffffffffff8111610d9457604052565b610180810190811067ffffffffffffffff821117610d9457604052565b610240810190811067ffffffffffffffff821117610d9457604052565b610320810190811067ffffffffffffffff821117610d9457604052565b6060810190811067ffffffffffffffff821117610d9457604052565b6040810190811067ffffffffffffffff821117610d9457604052565b60a0810190811067ffffffffffffffff821117610d9457604052565b90601f8019910116810190811067ffffffffffffffff821117610d9457604052565b67ffffffffffffffff8111610d9457601f01601f191660200190565b9060288210156108b95752565b608090600319011261032d5760043590602435906044359060643590565b919082519283825260005b8481106135d8575050826000602080949584010152601f8019910116010190565b6020818301810151848301820152016135b7565b60c9548110156136235760c96000527f66be4f155c5ef2ebd3772b228f2f00681e4ed5826cdb3b1943cc11ad15ad1d280190600090565b634e487b7160e01b600052603260045260246000fd5b80548210156136235760005260206000200190600090565b604060031982011261032d576004359160243567ffffffffffffffff9283821161032d578060238301121561032d57816004013593841161032d5760248460061b8301011161032d576024019190565b91908203918211610ab657565b906205460064ffffffffff80931601918211610ab657565b9062093a8064ffffffffff80931601918211610ab657565b9062093a8064ffffffffff80931602918216918203610ab657565b91908201809211610ab657565b60c95468010000000000000000811015610d945780600161372a920160c9556135ec565b819291549060031b91821b91600019901b1916179055565b8051156136235760200190565b61379e6137b19267ffffffffffffffff60cb5460781c168360005260d5602052604060002054916040519060208201928352604082015260408152613793816134ef565b51902060381c613bd7565b9060005260d56020526040600020613639565b50549062ffffff61ffff83169260101c1690565b9193929360009483865260d460205260408620549260405190602082019283526040820152604081526137f7816134ef565b519020908060031b908082046008149015171561382f576040926137b1959692613821921c613bd7565b92815260d460205220613639565b602486634e487b7160e01b81526011600452fd5b6000198114610ab65760010190565b9060088110156136235760051b0190565b61386c906138ae565b6000811280156138a2575b61389c57613884906135ec565b90549060031b1c60005260ca60205260406000205490565b50600090565b508060c9541115613877565b64ffffffffff60cb5460281c16908181106138d55762015180916138d1916136a1565b0490565b505060001990565b6138e690613863565b9081156138ef57565b60046040517fb4190460000000000000000000000000000000000000000000000000000000008152fd5b9060048110156136235760051b0190565b6040516080810181811067ffffffffffffffff821117610d945760405260803682378091600090815b6004808210156139ac576201518090818302918383041483151715613999575090613988613983600193856136a1565b6138dd565b6139928287613919565b5201613953565b846011602492634e487b7160e01b835252fd5b505050505090565b604051906139c1826134b5565b816102206000918281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e0820152826102008201520152565b90604051613a45816134b5565b61022081935461ffff8082168452808260101c166020850152808260201c166040850152808260301c166060850152808260401c166080850152808260501c1660a0850152808260601c1660c0850152808260701c1660e085015260ff8260801c16610100850152808260881c16610120850152808260981c1661014085015260ff8260a81c16610160850152808260b01c16610180850152808260c01c166101a085015260ff8260d01c166101c0850152808260d81c166101e08501528160e81c1661020084015260f81c910152565b60288210156108b95752565b60405190613b2f826134d2565b816103006000918281528260208201528260408201528260608201528260808201528260a08201528260c08201528260e08201528261010082015282610120820152826101408201528261016082015282610180820152826101a0820152826101c0820152826101e08201528261020082015282610220820152826102408201528261026082015282610280820152826102a0820152826102c0820152826102e08201520152565b8115613be1570690565b634e487b7160e01b600052601260045260246000fd5b929091604051926020840194855260408401526060830152608082015260808152613c2181613527565b51902090565b9060009082825260ca60205260409081832054613e89576001815103613e6057613c5090613742565b51928315613e37575b80835260ca60205283828420556001600160a01b038060d3541680613de7575b5060d6541680613d86575b50907f5c69e7026b653d8606b5613bb00fd8c4b0504b1cbe8db600c406faac180924d5918151908152846020820152a160cb54906201518090814204828102928184041490151715613d725764ffffffffff91828460501c161115613cea575b50505050565b620545ff19420190428211613d7257506effffffffff00000000000000000000613d5961112c6111277fffffffffffffffffff00000000000000000000000000ffffffffffffffffffff9562093a8076ffffffffffffffff0000000000000000000000000000009604166136de565b60501b169360781b169116171760cb5538808080613ce4565b80634e487b7160e01b602492526011600452fd5b803b15613de35783809160248551809481936327fe556d60e21b83528a60048401525af18015613dd657908491613dbe575b50613c84565b613dc790613484565b613dd2578238613db8565b8280fd5b50505051903d90823e3d90fd5b8380fd5b803b15613e335784809160248651809481936327fe556d60e21b83528b60048401525af18015613e295715613c7957613e2290949194613484565b9238613c79565b84513d87823e3d90fd5b8480fd5b92506000194301438111613e4c574092613c59565b602483634e487b7160e01b81526011600452fd5b600482517fff633a38000000000000000000000000000000000000000000000000000000008152fd5b600482517f533d99dd000000000000000000000000000000000000000000000000000000008152fd5b91908110156136235760051b810135906102be198136030182121561032d570190565b3590811515820361032d57565b359062ffffff8216820361032d57565b359063ffffffff8216820361032d57565b359060ff8216820361032d57565b602090613f2f8261ffff9283613f26826133b7565b168652016133b7565b16910152565b60ff613f2f6040809361ffff80613f4b836133b7565b168752613f5a602083016133b7565b16602087015201613f03565b35908160010b820361032d57565b91602090808285018386525260409182850194838360051b82010195856000925b858410613fa757505050505050505090565b9091929394959697603f1982820301845288356102be198436030181121561032d576102c09190840161ffff83830181613fe0846133b7565b16845289830135602881101561032d57613ffd908b860190613581565b6140088c8401613ed5565b15158c85015260609161401c838501613ed5565b151583860152608061402f818601613ed5565b15159086015262ffffff60a081614047828801613ee2565b169087015260c063ffffffff61405e828801613ef2565b169087015260e090614071828701613ee2565b1690860152610100816140858287016133b7565b1690860152610120906140998286016133b7565b169085015260ff610140816140af828701613f03565b1690860152610160906140c3828601613f03565b16908501526101806140d6818501613ed5565b15159085015236839003601e19016101a0848101358281121561032d578501908c823592019367ffffffffffffffff9889841161032d578360061b3603861361032d578392890152528d6102e0870193916000915b81831061424e57505050506101c090818501359081121561032d578401918b8335930196831161032d578383023603871361032d5780869594928d97889303908701528381520195916000915b81831061422757505050509282916001946101e0614197818301613f66565b870b90830152856102006141ac838201613f66565b820b908401526102206141c0818401613f66565b820b908401526102406141d4818401613f66565b820b908401526102606141e8818401613f66565b820b908401526102806141fc818401613f66565b820b908401526142106102a0809301613f66565b900b9101529a019401940192969594939190613f95565b808093959697508861423d869a60019597613f35565b019701930190918b95949392614178565b808661425f86986001959697613f11565b0195019201908f61412b565b35801515810361032d5790565b3561ffff8116810361032d5790565b3562ffffff8116810361032d5790565b903590601e198136030182121561032d570180359067ffffffffffffffff821161032d57602001918160061b3603831361032d57565b91908110156136235760061b0190565b9060288110156108b95760ff80198354169116179055565b3563ffffffff8116810361032d5790565b3560ff8116810361032d5790565b903590601e198136030182121561032d570180359067ffffffffffffffff821161032d5760200191606082023603831361032d57565b358060010b810361032d5790565b61436181614278565b61ffff916000918316156149c95761010081019161437e83614278565b610120830190858061438f84614278565b1691161161499f5760e083019162ffffff806143aa85614287565b161561493d576143b984614287565b168015614929576236ee80066148ff575b856143d485614278565b16815260209460cc865260409283832087870135916028831015613e33576143fc83836142dd565b61440788870161426b565b15158254946060988a8c8b820161441d9061426b565b1515608083019961442d8b61426b565b151560181b63ff000000169260a0850161444690614287565b901b66ffffff00000000169360c00161445e906142f5565b60381b6affffffff00000000000000169461447890614287565b60581b6dffffff0000000000000000000000169561449590614278565b60701b6fffff0000000000000000000000000000169660081b61ff0016907fffffffffffffffffffffffffffffffff000000000000000000000000000000ff16179060101b62ff00001617171717171782556144f090614278565b81547fffffffffffffffffffffffffffff0000ffffffffffffffffffffffffffffffff1660809190911b61ffff60801b161781556145316101408801614306565b815460ff60901b191660909190911b60ff60901b161781556145566101608801614306565b81546145656101808a0161426b565b151560a01b74ff0000000000000000000000000000000000000000169160981b73ff0000000000000000000000000000000000000016907fffffffffffffffffffffff0000ffffffffffffffffffffffffffffffffffffff1617179055876145cc87614278565b16835260d28752838320886145e088614278565b16845283858120557343da95dc00babae5d00ebea2c8088f3f7cd77832916101a088019161460e838a614297565b90853b156148fb579087895180937f1a2bbf3d00000000000000000000000000000000000000000000000000000000825283604483018d600485015252606482019093835b8d8282106148d857505050819293508560248301520381885af480156148ce576148bb575b506101c0890193614689858b614314565b92823b156148b75791899189938c8685519788967f91f221eb000000000000000000000000000000000000000000000000000000008852604488019060048901525260648601939187905b82821061488d575050505083918291602483015203915af480156148835790869161486f575b50506001036147f45750505081908661471286614278565b16815260d1865220946147286101e0850161434a565b94865461020086016147399061434a565b60101b9161474a610220880161434a565b901b9261475a610240880161434a565b60301b9461476b610260890161434a565b901b9561477b610280890161434a565b60501b976102a00161478c9061434a565b901b6dffff000000000000000000000000169716906dffffffffffffffffffffffffffff1916179063ffff000016179065ffff0000000016179067ffff00000000000016179069ffff00000000000000001617906bffff000000000000000000001617179055565b91959650929650614815935061480b915085614297565b9050151593614314565b905082614865575b5081614855575b5061482c5750565b600490517fb28b6f38000000000000000000000000000000000000000000000000000000008152fd5b61485f915061426b565b38614824565b151591503861481d565b61487890613484565b613e335784386146fa565b87513d88823e3d90fd5b91948291949698508397506148a481600195613f35565b0195019101908694928c9694928f6146d4565b8880fd5b6148c790969196613484565b9438614678565b88513d89823e3d90fd5b919450925080826148eb60019488613f11565b0194019101928a92859294614653565b8780fd5b60046040517ffbf84394000000000000000000000000000000000000000000000000000000008152fd5b602482634e487b7160e01b81526012600452fd5b506101a0840161494d8186614297565b905061495a575b506143ca565b6149649085614297565b1561498b576149766020889201614278565b16801561492957618ca0066148ff5738614954565b602482634e487b7160e01b81526032600452fd5b60046040517f3ab272e6000000000000000000000000000000000000000000000000000000008152fd5b60046040517fc78a7d8b000000000000000000000000000000000000000000000000000000008152fd5b91908082526020809201929160005b828110614a10575050505090565b90919293828060019261ffff614a25896133b7565b16815201950193929101614a02565b9035601e198236030181121561032d57016020813591019167ffffffffffffffff821161032d578160051b3603831361032d57565b949192909461ffff8096168152614a8d6060946020938685850152868401916149f3565b906040908181840391015283825282820194838560051b84010197876000945b878610614ac1575050505050505050505090565b90919293949596979899601f19828203018a528a356101be198436030181121561032d57830190602882358181101561032d5791614b00818c94613581565b614b0b838501613f66565b91600192830b8483015262ffffff80614b258c8801613ee2565b168b84015280614b368b8801613ee2565b168a840152614b5e6080614b4c81890189614a34565b90916101c080918801528601916149f3565b60a09186614b6e848a018a614a34565b939094878203908801528381520192916000915b818310614cd4575050505060c089614b9b8289016133b7565b169084015260ff60e081614bb0828a01613f03565b169085015261010090614bc4828901613f03565b169084015261012089614bd88289016133b7565b169084015261014089614bec8289016133b7565b1690840152610160614bff818801613ed5565b1515908401526101809185614c1684890189614a34565b939094868203908701528381520192916000915b818310614ca357505050508390614c476101a09687810190614a34565b9390968183039101528281520193916000915b808310614c7d5750505050806001929c019a019601949392919097969597614aad565b919380849663ffffffff614c918597613ef2565b168152019501930190918b9392614c5a565b919390928095975035908282101561032d578f81614cc382938a95613581565b019501930190918e96949392614c2a565b9193978084979984614ce78b9597613ee2565b168152019601930190918f97959392614b82565b91908110156136235760051b0190565b91908110156136235760051b810135906101be198136030182121561032d570190565b60208082526101e0820190602884358181101561032d57614d559083869594960190613581565b614d60848601613f66565b92600193840b604082015262ffffff9586614d7d60408301613ee2565b16606083015286614d9060608301613ee2565b166080830152614da36080820182614a34565b806101c0999299968760a0870152526102008401989060005b818110614f5357505050614dd360a0830183614a34565b601f19858b03810160c0870152818b52998901926000905b828210614f2b5750505050614e7d614e6b61ffff80614e0c60c087016133b7565b1660e0870152614e5b81614e4b60ff614e3b81614e2b60e08c01613f03565b1661010090818d01528a01613f03565b1661012090818b015288016133b7565b16610140908189015286016133b7565b1661016090818701528401613ed5565b15156101809081860152830183614a34565b8483038a016101a086810191909152818452928901956000905b828210614efa575050505081614eb291889594930190614a34565b9490978284030191015282815201939260005b828110614ed457505050505090565b9091928280869763ffffffff614eea8599613ef2565b1681520196019493929101614ec5565b90919296879a98999a35908282101561032d578981614f1b82938f95613581565b9a9c9b9a01980193920190614e97565b90919293988a80829c9a9b84614f4089613ee2565b1681529a9c9b9a01950193920190614deb565b909199978980829b999a61ffff614f698f6133b7565b168152019b989a999801929101614dbc565b903590601e198136030182121561032d570180359067ffffffffffffffff821161032d57602001918160051b3603831361032d57565b614fb9613b22565b50614fc7610160820161426b565b6000901561579757506001600160f81b031960805b60f81b1680610200526001614ff5610180840184614f7b565b90501161576b575b5061500b60a0820182614f7b565b9050151580615742575b80156156fa575b8060a052156156ab575b60a05161567c575b60288135101561032d576150466101a0820182614f7b565b6000608052159050615677576150606101a0820182614f7b565b156136235761506e906142f5565b6080525b61507e6020820161434a565b60c05261508d60408201614287565b60e05261509c60608201614287565b906150aa6080820182614f7b565b600091501561567157506150c16080820182614f7b565b15613623576150cf90614278565b915b6150de60a0830183614f7b565b9050151580615667575b6000901561566157506150fe60a0830183614f7b565b156136235761510e60ff91614287565b16905b61511e6080840184614f7b565b600091506001101561565b57506151386080840184614f7b565b6001101561362357602061514c9101614278565b925b600161515d60a0830183614f7b565b90501180615651575b6000901561564b575061517c60a0820182614f7b565b6001101561362357615192602060ff9201614287565b16925b6151a26080830183614f7b565b600091506002101561564557506151bc6080830183614f7b565b600210156136235760406151d09101614278565b945b60026151e160a0850185614f7b565b9050118061563b575b60009015615635575061520060a0840184614f7b565b6002101561362357615216604060ff9201614287565b16935b61522560c08501614278565b9061523260e08601614306565b916152406101008701614306565b9461524e6101208801614278565b9761525c6101408901614278565b9a600161526d6101808b018b614f7b565b9050600061010052116000146156305761528b6101808a018a614f7b565b600110156136235760200135602881101561032d57610100525b60016152b56101a08b018b614f7b565b90506000610120521160001461562b576152d36101a08a018a614f7b565b600110156136235760206152e791016142f5565b610120525b60026152fc6101808b018b614f7b565b9050600061016052116000146156265761531a6101808a018a614f7b565b600210156136235760400135602881101561032d57610160525b60026153446101a08b018b614f7b565b905060006101405211600014615621576153626101a08a018a614f7b565b6002101561362357604061537691016142f5565b610140525b61538860a08a018a614f7b565b9050151580615618575b60006101805215615613576153aa60a08a018a614f7b565b15613623576153b890614287565b610180525b60016153cc60a08b018b614f7b565b9050118061560a575b60006101a05215615605576153ed60a08a018a614f7b565b600110156136235760206154019101614287565b6101a0525b600261541560a08b018b614f7b565b905011806155fc575b60006101c052156155d75761543660a08a018a614f7b565b600292919210156136235760ff61ffff9e9c8f829c9a819f849c9883869a9262ffffff829e61548c8a9661546d6040879f01614287565b6101c0525b615482604051806101e0526134d2565b356101e051613b16565b63ffffffff6080511660206101e051015260c05160010b60406101e05101528160e0511660606101e05101521660806101e05101521660a06101e05101521660c06101e05101521660e06101e0510152166101006101e0510152166101206101e0510152166101406101e0510152166101606101e0510152166101806101e0510152166101a06101e0510152166101c06101e0510152166101e0805101526001600160f81b031961020051166102006101e051015260006102206101e0510152615560610100516102406101e05101613b16565b63ffffffff61012051166102606101e0510152615587610160516102806101e05101613b16565b63ffffffff61014051166102a06101e051015262ffffff61018051166102c06101e051015262ffffff6101a051166102e06101e051015262ffffff6101c051166103006101e05101526101e05190565b61ffff9c9060ff8e9c8d829c9a83809c9883809c9862ffffff829a61548c869e615472565b5060a05161541e565b615406565b5060a0516153d5565b6153bd565b5060a051615392565b61537b565b615334565b6152ec565b6152a5565b93615219565b5060a051156151ea565b946151d2565b92615195565b5060a05115615166565b9261514e565b90615111565b5060a051156150e8565b916150d1565b615072565b7f200000000000000000000000000000000000000000000000000000000000000061020051176102005261502e565b60026156ba60a0830183614f7b565b905011806156cb575b60a052615026565b506156d960a0820182614f7b565b600210156136235762ffffff6156f3604060ff9301614287565b16116156c3565b50600161570a60a0830183614f7b565b905011801561501c575061572160a0820182614f7b565b600110156136235762ffffff61573b602060ff9301614287565b161161501c565b5061575060a0820182614f7b565b156136235762ffffff61576460ff92614287565b1611615015565b7f4000000000000000000000000000000000000000000000000000000000000000176102005238614ffd565b6001600160f81b031990614fdc565b90821015613623576134649160051b810190614f7b565b805490600090818155826157d057505050565b815260208120918201915b8281106157e757505050565b8181556001016157db565b805468010000000000000000811015610d945761581491600182018155613639565b9190916158595761ffff61582782614278565b1664ffffff000061584660208554948461ffff19871617875501614287565b60101b169164ffffffffff191617179055565b634e487b7160e01b600052600060045260246000fd5b6001600160a01b0360975416330361588357565b60046040517f6db2465f000000000000000000000000000000000000000000000000000000008152fd5b609754906001600160a01b0380911691826001600160a01b0319821617609755167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a3565b803b15615938576001600160a01b037f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc91166001600160a01b0319825416179055565b60046040517f71ab98ae000000000000000000000000000000000000000000000000000000008152fd5b9091901561596e575090565b81511561597e5750805190602001fd5b6159bc906040519182917f08c379a00000000000000000000000000000000000000000000000000000000083526020600484015260248301906135ac565b0390fdfea26469706673582212203a8c6106c01cc9fed6bfcfd415a98ad454ebc5441c507e78519a1853359a96d564736f6c63430008140033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.