Source Code
Latest 25 from a total of 13,278 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Approve Primordi... | 16364211 | 322 days ago | IN | 0 ETH | 0.00000052 | ||||
| Approve Primordi... | 16364071 | 322 days ago | IN | 0 ETH | 0.00000105 | ||||
| Approve Primordi... | 16363887 | 322 days ago | IN | 0 ETH | 0.00000145 | ||||
| Approve Primordi... | 16362778 | 322 days ago | IN | 0 ETH | 0.0000005 | ||||
| Approve Primordi... | 16003573 | 330 days ago | IN | 0 ETH | 0.00000008 | ||||
| Approve Primordi... | 15219514 | 349 days ago | IN | 0 ETH | 0.00000023 | ||||
| Claim Primordial | 15162035 | 350 days ago | IN | 0 ETH | 0.00000008 | ||||
| Approve Primordi... | 15162028 | 350 days ago | IN | 0 ETH | 0.00000006 | ||||
| Hatch Primordial... | 14875883 | 357 days ago | IN | 0 ETH | 0.00000099 | ||||
| Feed Primordial | 14875875 | 357 days ago | IN | 0 ETH | 0.00000059 | ||||
| Feed Primordial | 14764129 | 359 days ago | IN | 0 ETH | 0.00000038 | ||||
| Claim Primordial | 14764044 | 359 days ago | IN | 0 ETH | 0.0000003 | ||||
| Approve Primordi... | 14764040 | 359 days ago | IN | 0 ETH | 0.00000035 | ||||
| Approve Primordi... | 14753230 | 359 days ago | IN | 0 ETH | 0.0000003 | ||||
| Feed Primordial | 14705317 | 360 days ago | IN | 0 ETH | 0.00000004 | ||||
| Feed Primordial | 14579527 | 363 days ago | IN | 0 ETH | 0.00000014 | ||||
| Approve Primordi... | 14497492 | 365 days ago | IN | 0 ETH | 0.00000007 | ||||
| Feed Primordial | 14343735 | 369 days ago | IN | 0 ETH | 0.00000076 | ||||
| Feed Primordial | 14051973 | 376 days ago | IN | 0 ETH | 0.00000058 | ||||
| Hatch Primordial... | 14013730 | 376 days ago | IN | 0 ETH | 0.00000006 | ||||
| Feed Primordial | 14013716 | 376 days ago | IN | 0 ETH | 0.00000004 | ||||
| Claim Primordial | 14013700 | 376 days ago | IN | 0 ETH | 0.00000003 | ||||
| Approve Primordi... | 14013694 | 376 days ago | IN | 0 ETH | 0.00000008 | ||||
| Feed Primordial | 13926115 | 379 days ago | IN | 0 ETH | 0.00000012 | ||||
| Hatch Primordial... | 13904553 | 379 days ago | IN | 0 ETH | 0.00000029 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
PrimordialManager
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 2000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "./BaseBlastManager.sol";
import "../interfaces/IPrimordialManager.sol";
import "../interfaces/IRNGProxy.sol";
import "../interfaces/ISnuggeryManager.sol";
import "../interfaces/IAccountManager.sol";
import "../interfaces/INFTOverlord.sol";
contract PrimordialManager is BaseBlastManager, IPrimordialManager {
IAccountManager accountManager;
INFTOverlord nftOverlord;
mapping(address => MunchablesCommonLib.PrimordialData) primordials;
mapping(address => bool) approved;
bool primordialsEnabled;
mapping(int8 => uint256) primordialLevels;
modifier onlyPrimordialsEnabled() {
if (!primordialsEnabled) revert PrimordialsNotEnabledError();
_;
}
constructor(address _configStorage) {
__BaseConfigStorage_setConfigStorage(_configStorage);
_reconfigure();
}
function _reconfigure() internal {
accountManager = IAccountManager(
configStorage.getAddress(StorageKey.AccountManager)
);
nftOverlord = INFTOverlord(
configStorage.getAddress(StorageKey.NFTOverlord)
);
primordialsEnabled = configStorage.getBool(
StorageKey.PrimordialsEnabled
);
uint256[] memory primordialLevelsTmp = configStorage.getUintArray(
StorageKey.PrimordialLevelThresholds
);
if (primordialLevelsTmp.length == 3) {
for (uint8 i; i < 3; i++) {
// primordial levels range from -3 to 0, we have levelup thresholds for -2, -1 and 0
primordialLevels[int8(i) - 2] = primordialLevelsTmp[i];
}
}
super.__BaseBlastManager_reconfigure();
}
function configUpdated() external override onlyConfigStorage {
_reconfigure();
}
/// @inheritdoc IPrimordialManager
function claimPrimordial() external notPaused onlyPrimordialsEnabled {
(address _caller, ) = _getMainAccountRequireRegistered(msg.sender);
if (!approved[_caller]) revert PrimordialNotApprovedError();
if (primordials[_caller].createdDate > 0)
revert PrimordialAlreadyClaimedError();
primordials[_caller].createdDate = uint32(block.timestamp);
primordials[_caller].level = -3;
emit PrimordialClaimed(_caller);
}
/// @inheritdoc IPrimordialManager
function feedPrimordial(
uint256 _schnibbles
) external notPaused onlyPrimordialsEnabled {
(
address _mainAccount,
MunchablesCommonLib.Player memory _player
) = _getMainAccountRequireRegistered(msg.sender);
if (!approved[_mainAccount]) revert PrimordialNotApprovedError();
if (_player.unfedSchnibbles < _schnibbles)
revert InsufficientSchnibblesError(_player.unfedSchnibbles);
if (primordials[_mainAccount].createdDate == 0)
revert PrimordialDoesntExistError();
if (primordials[_mainAccount].hatched)
revert PrimordialAlreadyHatchedError();
primordials[_mainAccount].chonks += _schnibbles;
// Level up algo for primordials
int8 currentLevel = primordials[_mainAccount].level;
if (currentLevel < 0) {
int8 nextLevel = currentLevel;
while (
primordialLevels[nextLevel + 1] <=
primordials[_mainAccount].chonks &&
primordialLevels[nextLevel + 1] > 0 &&
nextLevel < 1
) {
nextLevel++;
}
if (primordials[_mainAccount].chonks > primordialLevels[0]) {
// Prevent overfeeding
_schnibbles -= (primordials[_mainAccount].chonks -
primordialLevels[0]);
primordials[_mainAccount].chonks = primordialLevels[0];
}
if (nextLevel != currentLevel) {
// primordial levelup
primordials[_mainAccount].level = nextLevel;
emit PrimordialLevelledUp(
_mainAccount,
currentLevel,
nextLevel
);
}
}
_player.unfedSchnibbles -= _schnibbles;
accountManager.updatePlayer(_mainAccount, _player);
emit PrimordialFed(_mainAccount, _schnibbles);
}
/// @inheritdoc IPrimordialManager
function hatchPrimordialToMunchable() external notPaused {
(address _caller, ) = _getMainAccountRequireRegistered(msg.sender);
if (!approved[_caller]) revert PrimordialNotApprovedError();
if (primordials[_caller].hatched)
revert PrimordialAlreadyHatchedError();
if (primordials[_caller].createdDate == 0)
revert PrimordialDoesntExistError();
if (primordials[_caller].level < 0) revert PrimordialNotReadyError();
if (primordials[_caller].hatched)
revert PrimordialAlreadyHatchedError();
primordials[_caller].hatched = true;
nftOverlord.mintFromPrimordial(_caller);
emit PrimordialHatched(_caller);
}
function approvePrimordial(
address _player,
bool _approve
) external onlyRole(Role.NFTOracle) {
approved[_player] = _approve;
if (_approve) emit PrimordialApproved(_player);
else emit PrimordialDisapproved(_player);
}
function getPrimordial(
address _caller
)
external
view
returns (MunchablesCommonLib.PrimordialData memory _primordial)
{
(address _player, ) = _getMainAccountRequireRegistered(_caller);
_primordial = primordials[_player];
}
function _getMainAccountRequireRegistered(
address _account
)
internal
view
returns (
address _mainAccount,
MunchablesCommonLib.Player memory _player
)
{
(_mainAccount, _player) = accountManager.getPlayer(_account);
if (_player.registrationDate == 0) revert PlayerNotRegisteredError();
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "../interfaces/IConfigStorage.sol";
import "../interfaces/IConfigNotifiable.sol";
import "../config/BaseConfigStorage.sol";
import "../interfaces/IBaseBlastManager.sol";
import "../interfaces/IHoldsGovernorship.sol";
import "../interfaces/IERC20YieldClaimable.sol";
import "../interfaces/IBlast.sol";
abstract contract BaseBlastManager is
IBaseBlastManager,
IERC20YieldClaimable,
BaseConfigStorage
{
IBlast public blastContract;
IBlastPoints public blastPointsContract;
address private _governorConfigured;
address private _pointsOperatorConfigured;
bool private _blastClaimableConfigured;
IERC20 public USDB;
IERC20 public WETH;
error InvalidGovernorError();
function __BaseBlastManager_reconfigure() internal {
// load config from the config storage contract and configure myself
address blastAddress = configStorage.getAddress(
StorageKey.BlastContract
);
if (blastAddress != address(blastContract)) {
blastContract = IBlast(blastAddress);
if (blastContract.isAuthorized(address(this))) {
blastContract.configureClaimableGas();
// fails on cloned networks
(bool success, ) = blastAddress.call(
abi.encodeWithSelector(
bytes4(keccak256("configureClaimableYield()"))
)
);
if (success) {
// not on a cloned network and no compiler error!
}
}
}
address pointsContractAddress = configStorage.getAddress(
StorageKey.BlastPointsContract
);
if (pointsContractAddress != address(blastPointsContract)) {
blastPointsContract = IBlastPoints(pointsContractAddress);
address pointsOperator = configStorage.getAddress(
StorageKey.BlastPointsOperator
);
if (_pointsOperatorConfigured == address(0)) {
// Reassignment must be called from the point operator itself
blastPointsContract.configurePointsOperator(pointsOperator);
_pointsOperatorConfigured = pointsOperator;
}
}
address usdbAddress = configStorage.getAddress(StorageKey.USDBContract);
address wethAddress = configStorage.getAddress(StorageKey.WETHContract);
if (usdbAddress != address(USDB)) {
USDB = IERC20(usdbAddress);
IERC20Rebasing _USDB = IERC20Rebasing(usdbAddress);
_USDB.configure(YieldMode.CLAIMABLE);
}
if (wethAddress != address(WETH)) {
WETH = IERC20(wethAddress);
IERC20Rebasing _WETH = IERC20Rebasing(wethAddress);
_WETH.configure(YieldMode.CLAIMABLE);
}
address rewardsManagerAddress = configStorage.getAddress(
StorageKey.RewardsManager
);
if (rewardsManagerAddress != address(0)) {
setBlastGovernor(rewardsManagerAddress);
}
super.__BaseConfigStorage_reconfigure();
}
function setBlastGovernor(address _governor) internal {
if (_governor == address(0)) revert InvalidGovernorError();
if (address(blastContract) == address(0)) return;
if (_governorConfigured == address(0)) {
// if this contract is the governor then it should claim its own yield/gas
if (_governor != address(this)) {
// Once this is called the governor will be the only account allowed to configure
blastContract.configureGovernor(_governor);
}
} else {
IHoldsGovernorship(_governorConfigured).reassignBlastGovernor(
_governor
);
}
_governorConfigured = _governor;
}
function claimERC20Yield(
address _tokenContract,
uint256 _amount
) external onlyConfiguredContract(StorageKey.RewardsManager) {
IERC20Rebasing(_tokenContract).claim(
configStorage.getAddress(StorageKey.RewardsManager),
_amount
);
}
function getConfiguredGovernor() external view returns (address _governor) {
_governor = _governorConfigured;
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "../libraries/MunchablesCommonLib.sol";
interface IPrimordialManager {
/// @notice Claim a primordial, this can only be done once and with an empty snuggery. Primordials cannot be
/// exported so will always be in the first slot of the snuggery
function claimPrimordial() external;
/// @notice Feed a primordial to increase its chonksno bonus is payable for primordials
/// @param _schnibbles Amount of schnibbles to feed
function feedPrimordial(uint256 _schnibbles) external;
/// @notice Get a player's primordial data
/// @param _player Player's address
function getPrimordial(
address _player
)
external
view
returns (MunchablesCommonLib.PrimordialData memory _primordial);
/// @notice Once a primordial reaches level 0, they can then be swapped for an NFT
/// @dev This uses the same code as a reveal, but manually adds to the queue and requests the RNG
function hatchPrimordialToMunchable() external;
/// @notice Approved by EOA to be allowed to claim a primordial (after anti-bot checks)
/// @param _player The player (can be sub-account) address to approve
/// @param _approve Whether to approve or disapprove
function approvePrimordial(address _player, bool _approve) external;
// @notice Emitted when a primordial is claimed by a player
event PrimordialClaimed(address indexed _player);
/// @notice Emitted when a primordial is fed
/// @param _player Owner of the primordial
/// @param _schnibbles Number of schnibbles fed
event PrimordialFed(address indexed _player, uint256 _schnibbles);
/// @notice Same as munchable level up but using ints and not uint because primordial level is always < 1
event PrimordialLevelledUp(
address indexed _player,
int16 _levelFrom,
int16 _levelTo
);
/// @notice Emitted when a primordial is hatched into a munchable
event PrimordialHatched(address indexed _player);
/// @notice Emitted when a player is approved to claim a primordial
event PrimordialApproved(address indexed _player);
/// @notice Emitted when a player is disapproved to claim a primordial
event PrimordialDisapproved(address indexed _player);
/// @notice Error thrown when primordial claiming is not enabled
error PrimordialsNotEnabledError();
/// @notice Error thrown when a primordial has already been claimed
error PrimordialAlreadyClaimedError();
/// @notice Error thrown when a player attempts swap a primordial but they haven't reached level 0
error PrimordialNotReadyError();
error PlayerNotRegisteredError();
/// @notice Error thrown when a player attempts to claim a primordial while not being eligible
error PrimordialNotEligibleError();
error PrimordialDoesntExistError();
error PrimordialAlreadyHatchedError();
error InsufficientSchnibblesError(uint256 schnibbles);
error PrimordialNotApprovedError();
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
interface IRNGProxy {
/// @notice Request a random number to be provided back to the contract specified
/// @param _contract The contract that will receive the data
/// @param _selector The function on the contract to call
/// @param _index A unique identifier which the contract can use to identify the target for the data
function requestRandom(
address _contract,
bytes4 _selector,
uint256 _index
) external;
event RandomRequested(
address indexed _target,
bytes4 _selector,
uint256 indexed _index
);
event RandomRequestComplete(
uint256 indexed _index,
bool _success,
bytes _data
);
error NoRequestError();
error CallbackFailedError();
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "../libraries/MunchablesCommonLib.sol";
/// @title Interface for the Account Manager
/// @notice This interface manages player accounts including their snuggery, schibbles, chonks, and sub-accounts
interface ISnuggeryManager {
/// @notice Imports a munchable to the player's snuggery
/// @dev Check that the NFT is approved to transfer by this contract
/// @param _tokenId The token ID to import
/// @custom:frontend Import a munchable
function importMunchable(uint256 _tokenId) external;
/// @notice Exports a munchable from the player's snuggery, the munchable will be returned directly
/// @param _tokenId The token ID to export
/// @custom:frontend Export a munchable
function exportMunchable(uint256 _tokenId) external;
/// @notice Feed a munchable to increase its chonks, chonks will be schnibbles multiplied by any feed bonus
/// @param _tokenId Token ID of the munchable to feed
/// @param _schnibbles Amount of schnibbles to feed
/// @custom:frontend Feed a munchable, use event data to show how much chonk was added
function feed(uint256 _tokenId, uint256 _schnibbles) external;
/// @notice Increase the number of slots in a player's snuggery
/// @param _quantity Quantity to increase the snuggery size by
function increaseSnuggerySize(uint8 _quantity) external;
/// @notice Pet another player's munchable to give both petter and petted some schnibbles
/// @param _pettedOwner The owner of the token being petted (the token must be in that player's snuggery)
/// @param _tokenId Token ID of the munchable to pet
/// @custom:frontend Pet another user's munchable. Check last pet and petted times to see if this function
/// should be available
function pet(address _pettedOwner, uint256 _tokenId) external;
/// @notice Retrieve the total schnibbles count for a player's snuggery
/// @param _player Address of the player
/// @return _totalChonk Total schnibbles count
function getTotalChonk(
address _player
) external view returns (uint256 _totalChonk);
/// @notice Retrieve the global total schnibbles count across all snuggeries
function getGlobalTotalChonk()
external
view
returns (uint256 _totalGlobalChonk);
/// @notice Gets a snuggery (array of SnuggeryNFT)
/// @param _player Address of the player to get snuggery for
/// @return _snuggery Array of SnuggeryNFT items
function getSnuggery(
address _player
)
external
view
returns (MunchablesCommonLib.SnuggeryNFT[] memory _snuggery);
/// @notice Emitted when a munchable is imported into a player's snuggery
/// @param _player The address of the player who imported the munchable
/// @param _tokenId The token ID of the munchable that was imported
/// @custom:frontend Listen for events for the mainAccount, when it is received update your snuggery data
event MunchableImported(address indexed _player, uint256 _tokenId);
/// @notice Emitted when a munchable is exported from a player's snuggery
/// @param _player The address of the player who exported the munchable
/// @param _tokenId The token ID of the munchable that was exported
/// @custom:frontend Listen for events for the mainAccount, when it is received update your snuggery data
event MunchableExported(address indexed _player, uint256 _tokenId);
/// @notice Emitted when a munchable is fed schnibbles
/// @param _player The address of the player who fed the munchable
/// @param _tokenId The token ID of the munchable that was fed
/// @param _baseChonks The base amount of chonks that were gained by feeding, will be equal to the schnibbles fed
/// @param _bonusChonks The additional bonus chonks that were awarded during the feeding
/// @custom:frontend Listen for events for your mainAccount and when this is received update the particular token
/// in the snuggery by reloading the NFT data
event MunchableFed(
address indexed _player,
uint256 _tokenId,
uint256 _baseChonks,
int256 _bonusChonks
);
/// @notice Emitted when a munchable is petted, distributing schnibbles to both the petter and the petted
/// @param _petter The address of the player who petted the munchable
/// @param _petted The address of the player who owns the petted munchable
/// @param _tokenId The token ID of the munchable that was petted
/// @param _petterSchnibbles The amount of schnibbles awarded to the petter
/// @param _pettedSchnibbles The amount of schnibbles awarded to the owner of the petted munchable
/// @custom:frontend Listen for events where your mainAccount petted and where it was pet
/// - If your mainAccount was petted, update the unfedMunchables total
/// - If your account was petted then, update the unfedMunchables total, also optionally load the
/// lastPetTime for the munchable if you use that
event MunchablePetted(
address indexed _petter,
address indexed _petted,
uint256 _tokenId,
uint256 _petterSchnibbles,
uint256 _pettedSchnibbles
);
/// @notice Event emitted when a snuggery size is increased
event SnuggerySizeIncreased(
address _player,
uint16 _previousSize,
uint16 _newSize
);
/// @notice Error thrown when a token ID is not found in the snuggery
error TokenNotFoundInSnuggeryError();
/// @notice Error thrown when a player's snuggery is already full and cannot accept more munchables
error SnuggeryFullError();
/// @notice Someone tries to import a munchable they do not own
error IncorrectOwnerError();
/// @notice Error if user tries to import someone else's NFT
error InvalidOwnerError();
/// @notice Error thrown when an action is attempted that requires the player to be registered, but they are not
error PlayerNotRegisteredError();
/// @notice Error thrown when a munchable is not found in a player's snuggery
error MunchableNotInSnuggeryError();
/// @notice Error thrown when a player attempts to pet their own munchable
error CannotPetOwnError();
/// @notice Error thrown when a munchable is petted too soon after the last petting
error PettedTooSoonError();
/// @notice Error thrown when a player attempts to pet too soon after their last petting action
error PetTooSoonError();
/// @notice Error thrown when a player tries to feed a munchable but does not have enough schnibbles
/// @param _currentUnfedSchnibbles The current amount of unfed schnibbles available to the player
error InsufficientSchnibblesError(uint256 _currentUnfedSchnibbles);
/// @notice Error thrown when a player attempts swap a primordial but they dont have one
error NoPrimordialInSnuggeryError();
/// @notice Invalid token id passed (normally if 0)
error InvalidTokenIDError();
/// @notice Contract is not approved to transfer NFT on behalf of user
error NotApprovedError();
/// @notice Something not configured
error NotConfiguredError();
/// @notice This is thrown by the claim manager but we need it here to decode selector
error NotEnoughPointsError();
/// @notice When petting the user petting must supply the main account being petted
error PettedIsSubAccount();
/// @notice Player tries to increase their snuggery size beyond global max size
error SnuggeryMaxSizeError();
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "../libraries/MunchablesCommonLib.sol";
/// @title Interface for the Account Manager
/// @notice This interface manages player accounts including their snuggery, schibbles, chonks, and sub-accounts
interface IAccountManager {
/// @notice Struct representing a "Squirt", which is a distribution of schnibbles to a player
struct Squirt {
address player; // The address of the player receiving schnibbles
uint256 schnibbles; // The amount of schnibbles being distributed to that player
}
/// @notice Struct representing a proposal to spray schnibbles across multiple accounts
struct SprayProposal {
uint32 proposedDate; // The date the proposal was made
Squirt[] squirts; // Array of "Squirt" structs detailing the distribution
}
/// @notice Register a new account, create a new Player record, and set snuggery and referrer
/// @dev This should be the first function called when onboarding a new user
/// @param _snuggeryRealm The realm of the new snuggery, which cannot be changed later
/// @param _referrer The account referring this user, use the null address if there is no referrer
/// @custom:frontend Register a new account
function register(
MunchablesCommonLib.Realm _snuggeryRealm,
address _referrer
) external;
/// @notice Calculate schnibbles to distribute and credit to unfedSchnibbles, set lastHarvestDate
/// @custom:frontend Harvest schnibbles
function harvest() external returns (uint256 _harvested);
/// @notice Used when a user adds to their lock to force claim at the previous locked value
/// @param _player Address of the player whose harvest to force
function forceHarvest(address _player) external;
/// @notice Propose a spray of schnibbles to multiple accounts
/// @param _players Array of player addresses
/// @param _schnibbles Array of schnibbles amounts corresponding to each player
function spraySchnibblesPropose(
address[] calldata _players,
uint256[] calldata _schnibbles
) external;
/// @notice Approve a proposed spray of schnibbles
/// @param _proposer Address of the proposer of the spray
function execSprayProposal(address _proposer) external;
/// @notice Remove a proposed spray of schnibbles
/// @param _proposer Address of the proposer of the spray to remove
function removeSprayProposal(address _proposer) external;
/// @notice Add a sub-account for a player
/// @param _subAccount The sub-account to add
/// @custom:frontend Use to add a new sub-account
function addSubAccount(address _subAccount) external;
/// @notice Remove a previously added sub-account
/// @param _subAccount The sub-account to remove
/// @custom:frontend Use to remove an existing sub-account
function removeSubAccount(address _subAccount) external;
/// @notice Restricted to the Munchable Manager only
function updatePlayer(
address _account,
MunchablesCommonLib.Player memory _player
) external;
/// @notice Look up the main account associated with a potentially sub-account
/// @param _maybeSubAccount Account to check
/// @return _mainAccount Main account associated, or the input if not a sub-account
function getMainAccount(
address _maybeSubAccount
) external view returns (address _mainAccount);
/// @notice Get a list of sub-accounts associated with a main account
/// @param _player Main account to check
/// @param _start Index to start pagination
/// @return _subAccounts List of sub-accounts
/// @return _more Whether there are more sub-accounts beyond the returned list
/// @custom:frontend Use this to populate a UI for managing sub accounts
function getSubAccounts(
address _player,
uint256 _start
) external view returns (address[20] memory _subAccounts, bool _more);
/// @notice Retrieve player data for a given account
/// @param _account Account to retrieve data for
/// @return _mainAccount Main account associated, or the input if not a sub-account
/// @return _player Player data structure
/// @custom:frontend Call this straight after log in to get the data about this player. The account
/// logging in may be a sub account and in this case the _mainAccount parameter
/// will be different from the logged in user. In this case the UI should show only
/// functions available to a sub-account
function getPlayer(
address _account
)
external
view
returns (
address _mainAccount,
MunchablesCommonLib.Player memory _player
);
/// @notice Retrieve detailed player and snuggery data
/// @param _account Address of the player
/// @return _mainAccount Main account associated
/// @return _player Player data
/// @return _snuggery List of snuggery NFTs
/// @custom:frontend Use this to fetch player and snuggery data
function getFullPlayerData(
address _account
)
external
view
returns (
address _mainAccount,
MunchablesCommonLib.Player memory _player,
MunchablesCommonLib.SnuggeryNFT[] memory _snuggery
);
/// @notice Get daily schnibbles that an account is accrueing
/// @param _player The address of the player
function getDailySchnibbles(
address _player
) external view returns (uint256 _dailySchnibbles, uint256 _bonus);
/// @notice Emitted when a player registers for a new account
/// @param _player The address of the player who registered
/// @param _snuggeryRealm The realm associated with the new snuggery chosen by the player
/// @param _referrer The address of the referrer, if any; otherwise, the zero address
/// @custom:frontend You should only receive this event once and only if you are onboarding a new user
/// safe to ignore if you are in the onboarding process
event PlayerRegistered(
address indexed _player,
MunchablesCommonLib.Realm _snuggeryRealm,
address _referrer
);
/// @notice Emitted when a player's schnibbles are harvested
/// @param _player The address of the player who harvested schnibbles
/// @param _harvestedSchnibbles The total amount of schnibbles that were harvested
/// @custom:frontend Listen for events where _player is your mainAccount and update unfedSchnibbles total
event Harvested(address indexed _player, uint256 _harvestedSchnibbles);
/// @notice Emitted when a sub-account is added to a player's account
/// @param _player The address of the main account to which a sub-account was added
/// @param _subAccount The address of the sub-account that was added
/// @custom:frontend If you are managing sub accounts (ie the logged in user is not a subAccount), then use this
/// event to reload your cache of sub accounts
event SubAccountAdded(address indexed _player, address _subAccount);
/// @notice Emitted when a sub-account is removed from a player's account
/// @param _player The address of the main account from which a sub-account was removed
/// @param _subAccount The address of the sub-account that was removed
/// @custom:frontend If you are managing sub accounts (ie the logged in user is not a subAccount), then use this
/// event to reload your cache of sub accounts
event SubAccountRemoved(address indexed _player, address _subAccount);
/// @notice Emitted when a proposal to spray schnibbles is made
/// @param _proposer The address of the player who proposed the spray
/// @param _squirts An array of "Squirt" details defining the proposed schnibble distribution
/// @custom:admin
event ProposedScnibblesSpray(address indexed _proposer, Squirt[] _squirts);
/// @notice Emitted when a schnibble spray is executed for each player
/// @param _player The player receiving schnibbles
/// @param _schnibbles The amount of schnibbles received
event SchnibblesSprayed(address indexed _player, uint256 _schnibbles);
/// @notice Emitted when schnibbles are removed. This is used to reverse a schnibble spray in the case of some being improperly sent.
/// @param _player The schnibbles remove
/// @param _schnibbles The amount of schnibbles removed
event SchnibblesSprayedRemoved(
address indexed _player,
uint256 _schnibbles
);
/// @notice Emitted when a spray proposal is executed
/// @param _proposer The account which proposed the spray
event SprayProposalExecuted(address indexed _proposer);
/// @notice Emitted when a spray proposal is removed
/// @param _proposer Account that proposed the proposal
event SprayProposalRemoved(address indexed _proposer);
// Errors
/// @notice Error thrown when a player is already registered and attempts to register again
error PlayerAlreadyRegisteredError();
/// @notice Error thrown when an action is attempted that requires the player to be registered, but they are not
error PlayerNotRegisteredError();
/// @notice Error thrown when the main account of a player is not registered
error MainAccountNotRegisteredError(address _mainAccount);
/// @notice Error thrown when there are no pending reveals for a player
error NoPendingRevealError();
/// @notice Error thrown when a sub-account is already registered and an attempt is made to register it again
error SubAccountAlreadyRegisteredError();
/// @notice Error thrown when a sub-account attempts to register as a main account
error SubAccountCannotRegisterError();
/// @notice Error thrown when a spray proposal already exists and another one is attempted
error ExistingProposalError();
/// @notice Error thrown when the parameters provided to a function do not match in quantity or type
error UnMatchedParametersError();
/// @notice Error thrown when too many entries are attempted to be processed at once
error TooManyEntriesError();
/// @notice Error thrown when an expected parameter is empty
error EmptyParameterError();
/// @notice Error thrown when a realm is invalid
error InvalidRealmError();
/// @notice Error thrown when a sub-account is not registered and is tried to be removed
error SubAccountNotRegisteredError();
/// @notice Error thrown when a proposal is attempted to be executed, but none exists
error EmptyProposalError();
/// @notice Error thrown when a player attempts to refer themselves
error SelfReferralError();
/// @notice Error thrown when the same sprayer gets added twice in a proposal
error DuplicateSprayerError();
/// @notice When a user tries to create too many sub accounts (currently 5 max)
error TooManySubAccountsError();
error TooHighSprayAmountError();
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "../libraries/MunchablesCommonLib.sol";
/// @title Interface for the NFT Overlord
/// @notice This interface manages NFT minting and level up functions which rely on the RNGProxy. The implementation
/// contract will also handle notification from the LockManager contract when a player has earned
interface INFTOverlord {
/// @notice Stored between level up requests for a specific token id
struct LevelUpRequest {
address owner;
uint256 tokenId;
uint16 fromLevel;
uint16 toLevel;
}
/// @notice Struct to define mint probabilities based on percentage and species array
struct MintProbability {
uint32 percentage; // Probability percentage
uint8[] species; // Array of species IDs that can be minted under this probability
}
/// @notice Deduct one from Player.unrevealedNFTs and add one to AccountManager.revealQueue
/// @custom:frontend Use to reveal an NFT, listen for the events to see when it was minted
function startReveal() external;
/// @notice Add to Player.unrevealedNFTs, function only callable by lock manager
/// @param _player Address of the player
/// @param _quantity Quantity of reveals to add
function addReveal(address _player, uint16 _quantity) external;
/// @notice Reveals an NFT based on provided player ID and signature, decrementing the reveal queue
/// @param _player The player ID for whom the NFT will be revealed
/// @param _signature The signature to validate the reveal process
/// @return _tokenId The ID of the minted NFT
/// @dev This function should be called after RNG process
function reveal(
uint256 _player,
bytes memory _signature
) external returns (uint256 _tokenId);
/// @notice Called by PrimordialManager when a primordial has reached level 0 and can be hatched into a Munchable
/// @param _player The player address
function mintFromPrimordial(address _player) external; // only PrimordialManager
/// @notice Reveals an NFT based on provided player ID and signature, this is from a primordial hatching
/// @param _player The player ID whom the NFT will be revealed
/// @param _signature The signature to validate the reveal process
/// @return _tokenId The ID of the minted NFT
/// @dev This function should be called after RNG process
function revealFromPrimordial(
uint256 _player,
bytes memory _signature
) external returns (uint256 _tokenId);
/// @notice Mints an NFT for migration from V1 to V2, preserving attributes
/// @param _player The address of the player receiving the NFT
/// @param _attributes The dynamic attributes of the NFT
/// @param _immutableAttributes The immutable attributes of the NFT
/// @param _gameAttributes The game attributes of the NFT
/// @return _tokenId The token ID of the newly minted NFT
/// @dev Only callable by the migration manager
function mintForMigration(
address _player,
MunchablesCommonLib.NFTAttributes memory _attributes,
MunchablesCommonLib.NFTImmutableAttributes memory _immutableAttributes,
MunchablesCommonLib.NFTGameAttribute[] memory _gameAttributes
) external returns (uint256 _tokenId);
/// @notice Called post-level-up to randomly adjust game attributes based on transaction hash and signature
/// @param _requestId The ID of the RNG request
/// @param _rng Random bytes from the RNGProxy
/// @dev Only can be called by the RNGProxy
function levelUp(uint256 _requestId, bytes memory _rng) external;
/// @notice Called by SnuggeryManager when a player feeds a Munchable, it will check if level up is needed and
/// request randomness to update game attributes
/// @param _tokenId The token ID which was fed
/// @param _owner The eventual owner of the NFT at the time of the level up
function munchableFed(uint256 _tokenId, address _owner) external; // onlySnuggeryManager
/// @notice Get a player's unrevealed NFTs
/// @param _player The player to query, if a sub account is provided the main account unrevealedNFTs will be returned
function getUnrevealedNFTs(
address _player
) external view returns (uint16 _unrevealed);
/// @notice Get the current level and the next level threshold for a NFT given its schnibbles count
/// @param _chonks Quantity of schnibbles
/// @return _currentLevel Current level of the NFT
/// @return _nextLevelThreshold Schnibbles threshold for the next level
function getLevelUpData(
uint256 _chonks
) external view returns (uint16 _currentLevel, uint256 _nextLevelThreshold);
/// @notice Emitted when a player requests to reveal a munchable
/// @param _player The address of the player who initiated the reveal
event MunchableRevealRequested(address indexed _player);
/// @notice Emitted when a munchable levels up and requires an update to its attributes by an off-chain process
/// @param _player The address of the player whose munchable is leveling up
/// @param _tokenId The token ID of the munchable leveling up
/// @param _levelFrom The current level of the munchable
/// @param _levelTo The new level that the munchable should be updated to
event MunchableLevelUpRequest(
address indexed _player,
uint256 _tokenId,
uint16 _levelFrom,
uint16 _levelTo
);
/// @notice Event emitted when an NFT is revealed
event Revealed(
address indexed _owner,
uint256 _tokenId,
MunchablesCommonLib.NFTImmutableAttributes _immutableAttributes
);
/// @notice Event emitted when an NFT is leveled up
event LevelledUp(
address _owner,
uint256 _tokenId,
uint16 _fromLevel,
uint16 _toLevel,
MunchablesCommonLib.NFTGameAttribute[] _gameAttributes
);
/// @notice Emitted when a primordial is hatched into a munchable
event PrimordialHatched(
address indexed _player,
MunchablesCommonLib.NFTImmutableAttributes _immutableAttributes
);
/// @notice Event emitted when an NFT is minted for migration
event MintedForMigration(
address _player,
uint256 indexed _tokenId,
MunchablesCommonLib.NFTImmutableAttributes _immutableAttributes,
MunchablesCommonLib.NFTAttributes _attributes,
MunchablesCommonLib.NFTGameAttribute[] _gameAttributes
);
/// @notice Error thrown when there are no unrevealed munchables available for a player
error NoUnrevealedMunchablesError();
/// @notice Error thrown when a player's reveal queue is full and cannot handle more reveals
error RevealQueueFullError();
/// @notice Error thrown when a player's reveal queue is empty and there is nothing to reveal
error RevealQueueEmptyError();
/// @notice Error when a level up request either doesn't exist or the fromLevel is invalid
error InvalidLevelUpRequest();
/// @notice Error when no species is found for a given rarity during NFT creation
/// @param _rarity The rarity level that failed to produce a species
error NoSpeciesFoundError(MunchablesCommonLib.Rarity _rarity);
/// @notice Error if reveal cannot find species in realmLookup
/// @param _speciesId The species that failed
error NoRealmFoundError(uint16 _speciesId);
/// @notice Error thrown when a player attempts to claim a primordial while not being eligible
error PrimordialNotEligibleError();
/// @notice Error thrown when an action is attempted that requires the player to be registered, but they are not
error PlayerNotRegisteredError();
/// @notice Retrigger level rng
event RetriggeredLevelRNG(uint256[] tokenIds);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 value) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets a `value` amount of tokens as the allowance of `spender` over the
* caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 value) external returns (bool);
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
enum StorageKey {
Many,
Paused,
LockManager,
AccountManager,
ClaimManager,
MigrationManager,
NFTOverlord,
SnuggeryManager,
PrimordialManager,
MunchadexManager,
MunchNFT,
MunchToken,
RewardsManager,
YieldDistributor,
GasFeeDistributor,
BlastContract,
BlastPointsContract,
BlastPointsOperator,
USDBContract,
WETHContract,
RNGProxyContract,
NFTAttributesManager,
Treasury,
OldMunchNFT,
MaxLockDuration,
DefaultSnuggerySize,
MaxSnuggerySize,
MaxRevealQueue,
MaxSchnibbleSpray,
PetTotalSchnibbles,
NewSlotCost,
PrimordialsEnabled,
BonusManager,
ReferralBonus,
RealmBonuses,
RarityBonuses,
LevelThresholds,
PrimordialLevelThresholds,
TotalMunchables,
MunchablesPerRealm,
MunchablesPerRarity,
RaritySetBonuses,
PointsPerPeriod,
PointsPerToken,
SwapEnabled,
PointsPerMigratedNFT,
PointsPerUnrevealedNFT,
MinETHPetBonus,
MaxETHPetBonus,
PetBonusMultiplier,
RealmLookups,
// Species & Probabilities
CommonSpecies,
RareSpecies,
EpicSpecies,
LegendarySpecies,
MythicSpecies,
CommonPercentage,
RarePercentage,
EpicPercentage,
LegendaryPercentage,
MythicPercentage,
MigrationBonus,
MigrationBonusEndTime,
MigrationDiscountFactor
}
enum Role {
Admin,
Social_1,
Social_2,
Social_3,
Social_4,
Social_5,
SocialApproval_1,
SocialApproval_2,
SocialApproval_3,
SocialApproval_4,
SocialApproval_5,
PriceFeed_1,
PriceFeed_2,
PriceFeed_3,
PriceFeed_4,
PriceFeed_5,
Snapshot,
NewPeriod,
ClaimYield,
Minter,
NFTOracle
}
enum StorageType {
Uint,
SmallUintArray,
UintArray,
SmallInt,
SmallIntArray,
Bool,
Address,
AddressArray,
Bytes32
}
interface IConfigStorage {
// Manual notify
function manualNotify(uint8 _index, uint8 _length) external;
// Manual notify for a specific contract
function manualNotifyAddress(address _contract) external;
// Setters
function setRole(Role _role, address _contract, address _addr) external;
function setUniversalRole(Role _role, address _addr) external;
function setUint(StorageKey _key, uint256 _value, bool _notify) external;
function setUintArray(
StorageKey _key,
uint256[] memory _value,
bool _notify
) external;
function setSmallUintArray(
StorageKey _key,
uint8[] calldata _smallUintArray,
bool _notify
) external;
function setSmallInt(StorageKey _key, int16 _value, bool _notify) external;
function setSmallIntArray(
StorageKey _key,
int16[] memory _value,
bool _notify
) external;
function setBool(StorageKey _key, bool _value, bool _notify) external;
function setAddress(StorageKey _key, address _value, bool _notify) external;
function setAddresses(
StorageKey[] memory _keys,
address[] memory _values,
bool _notify
) external;
function setAddressArray(
StorageKey _key,
address[] memory _value,
bool _notify
) external;
function setBytes32(StorageKey _key, bytes32 _value, bool _notify) external;
// Getters
function getRole(Role _role) external view returns (address);
function getContractRole(
Role _role,
address _contract
) external view returns (address);
function getUniversalRole(Role _role) external view returns (address);
function getUint(StorageKey _key) external view returns (uint256);
function getUintArray(
StorageKey _key
) external view returns (uint256[] memory);
function getSmallUintArray(
StorageKey _key
) external view returns (uint8[] memory _smallUintArray);
function getSmallInt(StorageKey _key) external view returns (int16);
function getSmallIntArray(
StorageKey _key
) external view returns (int16[] memory);
function getBool(StorageKey _key) external view returns (bool);
function getAddress(StorageKey _key) external view returns (address);
function getAddressArray(
StorageKey _key
) external view returns (address[] memory);
function getBytes32(StorageKey _key) external view returns (bytes32);
// Notification Address Management
function addNotifiableAddress(address _addr) external;
function addNotifiableAddresses(address[] memory _addresses) external;
function removeNotifiableAddress(address _addr) external;
function getNotifiableAddresses()
external
view
returns (address[] memory _addresses);
error ArrayTooLongError();
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
import "./IConfigStorage.sol";
interface IConfigNotifiable {
function configUpdated() external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "../interfaces/IConfigStorage.sol";
abstract contract BaseConfigStorage {
IConfigStorage public configStorage;
bool _paused;
modifier onlyConfigStorage() {
if (msg.sender != address(configStorage)) revert OnlyStorageError();
_;
}
modifier onlyConfiguredContract(StorageKey _key) {
address configuredContract = configStorage.getAddress(_key);
if (configuredContract == address(0)) revert UnconfiguredError(_key);
if (configuredContract != msg.sender) revert UnauthorisedError();
_;
}
modifier onlyConfiguredContract2(StorageKey _key, StorageKey _key2) {
address configuredContract = configStorage.getAddress(_key);
address configuredContract2 = configStorage.getAddress(_key2);
if (
configuredContract != msg.sender &&
configuredContract2 != msg.sender
) {
if (configuredContract == address(0))
revert UnconfiguredError(_key);
if (configuredContract2 == address(0))
revert UnconfiguredError(_key2);
revert UnauthorisedError();
}
_;
}
modifier onlyConfiguredContract3(
StorageKey _key,
StorageKey _key2,
StorageKey _key3
) {
address configuredContract = configStorage.getAddress(_key);
address configuredContract2 = configStorage.getAddress(_key2);
address configuredContract3 = configStorage.getAddress(_key3);
if (
configuredContract != msg.sender &&
configuredContract2 != msg.sender &&
configuredContract3 != msg.sender
) {
if (configuredContract == address(0))
revert UnconfiguredError(_key);
if (configuredContract2 == address(0))
revert UnconfiguredError(_key2);
if (configuredContract3 == address(0))
revert UnconfiguredError(_key3);
revert UnauthorisedError();
}
_;
}
modifier onlyOneOfRoles(Role[5] memory roles) {
for (uint256 i = 0; i < roles.length; i++) {
if (msg.sender == configStorage.getRole(roles[i])) {
_;
return;
}
}
revert InvalidRoleError();
}
modifier onlyRole(Role role) {
if (msg.sender != configStorage.getRole(role))
revert InvalidRoleError();
_;
}
modifier onlyUniversalRole(Role role) {
if (msg.sender != configStorage.getUniversalRole(role))
revert InvalidRoleError();
_;
}
modifier onlyAdmin() {
if (msg.sender != configStorage.getUniversalRole(Role.Admin))
revert InvalidRoleError();
_;
}
modifier notPaused() {
if (_paused) revert ContractsPausedError();
_;
}
error UnconfiguredError(StorageKey _key);
error UnauthorisedError();
error OnlyStorageError();
error InvalidRoleError();
error ContractsPausedError();
function configUpdated() external virtual;
function __BaseConfigStorage_setConfigStorage(
address _configStorage
) internal {
configStorage = IConfigStorage(_configStorage);
}
function __BaseConfigStorage_reconfigure() internal {
_paused = configStorage.getBool(StorageKey.Paused);
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
interface IBaseBlastManager {
function getConfiguredGovernor() external view returns (address _governor);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
/// @notice Contracts which implement this interface will be the governor for other contracts and
/// give it up on request from the contract
interface IHoldsGovernorship {
function reassignBlastGovernor(address _newAddress) external;
function isGovernorOfContract(
address _contract
) external view returns (bool);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
/// @notice Contracts which implement this interface can be instructed by Rewards Manager to claim their yield for
/// ERC20 tokens and send the yield back to the rewards manager
interface IERC20YieldClaimable {
function claimERC20Yield(address _tokenContract, uint256 _amount) external;
}// SPDX-License-Identifier: MIT
pragma solidity 0.8.25;
enum YieldMode {
AUTOMATIC,
VOID,
CLAIMABLE
}
enum GasMode {
VOID,
CLAIMABLE
}
interface IBlastPoints {
function configurePointsOperator(address operator) external;
}
interface IERC20Rebasing {
function configure(YieldMode) external returns (uint256);
function claim(
address recipient,
uint256 amount
) external returns (uint256);
function getClaimableAmount(
address account
) external view returns (uint256);
}
interface IBlast {
// configure
function configureContract(
address contractAddress,
YieldMode _yield,
GasMode gasMode,
address governor
) external;
function configure(
YieldMode _yield,
GasMode gasMode,
address governor
) external;
// base configuration options
function configureClaimableYield() external;
function configureClaimableYieldOnBehalf(address contractAddress) external;
function configureAutomaticYield() external;
function configureAutomaticYieldOnBehalf(address contractAddress) external;
function configureVoidYield() external;
function configureVoidYieldOnBehalf(address contractAddress) external;
function configureClaimableGas() external;
function configureClaimableGasOnBehalf(address contractAddress) external;
function configureVoidGas() external;
function configureVoidGasOnBehalf(address contractAddress) external;
function configureGovernor(address _governor) external;
function configureGovernorOnBehalf(
address _newGovernor,
address contractAddress
) external;
// claim yield
function claimYield(
address contractAddress,
address recipientOfYield,
uint256 amount
) external returns (uint256);
function claimAllYield(
address contractAddress,
address recipientOfYield
) external returns (uint256);
// claim gas
function claimAllGas(
address contractAddress,
address recipientOfGas
) external returns (uint256);
function claimGasAtMinClaimRate(
address contractAddress,
address recipientOfGas,
uint256 minClaimRateBips
) external returns (uint256);
function claimMaxGas(
address contractAddress,
address recipientOfGas
) external returns (uint256);
function claimGas(
address contractAddress,
address recipientOfGas,
uint256 gasToClaim,
uint256 gasSecondsToConsume
) external returns (uint256);
// read functions
function readClaimableYield(
address contractAddress
) external view returns (uint256);
function readYieldConfiguration(
address contractAddress
) external view returns (uint8);
function readGasParams(
address contractAddress
)
external
view
returns (
uint256 etherSeconds,
uint256 etherBalance,
uint256 lastUpdated,
GasMode
);
/**
* @notice Checks if the caller is authorized
* @param contractAddress The address of the contract
* @return A boolean indicating if the caller is authorized
*/
function isAuthorized(address contractAddress) external view returns (bool);
function isGovernor(address contractAddress) external view returns (bool);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
library MunchablesCommonLib {
enum Rarity {
Primordial,
Common,
Rare,
Epic,
Legendary,
Mythic,
Invalid
}
enum Realm {
Everfrost,
Drench,
Moltania,
Arridia,
Verdentis,
Invalid
}
struct NFTImmutableAttributes {
Rarity rarity;
uint16 species;
Realm realm;
uint8 generation;
uint32 hatchedDate;
}
struct NFTAttributes {
uint256 chonks;
uint16 level;
uint16 evolution;
uint256 lastPettedTime;
}
struct NFTGameAttribute {
GameAttributeType dataType;
bytes value;
}
struct Munchadex {
mapping(Realm => uint256) numInRealm;
mapping(Rarity => uint256) numInRarity;
mapping(bytes32 => uint256) unique;
uint256 numUnique;
}
enum GameAttributeIndex {
Strength,
Agility,
Stamina,
Defence,
Voracity,
Cuteness,
Charisma,
Trustworthiness,
Leadership,
Empathy,
Intelligence,
Cunning,
Creativity,
Adaptability,
Wisdom,
IsOriginal,
IndexCount // Do not use and keep at the end to detect number of indexes
}
enum GameAttributeType {
NotSet,
Bool,
String,
SmallInt,
BigUInt,
Bytes
}
struct PrimordialData {
uint256 chonks;
uint32 createdDate;
int8 level;
bool hatched;
}
struct SnuggeryNFT {
uint256 tokenId;
uint32 importedDate;
}
struct NFTFull {
uint256 tokenId;
NFTImmutableAttributes immutableAttributes;
NFTAttributes attributes;
NFTGameAttribute[] gameAttributes;
}
struct Player {
uint32 registrationDate;
uint32 lastPetMunchable;
uint32 lastHarvestDate;
Realm snuggeryRealm;
uint16 maxSnuggerySize;
uint256 unfedSchnibbles;
address referrer;
}
// Pure Functions
/// @notice Error when insufficient random data is provided for operations
error NotEnoughRandomError();
function calculateRaritySpeciesPercentage(
bytes memory randomBytes
) internal pure returns (uint32, uint32) {
if (randomBytes.length < 5) revert NotEnoughRandomError();
uint32 rarityBytes;
uint8 speciesByte;
uint32 rarityPercentage;
uint32 speciesPercent;
rarityBytes =
(uint32(uint8(randomBytes[0])) << 24) |
(uint32(uint8(randomBytes[1])) << 16) |
(uint32(uint8(randomBytes[2])) << 8) |
uint32(uint8(randomBytes[3]));
speciesByte = uint8(randomBytes[4]);
uint256 rarityPercentageTmp = (uint256(rarityBytes) * 1e6) /
uint256(4294967295);
uint256 speciesPercentTmp = (uint256(speciesByte) * 1e6) / uint256(255);
rarityPercentage = uint32(rarityPercentageTmp);
speciesPercent = uint32(speciesPercentTmp);
return (rarityPercentage, speciesPercent);
}
function getLevelThresholds(
uint256[] memory levelThresholds,
uint256 _chonk
)
internal
pure
returns (uint16 _currentLevel, uint256 _currentLevelThreshold)
{
if (_chonk >= levelThresholds[99]) {
return (101, levelThresholds[99]);
}
if (_chonk < levelThresholds[0]) {
return (1, 0);
}
uint256 low = 0;
uint256 high = levelThresholds.length;
uint256 mid = 0;
uint16 answer = 0;
while (low < high) {
mid = (low + high) / 2;
if (levelThresholds[mid] <= _chonk) {
low = mid + 1;
} else {
answer = uint16(mid);
high = mid;
}
}
_currentLevel = answer + 1;
_currentLevelThreshold = levelThresholds[uint256(answer - 1)];
}
}{
"remappings": [
"@api3/=node_modules/@api3/",
"@openzeppelin/contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/contracts/",
"@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/",
"ds-test/=lib/openzeppelin-contracts-upgradeable/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/openzeppelin-contracts-upgradeable/lib/erc4626-tests/",
"forge-std/=lib/forge-std/src/",
"openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/",
"openzeppelin-contracts/=lib/openzeppelin-contracts/"
],
"optimizer": {
"enabled": true,
"runs": 2000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": true,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_configStorage","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ContractsPausedError","type":"error"},{"inputs":[{"internalType":"uint256","name":"schnibbles","type":"uint256"}],"name":"InsufficientSchnibblesError","type":"error"},{"inputs":[],"name":"InvalidGovernorError","type":"error"},{"inputs":[],"name":"InvalidRoleError","type":"error"},{"inputs":[],"name":"OnlyStorageError","type":"error"},{"inputs":[],"name":"PlayerNotRegisteredError","type":"error"},{"inputs":[],"name":"PrimordialAlreadyClaimedError","type":"error"},{"inputs":[],"name":"PrimordialAlreadyHatchedError","type":"error"},{"inputs":[],"name":"PrimordialDoesntExistError","type":"error"},{"inputs":[],"name":"PrimordialNotApprovedError","type":"error"},{"inputs":[],"name":"PrimordialNotEligibleError","type":"error"},{"inputs":[],"name":"PrimordialNotReadyError","type":"error"},{"inputs":[],"name":"PrimordialsNotEnabledError","type":"error"},{"inputs":[],"name":"UnauthorisedError","type":"error"},{"inputs":[{"internalType":"enum StorageKey","name":"_key","type":"uint8"}],"name":"UnconfiguredError","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_player","type":"address"}],"name":"PrimordialApproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_player","type":"address"}],"name":"PrimordialClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_player","type":"address"}],"name":"PrimordialDisapproved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_player","type":"address"},{"indexed":false,"internalType":"uint256","name":"_schnibbles","type":"uint256"}],"name":"PrimordialFed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_player","type":"address"}],"name":"PrimordialHatched","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_player","type":"address"},{"indexed":false,"internalType":"int16","name":"_levelFrom","type":"int16"},{"indexed":false,"internalType":"int16","name":"_levelTo","type":"int16"}],"name":"PrimordialLevelledUp","type":"event"},{"inputs":[],"name":"USDB","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"WETH","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_player","type":"address"},{"internalType":"bool","name":"_approve","type":"bool"}],"name":"approvePrimordial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"blastContract","outputs":[{"internalType":"contract IBlast","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blastPointsContract","outputs":[{"internalType":"contract IBlastPoints","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenContract","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"claimERC20Yield","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimPrimordial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"configStorage","outputs":[{"internalType":"contract IConfigStorage","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"configUpdated","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_schnibbles","type":"uint256"}],"name":"feedPrimordial","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getConfiguredGovernor","outputs":[{"internalType":"address","name":"_governor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_caller","type":"address"}],"name":"getPrimordial","outputs":[{"components":[{"internalType":"uint256","name":"chonks","type":"uint256"},{"internalType":"uint32","name":"createdDate","type":"uint32"},{"internalType":"int8","name":"level","type":"int8"},{"internalType":"bool","name":"hatched","type":"bool"}],"internalType":"struct MunchablesCommonLib.PrimordialData","name":"_primordial","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hatchPrimordialToMunchable","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040908082523461037d5760009061250e8038038091610021828561084a565b83396001600160a01b0391829161003b919081019061086d565b1660018060a01b03198181855416178455845163bcaa0c5560e01b9283825260039360049360038585015260209560249487818781885afa908115610401579089918b91610804575b5016826007541617600755895183815260068782015287818781885afa908115610401579089918b916107e7575b5016826008541617600855895190633caab1db60e21b94858352601f8884015288838881845afa92831561050b5787918c9182956107c8575b5060ff19600b541660ff809615151617600b558d519283809263ff74ad5f60e01b825260258d8301525afa90811561050b578b9161071a575b506003815114610683575b5050508386888a54168b5192838092878252600f8b8301525afa90811561067957899161065c575b5060015488821690838a82168303610532575b5050505086885416895183815260108782015287818781855afa90811561040157908692918b91610515575b50888a6002549216928b83168403610449575b50505050508688541689519083825260128783015287828781845afa9182156104015786929189918c9361042a575b508c519384809288825260138c8301525afa91821561040157918a93918993859261040b575b508a6005549116908b81168203610393575b5050896006549116918a82168303610322575b505050908790541691848a51809481938252600c898301525afa90811561031857918593916001959389916102eb575b508781166102dc575b5087549689519586948593845283015287165afa9182156102d25784926102a5575b505060ff60a01b1990911690151560a01b60ff60a01b1617905551611b74908161099a8239f35b6102c49250803d106102cb575b6102bc818361084a565b81019061088c565b388061027e565b503d6102b2565b85513d86823e3d90fd5b6102e5906108a4565b3861025c565b61030b9150853d8711610311575b610303818361084a565b81019061086d565b38610253565b503d6102f9565b88513d89823e3d90fd5b1681176006558a51631a33757d60e01b8152600288820152928391879183915af180156103895790869161035b575b9081808a93610223565b813d8311610382575b61036e818361084a565b8101031261037d578438610351565b600080fd5b503d610364565b89513d8a823e3d90fd5b831681176005558c51631a33757d60e01b815260028a82015292949193918391899183915af1801561040157918a939189936103d0575b80610210565b9092809294503d83116103fa575b6103e8818361084a565b8101031261037d5788918791386103ca565b503d6103de565b8b513d8c823e3d90fd5b610423919250843d861161031157610303818361084a565b90386101fe565b610442919350823d841161031157610303818361084a565b91386101d8565b83868416176002558d519485809289825260118d8301525afa92831561050b57908b9182946104ec575b508a89541615610487575b508887936101a9565b161790813b156104e85789898782938e5194859384926336b91f2b60e01b84521696878d8401525af1801561040157908a916104d0575b5050818654161785553880898161047e565b6104d990610821565b6104e45788386104be565b8880fd5b8980fd5b6105049194508a3d8c1161031157610303818361084a565b9238610473565b8c513d8d823e3d90fd5b61052c9150893d8b1161031157610303818361084a565b38610196565b1681176001558a516301fd3f7760e71b8152308882015288818881855afa90811561050b578b9161063f575b5061056b575b808361016a565b803b156104e857898091888d5180948193634e606c4760e01b83525af180156104015761062c575b50895163784c3b3d60e11b8882019081528782526001600160401b039291808d0184811182821017610618578d52518b9283929083905af1503d15610612573d908111610600578951906105f0601f8201601f191689018361084a565b815288873d92013e5b3880610564565b634e487b7160e01b8952604186528489fd5b506105f9565b8860418b634e487b7160e01b600052526000fd5b61063890999199610821565b9738610593565b6106569150893d8b116102cb576102bc818361084a565b3861055e565b6106739150873d891161031157610303818361084a565b38610157565b8a513d8b823e3d90fd5b929891999593869b979591989b50865b8b81168a8110156107045785518110156106f257600582901b611fe01686018e015190890b60011901607f198112607f8213176106e057890b8952600c8e52898920556001018b16610693565b634e487b7160e01b8a5260118952878afd5b634e487b7160e01b8952603288528689fd5b505093959950939599965096905038808061012f565b90503d808c833e61072b818361084a565b810189828203126107c45781516001600160401b03928382116107aa570181601f820112156107c05780519283116107ae578d908360051b9151936107728d84018661084a565b84528b808501928201019283116107aa578b809101915b83831061079a575050505038610124565b82518152918101918c9101610789565b8d80fd5b634e487b7160e01b8d5260418a52888dfd5b8c80fd5b8b80fd5b6107e09195508b3d8d116102cb576102bc818361084a565b93386100eb565b6107fe9150893d8b1161031157610303818361084a565b386100b2565b61081b9150893d8b1161031157610303818361084a565b38610084565b6001600160401b03811161083457604052565b634e487b7160e01b600052604160045260246000fd5b601f909101601f19168101906001600160401b0382119082101761083457604052565b9081602091031261037d57516001600160a01b038116810361037d5790565b9081602091031261037d5751801515810361037d5790565b6001600160a01b03908116908115610987578060015416156109835760035481168061093b57503082036108eb575b505b600380546001600160a01b031916919091179055565b60015416803b1561037d5760008091602460405180948193631d70c8d360e31b83528760048401525af1801561092f57156108d35761092990610821565b386108d3565b6040513d6000823e3d90fd5b8091503b1561037d5760008091602460405180948193633a74bfd760e01b83528760048401525af1801561092f57610974575b506108d5565b61097d90610821565b3861096e565b5050565b6040516305d8ce3d60e01b8152600490fdfe608080604052600436101561001357600080fd5b600090813560e01c9081631f883135146116835750806331a0edec1461165c5780633cdad82c14611635578063443b17861461160f5780634b03eeb41461142557806371bf2caa1461128b5780638da52e931461083f578063a790ee0714610743578063ad5c46481461071c578063b930b482146106f5578063f758869d14610246578063fcb33ca6146100d95763fce14af6146100b057600080fd5b346100d657806003193601126100d65760206001600160a01b0360015416604051908152f35b80fd5b50346100d65760406003193601126100d6576100f3611737565b60243580151591828203610242576001600160a01b03906024602083875416604051928380927f6288a66c000000000000000000000000000000000000000000000000000000008252601460048301525afa801561023757839187916101f7575b501633036101cd571691828452600a602052604084209060ff60ff1983541691161790556000146101a6577f447e792e4180e0bf4611501836728a318ed07f7be281231d653a713f3a8f139a8280a280f35b7faedc6caccd8c1052a0bba93e486b89e1fd35955733a99634961edbe181410e468280a280f35b60046040517ff7aa0316000000000000000000000000000000000000000000000000000000008152fd5b9150506020813d60201161022f575b81610213602093836117af565b8101031261022b5761022583916117d2565b38610154565b8580fd5b3d9150610206565b6040513d88823e3d90fd5b8380fd5b50346100d65760206003193601126100d65760ff815460a01c166106cb5760ff600b5416156106a1576004356001600160a01b0361028333611831565b911691828452600a60205260ff604085205416156106775760a0820151600435811061064657508284526009918260205263ffffffff6001604087200154161561061c578385528260205260ff600160408720015460281c166105f257838552826020526040852080549060043582018092116104ad575583855282602052600160408620015460201c850b9285841261045e575b5090915061032a8260a0830151611813565b60a08201526001600160a01b0360075416803b1561045a57604051917f2f2ab36400000000000000000000000000000000000000000000000000000000835284600484015263ffffffff815116602484015263ffffffff602082015116604484015263ffffffff6040820151166064840152606081015160068110156104465792610104818881956001600160a01b0360c08399978498608487015261ffff60808201511660a487015260a081015160c487015201511660e48401525af1801561043b57610423575b505060207f0638bf69e67afb4ffa8828126d19aa2c8f92cdfc90af04a0b2013c74b69f6e8791604051908152a280f35b61042c9061177f565b6104375782386103f3565b8280fd5b6040513d84823e3d90fd5b602487634e487b7160e01b81526021600452fd5b8480fd5b835b610469816117e6565b870b875285600c806020526040892054828a528460205260408a2054101590816105d1575b50806105c5575b156104c15750860b607f81146104ad57600101610460565b602487634e487b7160e01b81526011600452fd5b929394919091838852816020526040882054888052600c602052604089205410610577575b82880b8181036104fd575b50505083929150610318565b7f675cccc913874e554835375ac303a1ca52451c71c3ae2f71e6972e0a924bdddf93604093868b526020526001848b2001907fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff82549160201b64ff0000000016911617905582519182526020820152a282388080806104f1565b9450828752806020526105a661059e6040892054898052600c60205260408a205490611813565b600435611813565b94878052600c60205260408820548489528260205260408920556104e6565b50600182890b12610495565b9150506105dd826117e6565b880b885260205285604088205415153861048e565b60046040517f946d9356000000000000000000000000000000000000000000000000000000008152fd5b60046040517f3598c256000000000000000000000000000000000000000000000000000000008152fd5b602490604051907fa369efb60000000000000000000000000000000000000000000000000000000082526004820152fd5b60046040517fe3a55fcc000000000000000000000000000000000000000000000000000000008152fd5b60046040517f6fa53ae0000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8f85eea2000000000000000000000000000000000000000000000000000000008152fd5b50346100d657806003193601126100d65760206001600160a01b0360025416604051908152f35b50346100d657806003193601126100d65760206001600160a01b0360065416604051908152f35b50346100d657806003193601126100d65760ff815460a01c166106cb5760ff600b5416156106a1576001600160a01b0361077c33611831565b5016808252600a60205260ff6040832054161561067757808252600960205263ffffffff8060016040852001541661081557818352600960205264fd00000000600160408520019142167fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000835416171790557f8855e4f63b4806f0255129155e1f6c09a4574dcba1a47efc5ea2b8eb1ee2c9998280a280f35b60046040517fbdf758ec000000000000000000000000000000000000000000000000000000008152fd5b50346100d657806003193601126100d6576001600160a01b038082541690813303611261576040517fbcaa0c5500000000000000000000000000000000000000000000000000000000808252600393600360048401528560209360249685828981875afa91821561105657839261122a575b50867fffffffffffffffffffffffff000000000000000000000000000000000000000092168260075416176007556040518581526006600482015286818a81885afa8015610b7c57889185916111f2575b5016826008541617600855604051907ff2aac76c0000000000000000000000000000000000000000000000000000000094858352601f600484015287838b81845afa928315610e46578a91869182956111d3575b5060ff19600b541660ff809615151617600b55604051928380927fff74ad5f000000000000000000000000000000000000000000000000000000008252602560048301525afa908115610e46578591611115575b506003815114611061575b50505086858784541660405192838092898252600f60048301525afa908115611056578391611021575b5060015483888316918981168303610e88575b50546040518781526010600482015292508816905086828a81845afa918215610b7c578492610e51575b508887896002549416928a85168403610d51575b50505050508582541690604051918583526012600484015286838a81845afa928315610b7c57899188918695610d18575b50604051928380928a8252601360048301525afa908115610b7c57879385918293610cdd575b50896005549116908a81168203610c58575b505050876006549116918882168303610bcc575b50505090859054169286604051809581938252600c60048301525afa80156102375783928791610b96575b50848116610b87575b508554946040518095819382526001600483015287165afa8015610b7c577fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9274ff0000000000000000000000000000000000000000928692610b4f575b5050151560a01b16911617815580f35b610b6e9250803d10610b75575b610b6681836117af565b8101906119d2565b3880610b3f565b503d610b5c565b6040513d86823e3d90fd5b610b90906119ea565b38610ae1565b83819492503d8311610bc5575b610bad81836117af565b8101031261022b57610bbf83926117d2565b38610ad8565b503d610ba3565b8291161760065587604051809481937f1a33757d000000000000000000000000000000000000000000000000000000008352600260048401525af1908115610c4d578491610c1f575b9081808993610aad565b813d8311610c46575b610c3281836117af565b81010312610c41578238610c15565b600080fd5b503d610c28565b6040513d89823e3d90fd5b841681176005556040517f1a33757d00000000000000000000000000000000000000000000000000000000815260026004820152949185918c9183915af1928315610b7c578793610cac575b808591610a99565b9092809294503d8311610cd6575b610cc481836117af565b81010312610c41578791859138610ca4565b503d610cba565b94859193508092503d8311610d11575b610cf781836117af565b810103126102425783610d0a88946117d2565b9138610a87565b503d610ced565b9250935081813d8311610d4a575b610d3081836117af565b810103126102425786610d438a926117d2565b9338610a61565b503d610d26565b8386861617600255604051928380928b8252601160048301525afa928315610e465785918294610e0c575b50896004541615610d92575b8a91899150610a30565b161790813b156102425783888a829360405194859384927f36b91f2b00000000000000000000000000000000000000000000000000000000845216968760048401525af1908115610b7c578491610df8575b505081600454161760045538808381610d88565b610e019061177f565b610437578238610de4565b89809295508193503d8311610e3f575b610e2681836117af565b8101031261045a57610e3885916117d2565b9238610d7c565b503d610e1c565b6040513d87823e3d90fd5b9091508681813d8311610e81575b610e6981836117af565b8101031261024257610e7a906117d2565b9038610a1c565b503d610e5f565b828582161760015516176040517ffe9fbb8000000000000000000000000000000000000000000000000000000000815230600482015287818b81855afa908115610e46578591611004575b50610ee0575b83816109f2565b80939192933b15611000578180916004604051809481937f4e606c470000000000000000000000000000000000000000000000000000000083525af1801561043b57610fe8575b5050604051908582017ff098767a00000000000000000000000000000000000000000000000000000000815260048352604083019267ffffffffffffffff9381811085821117610fd357604052518a9283929083905af150873d15610fcb57503d908111610fb857604051889291610fa8601f8201601f19168801836117af565b815282863d92013e5b3880610ed9565b8688634e487b7160e01b81526041600452fd5b919050610fb1565b8a634e487b7160e01b60005260416004526000fd5b610ff19061177f565b610ffc578738610f27565b8780fd5b5080fd5b61101b9150883d8a11610b7557610b6681836117af565b38610ed3565b90508581813d831161104f575b61103881836117af565b8101031261043757611049906117d2565b386109df565b503d61102e565b6040513d85823e3d90fd5b939894909695919897929750895b8981168b89821015611102575085518110156110ef577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe88611fe08460051b1688010151918d0b01607f8113607f198212176110dc578c0b8c52600c885260408c2055600101891661106f565b878d634e487b7160e01b81526011600452fd5b868c634e487b7160e01b81526032600452fd5b95505050939750939450943880806109b5565b9192939450503d808b833e61112a81836117af565b810187828203126111cf57815167ffffffffffffffff928382116111b4570181601f820112156111cb5780519283116111b8578260051b90604051936111728b8401866117af565b845289808501928201019283116111b4579089808e98979695949301915b8383106111a15750505050386109aa565b825181528e9850918101918b9101611190565b8c80fd5b8a8c634e487b7160e01b81526041600452fd5b8b80fd5b8a80fd5b6111eb9195508a3d8c11610b7557610b6681836117af565b9338610956565b809250888092503d8311611223575b61120b81836117af565b810103126102425761121d88916117d2565b38610902565b503d611201565b9091508581813d831161125a575b61124281836117af565b8101031261043757611253906117d2565b90386108b1565b503d611238565b60046040517fe1010280000000000000000000000000000000000000000000000000000000008152fd5b50346100d657806003193601126100d65760ff815460a01c166106cb576112b133611831565b50906001600160a01b03809216918282526020600a815260ff60408420541615610677578383526009815260ff600160408520015460281c166105f2578383526009815263ffffffff6001604085200154161561061c5783835260098152826001604082200154821c810b126113fb578383526009815260ff600160408520015460281c166105f2576009908484525260016040832001650100000000007fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff82541617905560085416803b15611000578180916024604051809481937fe2bc1f930000000000000000000000000000000000000000000000000000000083528860048401525af1801561043b576113ec575b50907f2f4e3d361e58a7337f213065f8392a6465664cd78942b4be342f7ee6bdfbe38b8280a280f35b6113f59061177f565b386113c3565b60046040517f19c4ba24000000000000000000000000000000000000000000000000000000008152fd5b50346100d65760406003193601126100d65761143f611737565b6001600160a01b039081835416604051927fbcaa0c5500000000000000000000000000000000000000000000000000000000808552600c60048601526020948581602481875afa8015610c4d57839188916115d3575b501680156115a25733036115785784906024604051809581938252600c60048301525afa8015610e465784928691611540575b50604490868360405196879586947faad3ec960000000000000000000000000000000000000000000000000000000086521660048501526024356024850152165af1801561105657611518578280f35b813d8311611539575b61152b81836117af565b810103126100d65738808280f35b503d611521565b83819492503d8311611571575b61155781836117af565b8101031261045a57604461156b85936117d2565b906114c8565b503d61154d565b60046040517f1a48f084000000000000000000000000000000000000000000000000000000008152fd5b60246040517f92bc2cd0000000000000000000000000000000000000000000000000000000008152600c6004820152fd5b809250878092503d8311611608575b6115ec81836117af565b81010312611604576115fe83916117d2565b38611495565b8680fd5b503d6115e2565b50346100d657806003193601126100d6576001600160a01b036020915416604051908152f35b50346100d657806003193601126100d65760206001600160a01b0360035416604051908152f35b50346100d657806003193601126100d65760206001600160a01b0360055416604051908152f35b82346100d657602080600319360112611000576001600160a01b036116ce6080948460606116af611737565b926116b98161174d565b82815282878201528260408201520152611831565b501682526009815260408220916040516116e78161174d565b600184549485835201549263ffffffff818301818616815260ff6060604086019588861c880b8752019660281c161515865260405196875251169085015251900b60408301525115156060820152f35b600435906001600160a01b0382168203610c4157565b6080810190811067ffffffffffffffff82111761176957604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff811161176957604052565b60e0810190811067ffffffffffffffff82111761176957604052565b90601f601f19910116810190811067ffffffffffffffff82111761176957604052565b51906001600160a01b0382168203610c4157565b60000b60010190607f8213607f198312176117fd57565b634e487b7160e01b600052601160045260246000fd5b919082039182116117fd57565b519063ffffffff82168203610c4157565b60c0916040805161184181611793565b600094818680935282602082015282848201528260608201528260808201528260a082015201526001600160a01b0393846007541682519586957f5c12cd4b0000000000000000000000000000000000000000000000000000000087521660048601528460246101009788935afa9485156119c657819482966118fd575b50505063ffffffff8493945116156118d45750565b600490517f3e3a049f000000000000000000000000000000000000000000000000000000008152fd5b91945091945080823d84116119bf575b61191781836117af565b8101039182126102425760e0601f1961192f836117d2565b9301126102425784519361194285611793565b61194e60208301611820565b855261195b868301611820565b602086015261196c60608301611820565b868601526080820151600681101561100057606086015260a08201519061ffff821682036100d65750608085015260c081015160a08501526119b09060e0016117d2565b60c084015291923880806118bf565b503d61190d565b509051903d90823e3d90fd5b90816020910312610c4157518015158103610c415790565b6001600160a01b03809116908115611b1457806001541615611b1057600354811680611aaf5750308203611a46575b505b7fffffffffffffffffffffffff00000000000000000000000000000000000000006003541617600355565b60015416803b15610c4157600080916024604051809481937feb8646980000000000000000000000000000000000000000000000000000000083528760048401525af18015611aa35715611a1957611a9d9061177f565b38611a19565b6040513d6000823e3d90fd5b8091503b15610c4157600080916024604051809481937f3a74bfd70000000000000000000000000000000000000000000000000000000083528760048401525af18015611aa357611b01575b50611a1b565b611b0a9061177f565b38611afb565b5050565b60046040517f05d8ce3d000000000000000000000000000000000000000000000000000000008152fdfea2646970667358221220a866753fa3ff118560773bb23b5142a987b5efbaa3d71ef256fceea758a563a164736f6c63430008190033000000000000000000000000ef173bb4b36525974bf6711357d2c6c12b8001ec
Deployed Bytecode
0x608080604052600436101561001357600080fd5b600090813560e01c9081631f883135146116835750806331a0edec1461165c5780633cdad82c14611635578063443b17861461160f5780634b03eeb41461142557806371bf2caa1461128b5780638da52e931461083f578063a790ee0714610743578063ad5c46481461071c578063b930b482146106f5578063f758869d14610246578063fcb33ca6146100d95763fce14af6146100b057600080fd5b346100d657806003193601126100d65760206001600160a01b0360015416604051908152f35b80fd5b50346100d65760406003193601126100d6576100f3611737565b60243580151591828203610242576001600160a01b03906024602083875416604051928380927f6288a66c000000000000000000000000000000000000000000000000000000008252601460048301525afa801561023757839187916101f7575b501633036101cd571691828452600a602052604084209060ff60ff1983541691161790556000146101a6577f447e792e4180e0bf4611501836728a318ed07f7be281231d653a713f3a8f139a8280a280f35b7faedc6caccd8c1052a0bba93e486b89e1fd35955733a99634961edbe181410e468280a280f35b60046040517ff7aa0316000000000000000000000000000000000000000000000000000000008152fd5b9150506020813d60201161022f575b81610213602093836117af565b8101031261022b5761022583916117d2565b38610154565b8580fd5b3d9150610206565b6040513d88823e3d90fd5b8380fd5b50346100d65760206003193601126100d65760ff815460a01c166106cb5760ff600b5416156106a1576004356001600160a01b0361028333611831565b911691828452600a60205260ff604085205416156106775760a0820151600435811061064657508284526009918260205263ffffffff6001604087200154161561061c578385528260205260ff600160408720015460281c166105f257838552826020526040852080549060043582018092116104ad575583855282602052600160408620015460201c850b9285841261045e575b5090915061032a8260a0830151611813565b60a08201526001600160a01b0360075416803b1561045a57604051917f2f2ab36400000000000000000000000000000000000000000000000000000000835284600484015263ffffffff815116602484015263ffffffff602082015116604484015263ffffffff6040820151166064840152606081015160068110156104465792610104818881956001600160a01b0360c08399978498608487015261ffff60808201511660a487015260a081015160c487015201511660e48401525af1801561043b57610423575b505060207f0638bf69e67afb4ffa8828126d19aa2c8f92cdfc90af04a0b2013c74b69f6e8791604051908152a280f35b61042c9061177f565b6104375782386103f3565b8280fd5b6040513d84823e3d90fd5b602487634e487b7160e01b81526021600452fd5b8480fd5b835b610469816117e6565b870b875285600c806020526040892054828a528460205260408a2054101590816105d1575b50806105c5575b156104c15750860b607f81146104ad57600101610460565b602487634e487b7160e01b81526011600452fd5b929394919091838852816020526040882054888052600c602052604089205410610577575b82880b8181036104fd575b50505083929150610318565b7f675cccc913874e554835375ac303a1ca52451c71c3ae2f71e6972e0a924bdddf93604093868b526020526001848b2001907fffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffff82549160201b64ff0000000016911617905582519182526020820152a282388080806104f1565b9450828752806020526105a661059e6040892054898052600c60205260408a205490611813565b600435611813565b94878052600c60205260408820548489528260205260408920556104e6565b50600182890b12610495565b9150506105dd826117e6565b880b885260205285604088205415153861048e565b60046040517f946d9356000000000000000000000000000000000000000000000000000000008152fd5b60046040517f3598c256000000000000000000000000000000000000000000000000000000008152fd5b602490604051907fa369efb60000000000000000000000000000000000000000000000000000000082526004820152fd5b60046040517fe3a55fcc000000000000000000000000000000000000000000000000000000008152fd5b60046040517f6fa53ae0000000000000000000000000000000000000000000000000000000008152fd5b60046040517f8f85eea2000000000000000000000000000000000000000000000000000000008152fd5b50346100d657806003193601126100d65760206001600160a01b0360025416604051908152f35b50346100d657806003193601126100d65760206001600160a01b0360065416604051908152f35b50346100d657806003193601126100d65760ff815460a01c166106cb5760ff600b5416156106a1576001600160a01b0361077c33611831565b5016808252600a60205260ff6040832054161561067757808252600960205263ffffffff8060016040852001541661081557818352600960205264fd00000000600160408520019142167fffffffffffffffffffffffffffffffffffffffffffffffffffffff0000000000835416171790557f8855e4f63b4806f0255129155e1f6c09a4574dcba1a47efc5ea2b8eb1ee2c9998280a280f35b60046040517fbdf758ec000000000000000000000000000000000000000000000000000000008152fd5b50346100d657806003193601126100d6576001600160a01b038082541690813303611261576040517fbcaa0c5500000000000000000000000000000000000000000000000000000000808252600393600360048401528560209360249685828981875afa91821561105657839261122a575b50867fffffffffffffffffffffffff000000000000000000000000000000000000000092168260075416176007556040518581526006600482015286818a81885afa8015610b7c57889185916111f2575b5016826008541617600855604051907ff2aac76c0000000000000000000000000000000000000000000000000000000094858352601f600484015287838b81845afa928315610e46578a91869182956111d3575b5060ff19600b541660ff809615151617600b55604051928380927fff74ad5f000000000000000000000000000000000000000000000000000000008252602560048301525afa908115610e46578591611115575b506003815114611061575b50505086858784541660405192838092898252600f60048301525afa908115611056578391611021575b5060015483888316918981168303610e88575b50546040518781526010600482015292508816905086828a81845afa918215610b7c578492610e51575b508887896002549416928a85168403610d51575b50505050508582541690604051918583526012600484015286838a81845afa928315610b7c57899188918695610d18575b50604051928380928a8252601360048301525afa908115610b7c57879385918293610cdd575b50896005549116908a81168203610c58575b505050876006549116918882168303610bcc575b50505090859054169286604051809581938252600c60048301525afa80156102375783928791610b96575b50848116610b87575b508554946040518095819382526001600483015287165afa8015610b7c577fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff9274ff0000000000000000000000000000000000000000928692610b4f575b5050151560a01b16911617815580f35b610b6e9250803d10610b75575b610b6681836117af565b8101906119d2565b3880610b3f565b503d610b5c565b6040513d86823e3d90fd5b610b90906119ea565b38610ae1565b83819492503d8311610bc5575b610bad81836117af565b8101031261022b57610bbf83926117d2565b38610ad8565b503d610ba3565b8291161760065587604051809481937f1a33757d000000000000000000000000000000000000000000000000000000008352600260048401525af1908115610c4d578491610c1f575b9081808993610aad565b813d8311610c46575b610c3281836117af565b81010312610c41578238610c15565b600080fd5b503d610c28565b6040513d89823e3d90fd5b841681176005556040517f1a33757d00000000000000000000000000000000000000000000000000000000815260026004820152949185918c9183915af1928315610b7c578793610cac575b808591610a99565b9092809294503d8311610cd6575b610cc481836117af565b81010312610c41578791859138610ca4565b503d610cba565b94859193508092503d8311610d11575b610cf781836117af565b810103126102425783610d0a88946117d2565b9138610a87565b503d610ced565b9250935081813d8311610d4a575b610d3081836117af565b810103126102425786610d438a926117d2565b9338610a61565b503d610d26565b8386861617600255604051928380928b8252601160048301525afa928315610e465785918294610e0c575b50896004541615610d92575b8a91899150610a30565b161790813b156102425783888a829360405194859384927f36b91f2b00000000000000000000000000000000000000000000000000000000845216968760048401525af1908115610b7c578491610df8575b505081600454161760045538808381610d88565b610e019061177f565b610437578238610de4565b89809295508193503d8311610e3f575b610e2681836117af565b8101031261045a57610e3885916117d2565b9238610d7c565b503d610e1c565b6040513d87823e3d90fd5b9091508681813d8311610e81575b610e6981836117af565b8101031261024257610e7a906117d2565b9038610a1c565b503d610e5f565b828582161760015516176040517ffe9fbb8000000000000000000000000000000000000000000000000000000000815230600482015287818b81855afa908115610e46578591611004575b50610ee0575b83816109f2565b80939192933b15611000578180916004604051809481937f4e606c470000000000000000000000000000000000000000000000000000000083525af1801561043b57610fe8575b5050604051908582017ff098767a00000000000000000000000000000000000000000000000000000000815260048352604083019267ffffffffffffffff9381811085821117610fd357604052518a9283929083905af150873d15610fcb57503d908111610fb857604051889291610fa8601f8201601f19168801836117af565b815282863d92013e5b3880610ed9565b8688634e487b7160e01b81526041600452fd5b919050610fb1565b8a634e487b7160e01b60005260416004526000fd5b610ff19061177f565b610ffc578738610f27565b8780fd5b5080fd5b61101b9150883d8a11610b7557610b6681836117af565b38610ed3565b90508581813d831161104f575b61103881836117af565b8101031261043757611049906117d2565b386109df565b503d61102e565b6040513d85823e3d90fd5b939894909695919897929750895b8981168b89821015611102575085518110156110ef577ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe88611fe08460051b1688010151918d0b01607f8113607f198212176110dc578c0b8c52600c885260408c2055600101891661106f565b878d634e487b7160e01b81526011600452fd5b868c634e487b7160e01b81526032600452fd5b95505050939750939450943880806109b5565b9192939450503d808b833e61112a81836117af565b810187828203126111cf57815167ffffffffffffffff928382116111b4570181601f820112156111cb5780519283116111b8578260051b90604051936111728b8401866117af565b845289808501928201019283116111b4579089808e98979695949301915b8383106111a15750505050386109aa565b825181528e9850918101918b9101611190565b8c80fd5b8a8c634e487b7160e01b81526041600452fd5b8b80fd5b8a80fd5b6111eb9195508a3d8c11610b7557610b6681836117af565b9338610956565b809250888092503d8311611223575b61120b81836117af565b810103126102425761121d88916117d2565b38610902565b503d611201565b9091508581813d831161125a575b61124281836117af565b8101031261043757611253906117d2565b90386108b1565b503d611238565b60046040517fe1010280000000000000000000000000000000000000000000000000000000008152fd5b50346100d657806003193601126100d65760ff815460a01c166106cb576112b133611831565b50906001600160a01b03809216918282526020600a815260ff60408420541615610677578383526009815260ff600160408520015460281c166105f2578383526009815263ffffffff6001604085200154161561061c5783835260098152826001604082200154821c810b126113fb578383526009815260ff600160408520015460281c166105f2576009908484525260016040832001650100000000007fffffffffffffffffffffffffffffffffffffffffffffffffffff00ffffffffff82541617905560085416803b15611000578180916024604051809481937fe2bc1f930000000000000000000000000000000000000000000000000000000083528860048401525af1801561043b576113ec575b50907f2f4e3d361e58a7337f213065f8392a6465664cd78942b4be342f7ee6bdfbe38b8280a280f35b6113f59061177f565b386113c3565b60046040517f19c4ba24000000000000000000000000000000000000000000000000000000008152fd5b50346100d65760406003193601126100d65761143f611737565b6001600160a01b039081835416604051927fbcaa0c5500000000000000000000000000000000000000000000000000000000808552600c60048601526020948581602481875afa8015610c4d57839188916115d3575b501680156115a25733036115785784906024604051809581938252600c60048301525afa8015610e465784928691611540575b50604490868360405196879586947faad3ec960000000000000000000000000000000000000000000000000000000086521660048501526024356024850152165af1801561105657611518578280f35b813d8311611539575b61152b81836117af565b810103126100d65738808280f35b503d611521565b83819492503d8311611571575b61155781836117af565b8101031261045a57604461156b85936117d2565b906114c8565b503d61154d565b60046040517f1a48f084000000000000000000000000000000000000000000000000000000008152fd5b60246040517f92bc2cd0000000000000000000000000000000000000000000000000000000008152600c6004820152fd5b809250878092503d8311611608575b6115ec81836117af565b81010312611604576115fe83916117d2565b38611495565b8680fd5b503d6115e2565b50346100d657806003193601126100d6576001600160a01b036020915416604051908152f35b50346100d657806003193601126100d65760206001600160a01b0360035416604051908152f35b50346100d657806003193601126100d65760206001600160a01b0360055416604051908152f35b82346100d657602080600319360112611000576001600160a01b036116ce6080948460606116af611737565b926116b98161174d565b82815282878201528260408201520152611831565b501682526009815260408220916040516116e78161174d565b600184549485835201549263ffffffff818301818616815260ff6060604086019588861c880b8752019660281c161515865260405196875251169085015251900b60408301525115156060820152f35b600435906001600160a01b0382168203610c4157565b6080810190811067ffffffffffffffff82111761176957604052565b634e487b7160e01b600052604160045260246000fd5b67ffffffffffffffff811161176957604052565b60e0810190811067ffffffffffffffff82111761176957604052565b90601f601f19910116810190811067ffffffffffffffff82111761176957604052565b51906001600160a01b0382168203610c4157565b60000b60010190607f8213607f198312176117fd57565b634e487b7160e01b600052601160045260246000fd5b919082039182116117fd57565b519063ffffffff82168203610c4157565b60c0916040805161184181611793565b600094818680935282602082015282848201528260608201528260808201528260a082015201526001600160a01b0393846007541682519586957f5c12cd4b0000000000000000000000000000000000000000000000000000000087521660048601528460246101009788935afa9485156119c657819482966118fd575b50505063ffffffff8493945116156118d45750565b600490517f3e3a049f000000000000000000000000000000000000000000000000000000008152fd5b91945091945080823d84116119bf575b61191781836117af565b8101039182126102425760e0601f1961192f836117d2565b9301126102425784519361194285611793565b61194e60208301611820565b855261195b868301611820565b602086015261196c60608301611820565b868601526080820151600681101561100057606086015260a08201519061ffff821682036100d65750608085015260c081015160a08501526119b09060e0016117d2565b60c084015291923880806118bf565b503d61190d565b509051903d90823e3d90fd5b90816020910312610c4157518015158103610c415790565b6001600160a01b03809116908115611b1457806001541615611b1057600354811680611aaf5750308203611a46575b505b7fffffffffffffffffffffffff00000000000000000000000000000000000000006003541617600355565b60015416803b15610c4157600080916024604051809481937feb8646980000000000000000000000000000000000000000000000000000000083528760048401525af18015611aa35715611a1957611a9d9061177f565b38611a19565b6040513d6000823e3d90fd5b8091503b15610c4157600080916024604051809481937f3a74bfd70000000000000000000000000000000000000000000000000000000083528760048401525af18015611aa357611b01575b50611a1b565b611b0a9061177f565b38611afb565b5050565b60046040517f05d8ce3d000000000000000000000000000000000000000000000000000000008152fdfea2646970667358221220a866753fa3ff118560773bb23b5142a987b5efbaa3d71ef256fceea758a563a164736f6c63430008190033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ef173bb4b36525974bf6711357d2c6c12b8001ec
-----Decoded View---------------
Arg [0] : _configStorage (address): 0xEf173BB4b36525974BF6711357D2c6C12b8001eC
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000ef173bb4b36525974bf6711357d2c6c12b8001ec
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.