Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 28709945 | 41 days ago | 0 ETH | |||||
| 28709945 | 41 days ago | 0 ETH | |||||
| 28709945 | 41 days ago | 0 ETH | |||||
| 28709945 | 41 days ago | 0 ETH | |||||
| 28709945 | 41 days ago | 0 ETH | |||||
| 25330277 | 119 days ago | 0 ETH | |||||
| 25330277 | 119 days ago | 0 ETH | |||||
| 25330277 | 119 days ago | 0 ETH | |||||
| 25330277 | 119 days ago | 0 ETH | |||||
| 25330277 | 119 days ago | 0 ETH | |||||
| 25330277 | 119 days ago | 0 ETH | |||||
| 25330277 | 119 days ago | 0 ETH | |||||
| 25330277 | 119 days ago | 0 ETH | |||||
| 25330277 | 119 days ago | 0 ETH | |||||
| 25330277 | 119 days ago | 0 ETH | |||||
| 20603578 | 229 days ago | 0 ETH | |||||
| 20603578 | 229 days ago | 0 ETH | |||||
| 20603578 | 229 days ago | 0 ETH | |||||
| 20603578 | 229 days ago | 0 ETH | |||||
| 20603578 | 229 days ago | 0 ETH | |||||
| 20218205 | 237 days ago | 0 ETH | |||||
| 20218205 | 237 days ago | 0 ETH | |||||
| 20218205 | 237 days ago | 0 ETH | |||||
| 20218205 | 237 days ago | 0 ETH | |||||
| 20218205 | 237 days ago | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
BonusManager
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 "openzeppelin-contracts/contracts/token/ERC721/IERC721.sol";
import "../interfaces/IAccountManager.sol";
import "../interfaces/IBonusManager.sol";
import "../interfaces/ILockManager.sol";
import "../interfaces/IMigrationManager.sol";
import "../interfaces/INFTAttributesManager.sol";
import "./BaseBlastManager.sol";
import "../interfaces/ISnuggeryManager.sol";
import "../interfaces/IMunchadexManager.sol";
// All bonuses denominated in 1e18 (1e18 is a 100% bonus so 30e16 is a 30% bonus)
contract BonusManager is IBonusManager, BaseBlastManager {
ILockManager _lockManager;
IMigrationManager _migrationManager;
INFTAttributesManager _nftAttributesManager;
IAccountManager _accountManager;
IMunchadexManager _munchadexManager;
uint256 public referralBonus;
int16[] public realmBonuses;
uint8[] public rarityBonuses;
uint8[] public munchablesPerRealm;
uint8[] public munchablesPerRarity;
uint8[] public raritySetBonuses;
uint8 public totalMunchables;
uint256 minETHPetBonus;
uint256 maxETHPetBonus;
uint256 petBonusDivisor;
uint256 migrationBonus;
uint256 migrationBonusEndTime;
constructor(address _configStorage) {
__BaseConfigStorage_setConfigStorage(_configStorage);
_reconfigure();
}
function _reconfigure() internal {
_migrationManager = IMigrationManager(
configStorage.getAddress(StorageKey.MigrationManager)
);
_lockManager = ILockManager(
configStorage.getAddress(StorageKey.LockManager)
);
_nftAttributesManager = INFTAttributesManager(
configStorage.getAddress(StorageKey.NFTAttributesManager)
);
_accountManager = IAccountManager(
configStorage.getAddress(StorageKey.AccountManager)
);
_munchadexManager = IMunchadexManager(
configStorage.getAddress(StorageKey.MunchadexManager)
);
referralBonus = configStorage.getUint(StorageKey.ReferralBonus);
realmBonuses = configStorage.getSmallIntArray(StorageKey.RealmBonuses);
rarityBonuses = configStorage.getSmallUintArray(
StorageKey.RarityBonuses
);
totalMunchables = uint8(
configStorage.getUint(StorageKey.TotalMunchables)
);
munchablesPerRealm = configStorage.getSmallUintArray(
StorageKey.MunchablesPerRealm
);
munchablesPerRarity = configStorage.getSmallUintArray(
StorageKey.MunchablesPerRarity
);
raritySetBonuses = configStorage.getSmallUintArray(
StorageKey.RaritySetBonuses
);
minETHPetBonus = configStorage.getUint(StorageKey.MinETHPetBonus);
maxETHPetBonus = configStorage.getUint(StorageKey.MaxETHPetBonus);
petBonusDivisor = configStorage.getUint(StorageKey.PetBonusMultiplier);
migrationBonus = configStorage.getUint(StorageKey.MigrationBonus);
migrationBonusEndTime = configStorage.getUint(
StorageKey.MigrationBonusEndTime
);
super.__BaseBlastManager_reconfigure();
}
function configUpdated() external override onlyConfigStorage {
_reconfigure();
}
function getFeedBonus(
address _caller,
uint256 _tokenId
) external view override returns (int256) {
// Calculate bonuses for snuggery realm and rarity
MunchablesCommonLib.NFTImmutableAttributes
memory immutableAttributes = _nftAttributesManager
.getImmutableAttributes(_tokenId);
(, MunchablesCommonLib.Player memory player) = _accountManager
.getPlayer(_caller);
if (uint256(immutableAttributes.rarity) >= rarityBonuses.length)
revert InvalidRarityError(uint256(immutableAttributes.rarity));
uint8 rarityBonus = uint8(
rarityBonuses[uint256(immutableAttributes.rarity)]
);
uint256 realmIndex = (uint256(immutableAttributes.realm) * 5) +
uint256(player.snuggeryRealm);
if (realmIndex >= realmBonuses.length)
revert InvalidRealmBonus(realmIndex);
int8 realmBonus = int8(realmBonuses[realmIndex]);
int16 sumBonuses = int16(realmBonus) + int16(int8(rarityBonus));
int256 finalBonus = int256(1e16) * int256(sumBonuses);
finalBonus = finalBonus < -20e16 ? int256(-20e16) : finalBonus;
finalBonus = finalBonus > 100e16 ? int256(100e16) : finalBonus;
return finalBonus;
}
function getHarvestBonus(
address _caller
) external view override returns (uint256) {
uint256 weightedValue = _lockManager.getLockedWeightedValue(_caller);
ILockManager.PlayerSettings memory _settings = _lockManager
.getPlayerSettings(_caller);
uint256 _migrationBonus;
if (block.timestamp < migrationBonusEndTime) {
_migrationBonus = _calculateMigrationBonus(_caller, weightedValue);
}
return
_calculateLockBonus(_settings.lockDuration) +
_migrationBonus +
_calculateLevelBonus(_caller) +
_calculateMunchadexBonus(_caller);
}
function getPetBonus(
address _petter
) external view override returns (uint256) {
ILockManager.PlayerSettings memory _settings = _lockManager
.getPlayerSettings(_petter);
return _calculateLockBonus(_settings.lockDuration);
}
function _calculateLockBonus(
uint32 lockDuration
) internal pure returns (uint256 _lockBonusPercent) {
uint256 _daysStaked = lockDuration / 1 days;
if (_daysStaked >= 30) {
uint256 bonus4Pct = (1e16 * 4 * (_daysStaked - 30)) / 15;
uint256 bonus14Pct = (1e16 * 14 * (_daysStaked - 30)) / 60;
_lockBonusPercent = bonus4Pct + bonus14Pct;
}
}
// TODO: Do we want to expose these for front-end?
function _calculateMigrationBonus(
address _caller,
uint256 weightedValue
) internal view returns (uint256 _migrationBonus) {
(
bool didMigrate,
IMigrationManager.MigrationTotals memory totals
) = _migrationManager.getUserMigrationCompletedData(_caller);
ILockManager.ConfiguredToken memory configuredToken = _lockManager
.getConfiguredToken(totals.tokenLocked);
if (didMigrate) {
// Change to double original amount
uint256 usdPrice = configuredToken.usdPrice;
uint256 migrateHighestAmount = (2 *
totals.totalLockedAmount *
usdPrice) / 1e18;
uint256 halfAmount = ((totals.totalLockedAmount * usdPrice) /
1e18) / 2;
if (weightedValue >= migrateHighestAmount) {
// Full bonus
_migrationBonus = migrationBonus;
} else if (weightedValue >= halfAmount) {
// Calculate bonus from delta
_migrationBonus =
(migrationBonus * (weightedValue - halfAmount)) /
(migrateHighestAmount - halfAmount);
}
}
}
function _calculateLevelBonus(
address _caller
) internal view returns (uint256 _levelBonus) {
(
,
MunchablesCommonLib.Player memory player,
MunchablesCommonLib.SnuggeryNFT[] memory _snuggery
) = _accountManager.getFullPlayerData(_caller);
uint256 _snuggerySize = _snuggery.length;
if (_snuggerySize > 0) {
uint i;
for (; i < _snuggerySize; i++) {
_levelBonus += _nftAttributesManager
.getAttributes(_snuggery[i].tokenId)
.level;
}
_levelBonus *= 1e16;
_levelBonus /= (_snuggerySize * 2);
_levelBonus += _snuggerySize == player.maxSnuggerySize ? 3e16 : 0;
}
}
function _calculateMunchadexBonus(
address _caller
) internal view returns (uint256 _munchadexBonus) {
(
uint256[] memory numMunchablesPerRealm,
uint256[] memory numMunchablesPerRarity,
uint256 numUnique
) = _munchadexManager.getMunchadexInfo(_caller);
if (numUnique == 125) {
_munchadexBonus += 100;
} else {
uint8 i;
bool perRealmUnique = true;
bool perRealmGreaterThan6 = true;
for (
;
i < numMunchablesPerRealm.length &&
i < munchablesPerRealm.length;
i++
) {
if (numMunchablesPerRealm[i] < 6) {
perRealmGreaterThan6 = false;
if (numMunchablesPerRealm[i] == 0) {
perRealmUnique = false;
}
} else if (numMunchablesPerRealm[i] == munchablesPerRealm[i]) {
_munchadexBonus += 3;
}
}
if (perRealmUnique && perRealmGreaterThan6) {
_munchadexBonus += 2;
} else if (perRealmUnique) {
_munchadexBonus += 1;
}
i = 0;
for (
;
i < numMunchablesPerRarity.length &&
i < munchablesPerRarity.length;
i++
) {
if (numMunchablesPerRarity[i] == munchablesPerRarity[i])
_munchadexBonus += raritySetBonuses[i];
}
}
_munchadexBonus *= 1e16;
}
function getReferralBonus() external view override returns (uint256) {
return referralBonus * 1e16;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)
pragma solidity ^0.8.20;
import {IERC165} from "../../utils/introspection/IERC165.sol";
/**
* @dev Required interface of an ERC721 compliant contract.
*/
interface IERC721 is IERC165 {
/**
* @dev Emitted when `tokenId` token is transferred from `from` to `to`.
*/
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
*/
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
/**
* @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
*/
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
/**
* @dev Returns the number of tokens in ``owner``'s account.
*/
function balanceOf(address owner) external view returns (uint256 balance);
/**
* @dev Returns the owner of the `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function ownerOf(uint256 tokenId) external view returns (address owner);
/**
* @dev Safely transfers `tokenId` token from `from` to `to`.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external;
/**
* @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
* are aware of the ERC721 protocol to prevent tokens from being forever locked.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must exist and be owned by `from`.
* - If the caller is not `from`, it must have been allowed to move this token by either {approve} or
* {setApprovalForAll}.
* - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon
* a safe transfer.
*
* Emits a {Transfer} event.
*/
function safeTransferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Transfers `tokenId` token from `from` to `to`.
*
* WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
* or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
* understand this adds an external call which potentially creates a reentrancy vulnerability.
*
* Requirements:
*
* - `from` cannot be the zero address.
* - `to` cannot be the zero address.
* - `tokenId` token must be owned by `from`.
* - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
*
* Emits a {Transfer} event.
*/
function transferFrom(address from, address to, uint256 tokenId) external;
/**
* @dev Gives permission to `to` to transfer `tokenId` token to another account.
* The approval is cleared when the token is transferred.
*
* Only a single account can be approved at a time, so approving the zero address clears previous approvals.
*
* Requirements:
*
* - The caller must own the token or be an approved operator.
* - `tokenId` must exist.
*
* Emits an {Approval} event.
*/
function approve(address to, uint256 tokenId) external;
/**
* @dev Approve or remove `operator` as an operator for the caller.
* Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
*
* Requirements:
*
* - The `operator` cannot be the address zero.
*
* Emits an {ApprovalForAll} event.
*/
function setApprovalForAll(address operator, bool approved) external;
/**
* @dev Returns the account approved for `tokenId` token.
*
* Requirements:
*
* - `tokenId` must exist.
*/
function getApproved(uint256 tokenId) external view returns (address operator);
/**
* @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
*
* See {setApprovalForAll}
*/
function isApprovedForAll(address owner, address operator) external view returns (bool);
}// 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;
/// @title Interface for the Bonus Manager
/// @notice This interface defines the functions that the Bonus Manager contract should implement. Each function is a getter responsible for returning a percentage multiplier
interface IBonusManager {
function getFeedBonus(
address _caller,
uint256 _tokenId
) external view returns (int256 _amount);
function getHarvestBonus(
address _caller
) external view returns (uint256 _amount);
function getPetBonus(
address _petter
) external view returns (uint256 _amount);
function getReferralBonus() external view returns (uint256 _amount);
error InvalidRarityError(uint256 _rarity);
error InvalidRealmBonus(uint256 _realmIndex);
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
/// @title ILockManager interface
/// @notice Provides an interface for managing token locks, including price updates, lock configurations, and user interactions.
interface ILockManager {
/// @notice Struct representing a lockdrop event
/// @param start Unix timestamp for when the lockdrop starts
/// @param end Unix timestamp for when the lockdrop ends
/// @param minLockDuration Minimum lock duration allowed when locking a token
struct Lockdrop {
uint32 start;
uint32 end;
uint32 minLockDuration;
}
/// @notice Struct holding details about tokens that can be locked
/// @param usdPrice USD price per token
/// @param nftCost Cost of the NFT associated with locking this token
/// @param decimals Number of decimals for the token
/// @param active Boolean indicating if the token is currently active for locking
struct ConfiguredToken {
uint256 usdPrice;
uint256 nftCost;
uint8 decimals;
bool active;
}
/// @notice Struct describing tokens locked by a player
/// @param quantity Amount of tokens locked
/// @param remainder Tokens left over after locking, not meeting the full NFT cost
/// @param lastLockTime The last time tokens were locked
/// @param unlockTime When the tokens will be unlocked
struct LockedToken {
uint256 quantity;
uint256 remainder;
uint32 lastLockTime;
uint32 unlockTime;
}
/// @notice Struct to hold locked tokens and their metadata
/// @param lockedToken LockedToken struct containing lock details
/// @param tokenContract Address of the token contract
struct LockedTokenWithMetadata {
LockedToken lockedToken;
address tokenContract;
}
/// @notice Struct to keep player-specific settings
/// @param lockDuration Duration in seconds for which tokens are locked
struct PlayerSettings {
uint32 lockDuration;
}
/// @notice Struct to manage USD price update proposals
/// @param proposedDate Timestamp when the price was proposed
/// @param proposer Address of the oracle proposing the new price
/// @param contracts Array of contracts whose prices are proposed to be updated
/// @param proposedPrice New proposed price in USD
struct USDUpdateProposal {
uint32 proposedDate;
address proposer;
address[] contracts;
uint256 proposedPrice;
mapping(address => uint32) approvals;
mapping(address => uint32) disapprovals;
uint8 approvalsCount;
uint8 disapprovalsCount;
}
/// @notice Configures the start and end times for a lockdrop event
/// @param _lockdropData Struct containing the start and end times
function configureLockdrop(Lockdrop calldata _lockdropData) external;
/// @notice Adds or updates a token configuration for locking purposes
/// @param _tokenContract The contract address of the token to configure
/// @param _tokenData The configuration data for the token
function configureToken(
address _tokenContract,
ConfiguredToken memory _tokenData
) external;
/// @notice Sets the thresholds for approving or disapproving USD price updates
/// @param _approve Number of approvals required to accept a price update
/// @param _disapprove Number of disapprovals required to reject a price update
function setUSDThresholds(uint8 _approve, uint8 _disapprove) external;
/// @notice Proposes a new USD price for one or more tokens
/// @param _price The new proposed price in USD
/// @param _contracts Array of token contract addresses to update
function proposeUSDPrice(
uint256 _price,
address[] calldata _contracts
) external;
/// @notice Approves a proposed USD price update
/// @param _price The price that needs to be approved
function approveUSDPrice(uint256 _price) external;
/// @notice Disapproves a proposed USD price update
/// @param _price The price that needs to be disapproved
function disapproveUSDPrice(uint256 _price) external;
/// @notice Sets the lock duration for a player's tokens
/// @param _duration The lock duration in seconds
function setLockDuration(uint256 _duration) external;
/// @notice Locks tokens on behalf of a player
/// @param _tokenContract Contract address of the token to be locked
/// @param _quantity Amount of tokens to lock
/// @param _onBehalfOf Address of the player for whom tokens are being locked
function lockOnBehalf(
address _tokenContract,
uint256 _quantity,
address _onBehalfOf
) external payable;
/// @notice Locks tokens
/// @param _tokenContract Contract address of the token to be locked
/// @param _quantity Amount of tokens to lock
function lock(address _tokenContract, uint256 _quantity) external payable;
/// @notice Unlocks the player's tokens
/// @param _tokenContract Contract address of the token to be unlocked
/// @param _quantity Amount of tokens to unlock
function unlock(address _tokenContract, uint256 _quantity) external;
/// @notice Retrieves locked tokens for a player
/// @param _player Address of the player
/// @return _lockedTokens Array of LockedTokenWithMetadata structs for all tokens configured
function getLocked(
address _player
) external view returns (LockedTokenWithMetadata[] memory _lockedTokens);
/// @notice Calculates the USD value of all tokens locked by a player, weighted by their yield
/// @param _player Address of the player
/// @return _lockedWeightedValue Total weighted USD value of locked tokens
function getLockedWeightedValue(
address _player
) external view returns (uint256 _lockedWeightedValue);
/// @notice Retrieves configuration for a token given its contract address
/// @param _tokenContract The contract address of the token
/// @return _token Struct containing the token's configuration
function getConfiguredToken(
address _tokenContract
) external view returns (ConfiguredToken memory _token);
/// @notice Retrieves lock settings for a player
/// @param _player Address of the player
/// @return _settings PlayerSettings struct containing the player's lock settings
function getPlayerSettings(
address _player
) external view returns (PlayerSettings calldata _settings);
/// @notice Emitted when a new token is configured
/// @param _tokenContract The token contract being configured
/// @param _tokenData ConfiguredToken struct with new config
event TokenConfigured(address _tokenContract, ConfiguredToken _tokenData);
/// @notice Emitted when a new lockdrop has been configured
/// @param _lockdrop_data Lockdrop struct containing the new lockdrop configuration
event LockDropConfigured(Lockdrop _lockdrop_data);
/// @notice Emitted when a new USD price has been proposed by one of the oracles
/// @param _proposer The oracle proposing the new price
/// @param _price New proposed price, specified in whole dollars
event ProposedUSDPrice(address _proposer, uint256 _price);
/// @notice Emitted when a USD price proposal has been approved by the required number of oracles
/// @param _approver The oracle who approved the new price
event ApprovedUSDPrice(address _approver);
/// @notice Emitted when an oracle disapproves of the proposed USD price
/// @param _disapprover The oracle disapproving of the new price
event DisapprovedUSDPrice(address _disapprover);
/// @notice Emitted when a USD price proposal is removed after receiving sufficient disapprovals
event RemovedUSDProposal();
/// @notice Emitted when the thresholds for USD oracle approvals and disapprovals are updated
/// @param _approve New threshold for approvals
/// @param _disapprove New threshold for disapprovals
event USDThresholdUpdated(uint8 _approve, uint8 _disapprove);
/// @notice Emitted when a player updates their lock duration
/// @param _player The player whose lock duration is updated
/// @param _duration New lock duration, specified in seconds
event LockDuration(address indexed _player, uint256 _duration);
/// @notice Emitted when a player locks tokens
/// @param _player The player locking the tokens
/// @param _sender The sender of the lock transaction
/// @param _tokenContract The contract address of the locked token
/// @param _quantity The amount of tokens locked
/// @param _remainder The remainder of tokens left after locking (not reaching an NFT cost)
/// @param _numberNFTs The number of NFTs the player is entitled to due to the lock
event Locked(
address indexed _player,
address _sender,
address _tokenContract,
uint256 _quantity,
uint256 _remainder,
uint256 _numberNFTs,
uint256 _lockDuration
);
/// @notice Emitted when a player unlocks tokens
/// @param _player The player unlocking the tokens
/// @param _tokenContract The contract address of the unlocked token
/// @param _quantity The amount of tokens unlocked
event Unlocked(
address indexed _player,
address _tokenContract,
uint256 _quantity
);
/// @notice Emitted when the discount factor for token locking is updated
/// @param discountFactor The new discount factor
event DiscountFactorUpdated(uint256 discountFactor);
/// @notice Emitted when the USD price is updated for a token
/// @param _tokenContract The token contract updated
/// @param _newPrice The new USD price
event USDPriceUpdated(address _tokenContract, uint256 _newPrice);
/// @notice Error thrown when an action is attempted by an entity other than the Account Manager
error OnlyAccountManagerError();
/// @notice Error thrown when an operation is attempted on a token that is not configured
error TokenNotConfiguredError();
/// @notice Error thrown when an action is attempted after the lockdrop period has ended
/// @param end The ending time of the lockdrop period
/// @param block_timestamp The current block timestamp, indicating the time of the error
error LockdropEndedError(uint32 end, uint32 block_timestamp);
/// @notice Error thrown when the lockdrop configuration is invalid
error LockdropInvalidError();
/// @notice Error thrown when the NFT cost specified is invalid or not allowed
error NFTCostInvalidError();
/// @notice Error thrown when the USD price proposed is deemed invalid
error USDPriceInvalidError();
/// @notice Error thrown when there is already a proposal in progress and another cannot be started
error ProposalInProgressError();
/// @notice Error thrown when the contracts specified in a proposal are invalid
error ProposalInvalidContractsError();
/// @notice Error thrown when there is no active proposal to operate on
error NoProposalError();
/// @notice Error thrown when the proposer is not allowed to approve their own proposal
error ProposerCannotApproveError();
/// @notice Error thrown when a proposal has already been approved
error ProposalAlreadyApprovedError();
/// @notice Error thrown when a proposal has already been disapproved
error ProposalAlreadyDisapprovedError();
/// @notice Error thrown when the price specified does not match the price in the active proposal
error ProposalPriceNotMatchedError();
/// @notice Error thrown when the lock duration specified exceeds the maximum allowed limit
error MaximumLockDurationError();
/// @notice Error thrown when the ETH value provided in a transaction is incorrect for the intended operation
error ETHValueIncorrectError();
/// @notice Error thrown when the message value provided in a call is invalid
error InvalidMessageValueError();
/// @notice Error thrown when the allowance provided for an operation is insufficient
error InsufficientAllowanceError();
/// @notice Error thrown when the amount locked is insufficient for the intended operation
error InsufficientLockAmountError();
/// @notice Error thrown when tokens are still locked and cannot be unlocked due to the lock period not expiring
error TokenStillLockedError();
/// @notice Error thrown when an invalid call is made to the Lock Manager
error LockManagerInvalidCallError();
/// @notice Error thrown when the Lock Manager refuses to accept ETH for a transaction
error LockManagerRefuseETHError();
/// @notice Error thrown when an invalid token contract address is provided for an operation
error InvalidTokenContractError();
/// @notice Lock duration out of range
error InvalidLockDurationError();
/// @notice User tries to reduce the unlock time
error LockDurationReducedError();
/// @notice If a sub account tries to lock tokens
error SubAccountCannotLockError();
/// @notice Account not registered with AccountManager
error AccountNotRegisteredError();
/// @notice If the player tries to lock too many tokens resulting in too many NFTs being minted
error TooManyNFTsError();
/// @notice Failed to transfer ETH
error FailedTransferError();
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "../libraries/MunchablesCommonLib.sol";
interface IOldNFT {
// This function needs to be added when upgrading the old NFT contract
function burn(uint256 _tokenId) external;
}
/// @title Interface for Migration Manager
/// @notice Handles the migration of NFTs with specific attributes and immutable attributes
interface IMigrationManager {
enum UserLockedChoice {
NONE,
LOCKED_FULL_MIGRATION,
LOCKED_BURN
}
/// @dev Struct to hold data during migration
/// @param tokenId The ID of the token being migrated
/// @param lockAmount Amount of tokens to lock during migration
/// @param lockDuration Duration for which tokens will be locked
/// @param tokenType Type of the token
/// @param attributes Attributes of the NFT
/// @param immutableAttributes Immutable attributes of the NFT
/// @param claimed Status of the NFT claim
struct MigrationSnapshotData {
uint256 tokenId;
uint256 lockAmount;
address token;
MunchablesCommonLib.NFTAttributes attributes;
MunchablesCommonLib.NFTImmutableAttributes immutableAttributes;
MunchablesCommonLib.NFTGameAttribute[] gameAttributes;
bool claimed;
}
struct MigrationTotals {
uint256 totalPurchasedAmount;
uint256 totalLockedAmount;
address tokenLocked;
}
/// @notice Load the migration snapshot for a batch of users
/// @dev This function sets up migration data for users
/// @param users Array of user addresses
/// @param data Array of migration data corresponding to each user
function loadMigrationSnapshot(
address[] calldata users,
MigrationSnapshotData[] calldata data
) external;
/// @notice Load the unrevealed snapshot for a batch of users
/// @dev This function sets up unrevealed data for users
/// @param users Array of user addresses
/// @param unrevealed Array of number of unrevealed for each user
function loadUnrevealedSnapshot(
address[] calldata users,
uint16[] calldata unrevealed
) external;
/// @notice Seals migration data loading
function sealData() external; // onlyRole(DEFAULT_ADMIN_ROLE)
/// @notice Burns NFTs
/// @dev This function handles multiple NFT burn process
function burnNFTs(address _user, uint32 _skip) external;
/// @notice Burns remaining purchased NFTs
/// @dev This function handles burning all remaining purchased NFTs
function burnRemainingPurchasedNFTs(address _user, uint32 _skip) external;
/// @notice Lock funds for migration
/// @dev This function handles locking funds and changing state to migrate
function lockFundsForAllMigration() external payable;
/// @notice Migrates all NFTs to the new version
/// @dev This function handles multiple NFT migration processes. They need to lock funds first before migrating.
function migrateAllNFTs(address _user, uint32 _skip) external;
/// @notice Migrates purchased NFTs to the new version
/// @dev This function handles multiple NFT migration processes
function migratePurchasedNFTs(uint256[] memory tokenIds) external payable;
/// @notice Burn unrevealed NFTs for points
function burnUnrevealedForPoints() external;
/// @notice Return funds which are stuck in the contract (admin only)
/// @param _tokenContract The token contract address(0) for ETH
/// @param _quantity Amount to return
/// @param _returnAddress Address to return to
function rescue(
address _tokenContract,
uint256 _quantity,
address _returnAddress
) external;
/// @notice Gets the migration data for a user and token ID
/// @param _user The user address
/// @param _tokenId The token ID
function getUserMigrationData(
address _user,
uint256 _tokenId
) external view returns (MigrationSnapshotData memory);
/// @notice Gets the overall migration data for a user
/// @param _user The user address
function getUserMigrationCompletedData(
address _user
) external view returns (bool, MigrationTotals memory);
/// @notice Gets the total number of NFTs owned by a user
/// @param _user The user address
function getUserNFTsLength(address _user) external view returns (uint256);
/// @notice Emitted when the migration snapshot is loaded
/// @param users The array of user addresses involved in the migration
/// @param data The migration data corresponding to each user
event MigrationSnapshotLoaded(
address[] users,
MigrationSnapshotData[] data
);
/// @notice Emitted when unreveal data is loaded
/// @param users The accounts
/// @param unrevealed Number of unrevealed NFTs
event UnrevealedSnapshotLoaded(address[] users, uint16[] unrevealed);
/// @notice Emitted when an NFT migration is successful
/// @param user The user who owns the NFTs
/// @param _oldTokenIds The token IDs of the old NFTs
/// @param _newTokenIds The token IDs of the new NFTs
event MigrationSucceeded(
address user,
uint256[] _oldTokenIds,
uint256[] _newTokenIds
);
/// @notice Emitted when an NFT burn is successful
/// @param user The user who owns the NFTs
/// @param _oldTokenIds The token IDs of the old NFTs
event BurnSucceeded(address user, uint256[] _oldTokenIds);
/// @notice Emitted when an NFT burn is successful
/// @param user The user who owns the NFTs
/// @param _oldTokenIds The token IDs of the old NFTs
event BurnPurchasedSucceeded(address user, uint256[] _oldTokenIds);
/// @notice Emitted after a player swaps unrevealed NFTs for points
/// @param user The account that swapped the unrevealed NFTS
/// @param amountSwapped The amount of unrevealed NFTs which will be swapped for points
event UnrevealedSwapSucceeded(address user, uint256 amountSwapped);
/// @notice Emitted when the migration data is sealed
event MigrationDataSealed();
/// @notice Emitted when a user locks their funds for a full migration
event LockedForMigration(address user, uint256 amount, address token);
error NotBoughtNFTError();
error NFTPurchasedContractError();
error UnrevealedNFTError();
error NoMigrationExistsError();
error InvalidMigrationOwnerError(address _owner, address _sender);
error InvalidMigrationAmountError();
error InvalidMigrationTokenError();
error AllowanceTooLowError();
error MigrationDataSealedError();
error MigrationDataNotSealedError();
error NoUnrevealedError();
error NoNFTsToBurnError();
error InvalidDataLengthError();
error DataAlreadyLoadedError();
error DifferentLockActionError();
error SelfNeedsToChooseError();
error InvalidSkipAmountError();
error InvalidMigrationTokenIdError();
error RescueTransferError();
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.25;
import "../libraries/MunchablesCommonLib.sol";
/// @title Interface for NFT Attributes Manager V1
/// @notice This interface manages the attributes and metadata of NFTs within the Munch ecosystem.
interface INFTAttributesManager {
/// @notice Called from MunchableManager to initialise a new record
function createWithImmutable(
uint256 _tokenId,
MunchablesCommonLib.NFTImmutableAttributes memory _immutableAttributes
) external;
/// @notice Sets dynamic attributes for a specific NFT, typically called after feeding or interaction events
/// @param _tokenId The ID of the NFT
/// @param _attributes Struct of new attributes
function setAttributes(
uint256 _tokenId,
MunchablesCommonLib.NFTAttributes calldata _attributes
) external;
/// @notice Sets game attributes for a specific NFT, typically called after level up
/// @param _tokenId The ID of the NFT
/// @param _attributes Array of new game attributes
function setGameAttributes(
uint256 _tokenId,
MunchablesCommonLib.NFTGameAttribute[] calldata _attributes
) external;
/// @notice Retrieves all data associated with an NFT in a single call
/// @param _tokenId The ID of the NFT
/// @return _nftData A struct containing all attributes (dynamic, immutable, and game-specific)
// function getFullNFTData(
// uint256 _tokenId
// ) external view returns (NFTFull memory _nftData);
/// @notice Retrieves dynamic attributes for a specific token
/// @param _tokenId The ID of the NFT
/// @return _attributes Struct of the NFT's dynamic attributes
function getAttributes(
uint256 _tokenId
)
external
view
returns (MunchablesCommonLib.NFTAttributes memory _attributes);
/// @notice Retrieves immutable attributes for a specific token
/// @param _tokenId The ID of the NFT
/// @return _immutableAttributes Struct of the NFT's immutable attributes
function getImmutableAttributes(
uint256 _tokenId
)
external
view
returns (
MunchablesCommonLib.NFTImmutableAttributes
memory _immutableAttributes
);
/// @notice Retrieves game-specific attributes for a specific token
/// @param _tokenId The ID of the NFT
/// @param _requestedIndexes Array of GameAttributeIndex to define subset of attributes to include in the result
/// @return _gameAttributes Struct of the NFT's game attributes
function getGameAttributes(
uint256 _tokenId,
MunchablesCommonLib.GameAttributeIndex[] calldata _requestedIndexes
)
external
view
returns (MunchablesCommonLib.NFTGameAttribute[] memory _gameAttributes);
function getGameAttributeDataType(
uint8 _index
) external pure returns (MunchablesCommonLib.GameAttributeType _dataType);
event CreatedWithImmutable(
uint256 _tokenId,
MunchablesCommonLib.NFTImmutableAttributes _immutableAttributes
);
/// @notice Event emitted when NFT attributes are updated
event AttributesUpdated(uint256 indexed _tokenId);
/// @notice Event emitted when NFT game attributes are updated
event GameAttributesUpdated(uint256 indexed _tokenId);
/// @notice Error when the owner of the NFT does not match the expected address
error IncorrectOwnerError();
/// @notice Error when the 'from' level specified is invalid
error InvalidLevelFromError();
/// @notice Error when the oracle recovering the signature is invalid
/// @param _recoveredSigner The address of the invalid signer
error InvalidOracleError(address _recoveredSigner);
/// @notice Error when a call is made by a non-authorized migration manager
error NotAuthorizedMigrationManagerError();
/// @notice When user tries to set attributes when the record hasnt been created
error NotCreatedError();
}// 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";
/// @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";
interface IMunchadexManager {
/// @notice Updates the Munchadex with this transfer data
/// @param _from The address of the sender
/// @param _to The address of the receiver
/// @param _tokenId The ID of the NFT being transferred
function updateMunchadex(
address _from,
address _to,
uint256 _tokenId
) external;
/// @notice Retrieves the Munchadex data for a specific player
/// @param _player The address of the player
function getMunchadexInfo(
address _player
)
external
view
returns (
uint256[] memory numMunchablesPerRealm,
uint256[] memory numMunchablesPerRarity,
uint256 numUnique
);
// @notice internal munchadex counters updated
event MunchadexUpdated(
address indexed _player,
uint256 _tokenId,
MunchablesCommonLib.Realm realm,
MunchablesCommonLib.Rarity rarity,
uint256 _numInRealm,
uint256 _numInRarity,
uint256 _numUnique
);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: 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)];
}
}// 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);
}{
"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":[],"name":"InvalidGovernorError","type":"error"},{"inputs":[{"internalType":"uint256","name":"_rarity","type":"uint256"}],"name":"InvalidRarityError","type":"error"},{"inputs":[{"internalType":"uint256","name":"_realmIndex","type":"uint256"}],"name":"InvalidRealmBonus","type":"error"},{"inputs":[],"name":"InvalidRoleError","type":"error"},{"inputs":[],"name":"OnlyStorageError","type":"error"},{"inputs":[],"name":"UnauthorisedError","type":"error"},{"inputs":[{"internalType":"enum StorageKey","name":"_key","type":"uint8"}],"name":"UnconfiguredError","type":"error"},{"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":[],"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":"configStorage","outputs":[{"internalType":"contract IConfigStorage","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"configUpdated","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"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getFeedBonus","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_caller","type":"address"}],"name":"getHarvestBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_petter","type":"address"}],"name":"getPetBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReferralBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"munchablesPerRarity","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"munchablesPerRealm","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rarityBonuses","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"raritySetBonuses","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"realmBonuses","outputs":[{"internalType":"int16","name":"","type":"int16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referralBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMunchables","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"}]Contract Creation Code
6080806040523461097c576000906100366148f59182380380936100238284611401565b82396001600160a01b0392810190611424565b82546001600160a01b0319169116908117825560405163bcaa0c5560e01b815260056004820152602081602481855afa9081156108be5783916113cf575b50600880546001600160a01b0319166001600160a01b039290921691909117905560405163bcaa0c5560e01b815260026004820152602081602481855afa9081156108be5783916113b0575b50600780546001600160a01b0319166001600160a01b039290921691909117905560405163bcaa0c5560e01b815260156004820152602081602481855afa9081156108be578391611391575b50600980546001600160a01b0319166001600160a01b039290921691909117905560405163bcaa0c5560e01b815260036004820152602081602481855afa9081156108be578391611372575b50600a80546001600160a01b0319166001600160a01b039290921691909117905560405163bcaa0c5560e01b815260096004820152602081602481855afa9081156108be578391611353575b50600b80546001600160a01b0319166001600160a01b03929092169190911790556040516342ab14dd60e01b815260216004820152908290602083602481845afa8015610907578290611320575b600c55604051630b371dd960e41b8152602260048201529250829060249082905afa908115610907578291611279575b508051906001600160401b038211610ea557680100000000000000008211610ea557602090600d5483600d55808410611221575b50600d845201907fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb590835b8160041c81106111e15750600f198116808203611198575b505082546040516341a2549360e11b8152602360048201529250839150829060249082906001600160a01b03165afa90811561090757829161117e575b508051906001600160401b038211610ea557680100000000000000008211610ea557602090600e5483600e5580841061114e575b50600e845201907fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd90835b8160051c811061110f5750601f1981168082036110c0575b505082546040516342ab14dd60e01b81526026600482015292508391506001600160a01b0316602083602481845afa92831561090757829361108b575b5060ff6024931660ff196012541617601255604051928380926341a2549360e11b8252602760048301525afa908115610907578291611071575b508051906001600160401b038211610ea557680100000000000000008211610ea557602090600f5483600f55808410611041575b50600f845201907f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80290835b8160051c81106110025750601f198116808203610fb3575b505082546040516341a2549360e11b8152602860048201529250839150829060249082906001600160a01b03165afa908115610907578291610f99575b508051906001600160401b038211610ea557680100000000000000008211610ea55760209060105483601055808410610f69575b506010845201907f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67290835b8160051c8110610f2a5750601f198116808203610edb575b505082546040516341a2549360e11b8152602960048201529250839150829060249082906001600160a01b03165afa908115610907578291610eb9575b508051906001600160401b038211610ea557680100000000000000008211610ea55760209060115483601155808410610e51575b506011845201907f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6890835b8160051c8110610e125750601f198116810380610dc5575b505082546040516342ab14dd60e01b8152602f60048201526001600160a01b0390911692509050602081602481855afa9081156108be578391610d93575b506013556040516342ab14dd60e01b815260306004820152602081602481855afa9081156108be578391610d61575b506014556040516342ab14dd60e01b815260316004820152602081602481855afa9081156108be578391610d2f575b506015556040516342ab14dd60e01b8152603d6004820152602081602481855afa9081156108be578391610cfd575b506016556040516342ab14dd60e01b8152603e6004820152602081602481855afa9081156108be578391610cc6575b5060175560405163bcaa0c5560e01b8152600f60048201529190602090839060249082905afa918215610cb9578192610c98575b506001546001600160a01b03838116919081168203610b4d575b5050805460405163bcaa0c5560e01b8152601060048201529192506001600160a01b0316908290602081602481865afa908115610907578291610b2e575b506002546001600160a01b039182169181168203610a43575b5050805460405163bcaa0c5560e01b8152601260048201529192506001600160a01b0316602082602481845afa9182156108be578392610a1e575b5060206024916040519283809263bcaa0c5560e01b8252601360048301525afa9182156108be57839182936109fd575b50600554906001600160a01b039081169082168103610988575b5050600654916001600160a01b03908116915082168103610912575b5050815460405163bcaa0c5560e01b8152600c60048201529150602090829060249082906001600160a01b03165afa9081156109075782916108d8575b506001600160a01b0381166108c9575b508054604051633caab1db60e21b8152600160048201526020816024816001600160a01b0386165afa9081156108be57839161088f575b5060ff60a01b1990911690151560a01b60ff60a01b161790556040516132f390816116028239f35b6108b1915060203d6020116108b7575b6108a98183611401565b8101906114f4565b38610867565b503d61089f565b6040513d85823e3d90fd5b6108d29061150c565b38610830565b6108fa915060203d602011610900575b6108f28183611401565b810190611424565b38610820565b503d6108e8565b6040513d84823e3d90fd5b6001600160a01b03199091168117600655604051631a33757d60e01b8152600260048201529160209183916024918391905af1801561090757610958575b8082916107e3565b602090813d8311610981575b61096e8183611401565b8101031261097c5738610950565b600080fd5b503d610964565b6001600160a01b03199091168117600555604051631a33757d60e01b8152600260048201529160209183916024918391905af180156108be576109ce575b8083916107c7565b6020809293503d83116109f6575b6109e68183611401565b8101031261097c578190386109c6565b503d6109dc565b610a1791935060203d602011610900576108f28183611401565b91386107ad565b6024919250610a3b602091823d8411610900576108f28183611401565b92915061077d565b6001600160a01b03198116821760025560405163bcaa0c5560e01b81526011600482015293602090859060249082905afa9384156108be578394610b0d575b506004546001600160a01b03166107425782161791823b15610b09576040516336b91f2b60e01b81526001600160a01b03909116600482018190529282908290602490829084905af1801561090757610af5575b5050600480546001600160a01b03191691909117905538818180610742565b610afe906113ee565b610b09578138610ad6565b5080fd5b610b2791945060203d602011610900576108f28183611401565b9238610a82565b610b47915060203d602011610900576108f28183611401565b38610729565b6001600160a01b03191681176001556040516301fd3f7760e71b8152306004820152602081602481855afa9081156108be578391610c79575b50610b92575b806106eb565b803b15610b0957818091600460405180948193634e606c4760e01b83525af1801561090757610c6a575b506040805163784c3b3d60e11b60208201908152600482529293918101929091906001600160401b03841183851017610c545784809493819460405251925af1503d15610c4f573d6001600160401b038111610c3b5760405190610c2a601f8201601f191660200183611401565b81528160203d92013e5b8038610b8c565b634e487b7160e01b82526041600452602482fd5b610c34565b634e487b7160e01b600052604160045260246000fd5b610c73906113ee565b38610bbc565b610c92915060203d6020116108b7576108a98183611401565b38610b86565b610cb291925060203d602011610900576108f28183611401565b90386106d1565b50604051903d90823e3d90fd5b90506020813d602011610cf5575b81610ce160209383611401565b81010312610cf15751602461069d565b8280fd5b3d9150610cd4565b90506020813d602011610d27575b81610d1860209383611401565b81010312610cf157513861066e565b3d9150610d0b565b90506020813d602011610d59575b81610d4a60209383611401565b81010312610cf157513861063f565b3d9150610d3d565b90506020813d602011610d8b575b81610d7c60209383611401565b81010312610cf1575138610610565b3d9150610d6f565b90506020813d602011610dbd575b81610dae60209383611401565b81010312610cf15751386105e1565b3d9150610da1565b928493855b818110610de25750505060051c0155388080806105a3565b9091946020610e086001928460ff8a5116919060ff809160031b9316831b921b19161790565b9601929101610dca565b84855b60208110610e2a57508382015560010161058b565b855190959160019160209160ff60038a901b81811b199092169216901b1792019501610e15565b610e7c9060118652838620601f80870160051c82019281881680610e82575b500160051c019061145a565b38610560565b610e9f906000198601908154906000199060200360031b1c169055565b38610e70565b634e487b7160e01b83526041600452602483fd5b610ed591503d8084833e610ecd8183611401565b810190611471565b3861052c565b928493855b8184038110610efa5750505060051c0155388080806104ef565b9091946020610f206001928460ff8a5116919060ff809160031b9316831b921b19161790565b9601929101610ee0565b84855b60208110610f425750838201556001016104d7565b855190959160019160209160ff60038a901b81811b199092169216901b1792019501610f2d565b610f939060108652838620601f80870160051c82019281881680610e8257500160051c019061145a565b386104ac565b610fad91503d8084833e610ecd8183611401565b38610478565b928493855b8184038110610fd25750505060051c01553880808061043b565b9091946020610ff86001928460ff8a5116919060ff809160031b9316831b921b19161790565b9601929101610fb8565b84855b6020811061101a575083820155600101610423565b855190959160019160209160ff60038a901b81811b199092169216901b1792019501611005565b61106b90600f8652838620601f80870160051c82019281881680610e8257500160051c019061145a565b386103f8565b61108591503d8084833e610ecd8183611401565b386103c4565b92506020833d6020116110b8575b816110a660209383611401565b81010312610b095791519160ff61038a565b3d9150611099565b928493855b81840381106110df5750505060051c01553880808061034d565b90919460206111056001928460ff8a5116919060ff809160031b9316831b921b19161790565b96019291016110c5565b84855b60208110611127575083820155600101610335565b855190959160019160209160ff60038a901b81811b199092169216901b1792019501611112565b61117890600e8652838620601f80870160051c82019281881680610e8257500160051c019061145a565b3861030a565b61119291503d8084833e610ecd8183611401565b386102d6565b928493855b81840381106111b75750505060041c015538808080610299565b825161ffff908116600483901b90811b91901b19909616959095179460209092019160010161119d565b84855b601081106111f9575083820155600101610281565b855190959160019160209161ffff60048a901b81811b199092169216901b17920195016111e4565b61125090600d8652838620600f80870160041c820192601e8860011b1680611256575b500160041c019061145a565b38610256565b611273906000198601908154906000199060200360031b1c169055565b38611244565b90503d8083833e61128a8183611401565b810190602081830312610cf1578051906001600160401b03821161131c57019080601f83011215610cf1578151906112c182611443565b926112cf6040519485611401565b82845260208085019360051b82010191821161131857602001915b8183106112fa5750505038610222565b82518060010b8103611314578152602092830192016112ea565b8580fd5b8480fd5b8380fd5b506020833d60201161134b575b8161133a60209383611401565b81010312610b0957602492516101f2565b3d915061132d565b61136c915060203d602011610900576108f28183611401565b386101a4565b61138b915060203d602011610900576108f28183611401565b38610158565b6113aa915060203d602011610900576108f28183611401565b3861010c565b6113c9915060203d602011610900576108f28183611401565b386100c0565b6113e8915060203d602011610900576108f28183611401565b38610074565b6001600160401b038111610c5457604052565b601f909101601f19168101906001600160401b03821190821017610c5457604052565b9081602091031261097c57516001600160a01b038116810361097c5790565b6001600160401b038111610c545760051b60200190565b818110611465575050565b6000815560010161145a565b602090818184031261097c578051906001600160401b03821161097c57019180601f8401121561097c5782516114a681611443565b936114b46040519586611401565b818552838086019260051b82010192831161097c578301905b8282106114db575050505090565b815160ff8116810361097c5781529083019083016114cd565b9081602091031261097c5751801515810361097c5790565b6001600160a01b039081169081156115ef578060015416156115eb576003548116806115a35750308203611553575b505b600380546001600160a01b031916919091179055565b60015416803b1561097c5760008091602460405180948193631d70c8d360e31b83528760048401525af18015611597571561153b57611591906113ee565b3861153b565b6040513d6000823e3d90fd5b8091503b1561097c5760008091602460405180948193633a74bfd760e01b83528760048401525af18015611597576115dc575b5061153d565b6115e5906113ee565b386115d6565b5050565b6040516305d8ce3d60e01b8152600490fdfe608080604052600436101561001357600080fd5b600090813560e01c9081631389930314612c12575080631714818b14612be55780631f89561e14612bb857806331a0edec14612b9157806339928cf714612b645780633cdad82c14612b3d578063443b178614612b175780634b03eeb41461293f5780634f73a920146129035780635c806e9f146128e2578063679c93b914611ec05780638da52e931461064e578063ad5c464814610627578063b930b48214610600578063c049072214610237578063ce7842f514610219578063d5994276146101dc578063df89ff781461011b5763fce14af6146100f257600080fd5b3461011857806003193601126101185760206001600160a01b0360015416604051908152f35b80fd5b503461011857602060031936011261011857610135612d66565b60206001600160a01b03602481600754169360405194859384927f527335610000000000000000000000000000000000000000000000000000000084521660048301525afa9081156101d15761019c9163ffffffff91602094916101a4575b505116612f93565b604051908152f35b6101c49150843d86116101ca575b6101bc8183612e15565b810190612e5d565b38610194565b503d6101b2565b6040513d84823e3d90fd5b5034610118576020600319360112610118576004359060105482101561011857602060ff61020984612d29565b9190546040519260031b1c168152f35b50346101185780600319360112610118576020600c54604051908152f35b503461011857604060031936011261011857610251612d66565b90602491826001600160a01b039160a08360095416604051938480927fd20264ca000000000000000000000000000000000000000000000000000000008252823560048301525afa918215610537578492610542575b5082600a54166040519384927f5c12cd4b00000000000000000000000000000000000000000000000000000000845216600483015281866101009384935afa9283156105375784936104eb575b50508051600781101561048857600e54111561049c57805191600783101561048857610321604093612cec565b93905492015190600682101561046257600582029180830460051490151715610475576060015160068110156104625761035a91612e95565b600d54811015610432579061037060ff92612d7c565b90549060031b1c840b9260031b1c16820b017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80008112617fff8213176104205760010b662386f26fc10000908082029182050361042057602092507ffffffffffffffffffffffffffffffffffffffffffffffffffd39750f44ec0000908181121561041957505b670de0b6b3a76400009150818113156104125750604051908152f35b905061019c565b90506103f6565b50634e487b7160e01b81526011600452fd5b8490604051907f1dd219080000000000000000000000000000000000000000000000000000000082526004820152fd5b8585634e487b7160e01b81526021600452fd5b8585634e487b7160e01b81526011600452fd5b505050634e487b7160e01b81526021600452fd5b9050519060078210156104d85750604051907f526a55b60000000000000000000000000000000000000000000000000000000082526004820152fd5b9050634e487b7160e01b81526021600452fd5b90809293503d8311610530575b6105028183612e15565b8101918183031261052c579060208261051d61052494612e38565b5001612ebf565b9038806102f4565b8380fd5b503d6104f8565b6040513d86823e3d90fd5b90915060a0813d60a0116105f8575b8161055e60a09383612e15565b8101031261052c576040519060a0820182811067ffffffffffffffff8211176105e357604052805160078110156105df57825261059d60208201612ea2565b6020830152604081015160068110156105df576105d39160809160408501526105c860608201612eb1565b606085015201612e4c565b608082015290386102a7565b8580fd5b86634e487b7160e01b60005260416004526000fd5b3d9150610551565b503461011857806003193601126101185760206001600160a01b0360025416604051908152f35b503461011857806003193601126101185760206001600160a01b0360065416604051908152f35b50346101185780600319360112610118576001600160a01b03815416803303611e965760405163bcaa0c5560e01b815260056004820152602081602481855afa8015610ef1578390611e56575b6001600160a01b039150166001600160a01b0319600854161760085560405163bcaa0c5560e01b815260026004820152602081602481855afa8015610ef1578390611e16575b6001600160a01b039150166001600160a01b0319600754161760075560405163bcaa0c5560e01b815260156004820152602081602481855afa8015610ef1578390611dd6575b6001600160a01b039150166001600160a01b0319600954161760095560405163bcaa0c5560e01b815260036004820152602081602481855afa8015610ef1578390611d96575b6001600160a01b039150166001600160a01b0319600a541617600a5560405163bcaa0c5560e01b815260096004820152602081602481855afa8015610ef1578390611d56575b6001600160a01b039150166001600160a01b0319600b541617600b5581604051916342ab14dd60e01b835260216004840152602083602481845afa80156101d1578290611d23575b60249350600c55604051928380927fb371dd90000000000000000000000000000000000000000000000000000000008252602260048301525afa9081156101d1578291611c83575b5080519067ffffffffffffffff82116116785768010000000000000000821161167857602090600d5483600d55808410611bf3575b500190600d8352825b8160041c8110611b9357507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08116808203611b2a575b5050506024816001600160a01b03815416604051928380926341a2549360e11b8252602360048301525afa9081156101d1578291611b10575b5080519067ffffffffffffffff82116116785768010000000000000000821161167857602090600e5483600e55808410611a8b575b500190600e8352825b8160051c8110611a2c5750601f1981168082036119bd575b5050506001600160a01b0381541681604051916342ab14dd60e01b835260266004840152602083602481845afa9283156101d1578293611988575b5060ff602493167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff006012541617601255604051928380926341a2549360e11b8252602760048301525afa9081156101d157829161196e575b5080519067ffffffffffffffff82116116785768010000000000000000821161167857602090600f5483600f558084106118e9575b500190600f8352825b8160051c811061188a5750601f19811680820361181b575b5050506024816001600160a01b03815416604051928380926341a2549360e11b8252602860048301525afa9081156101d1578291611801575b5080519067ffffffffffffffff821161167857680100000000000000008211611678576020906010548360105580841061177c575b50019060108352825b8160051c811061171d5750601f1981168082036116ae575b5050506024816001600160a01b03815416604051928380926341a2549360e11b8252602960048301525afa9081156101d157829161168c575b5080519067ffffffffffffffff82116116785768010000000000000000821161167857602090601154836011558084106115ec575b50019060118352825b8160051c811061158d5750601f19811680820361151e575b5050506001600160a01b038154166040516342ab14dd60e01b8152602f6004820152602081602481855afa908115610ef15783916114ec575b506013556040516342ab14dd60e01b815260306004820152602081602481855afa908115610ef15783916114ba575b506014556040516342ab14dd60e01b815260316004820152602081602481855afa908115610ef1578391611488575b506015556040516342ab14dd60e01b8152603d6004820152602081602481855afa908115610ef1578391611456575b506016556040516342ab14dd60e01b8152603e6004820152602081602481855afa908115610ef1578391611423575b50602492916020916017556040519384809263bcaa0c5560e01b8252600f60048301525afa9182156114165781926113da575b506001546001600160a01b038316906001600160a01b038116820361122b575b505090506001600160a01b038154168160405163bcaa0c5560e01b815260106004820152602081602481865afa9081156101d15782916111f1575b506001600160a01b036002549116906001600160a01b03811682036110df575b505090506001600160a01b038154166040519063bcaa0c5560e01b825260126004830152602082602481845afa918215610ef157839261109e575b5060206024916040519283809263bcaa0c5560e01b8252601360048301525afa918215610ef1578391829361105c575b506001600160a01b0360055491166001600160a01b0382168103610fd3575b5050506001600160a01b0360065491166001600160a01b0382168103610f49575b505060206001600160a01b0360249254166040519283809263bcaa0c5560e01b8252600c60048301525afa9081156101d1578291610f0b575b506001600160a01b038116610efc575b5080546040517ff2aac76c000000000000000000000000000000000000000000000000000000008152600160048201526020816024816001600160a01b0386165afa908115610ef1578391610e7b575b5074ff00000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff91151560a01b16911617815580f35b90506020813d602011610ee9575b81610e9660209383612e15565b81010312610ee55774ff0000000000000000000000000000000000000000610ede7fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff92612f59565b9150610e34565b8280fd5b3d9150610e89565b6040513d85823e3d90fd5b610f0590613181565b38610de4565b90506020813d602011610f41575b81610f2660209383612e15565b81010312610f3d57610f3790612e38565b38610dd4565b5080fd5b3d9150610f19565b806001600160a01b031960209316176006556024604051809481937f1a33757d000000000000000000000000000000000000000000000000000000008352600260048401525af180156101d157610fa3575b808291610d9b565b602090813d8311610fcc575b610fb98183612e15565b81010312610fc75738610f9b565b600080fd5b503d610faf565b806001600160a01b031960209316176005556024604051809481937f1a33757d000000000000000000000000000000000000000000000000000000008352600260048401525af18015610ef15761102d575b808391610d7a565b6020809293503d8311611055575b6110458183612e15565b81010312610fc757819038611025565b503d61103b565b915091506020813d602011611096575b8161107960209383612e15565b810103126110925761108b8391612e38565b9138610d5b565b5050fd5b3d915061106c565b9091506020813d6020116110d7575b816110ba60209383612e15565b810103126110925760206110cf602492612e38565b929150610d2b565b3d91506110ad565b6020602494836001600160a01b03198416176002556040519586809263bcaa0c5560e01b8252601160048301525afa938415610ef15783946111b5575b506001600160a01b0360045416610cf05782161791823b15610f3d57816001600160a01b036024829360405194859384927f36b91f2b00000000000000000000000000000000000000000000000000000000845216978860048401525af180156101d1576111a1575b50506001600160a01b0319600454161760045538818180610cf0565b6111aa90612e01565b610f3d578138611185565b9093506020813d6020116111e9575b816111d160209383612e15565b81010312610ee5576111e290612e38565b923861111c565b3d91506111c4565b90506020813d602011611223575b8161120c60209383612e15565b81010312610f3d5761121d90612e38565b38610cd0565b3d91506111ff565b6001600160a01b03191681176001556040517ffe9fbb80000000000000000000000000000000000000000000000000000000008152306004820152602081602481855afa908115610ef15783916113a0575b50611289575b80610c95565b803b15610f3d578180916004604051809481937f4e606c470000000000000000000000000000000000000000000000000000000083525af180156101d157611391575b509060405160208101917ff098767a00000000000000000000000000000000000000000000000000000000835260048252604082019282841067ffffffffffffffff85111761137b5784809493819460405251925af1503d15611376573d67ffffffffffffffff811161136257604051906113516020601f19601f8401160183612e15565b81528160203d92013e5b8038611283565b602482634e487b7160e01b81526041600452fd5b61135b565b634e487b7160e01b600052604160045260246000fd5b61139a90612e01565b386112cc565b90506020813d6020116113d2575b816113bb60209383612e15565b81010312610ee5576113cc90612f59565b3861127d565b3d91506113ae565b9091506020813d60201161140e575b816113f660209383612e15565b81010312610f3d5761140790612e38565b9038610c75565b3d91506113e9565b50604051903d90823e3d90fd5b90506020813d60201161144e575b8161143e60209383612e15565b81010312610ee557516024610c42565b3d9150611431565b90506020813d602011611480575b8161147160209383612e15565b81010312610ee5575138610c13565b3d9150611464565b90506020813d6020116114b2575b816114a360209383612e15565b81010312610ee5575138610be4565b3d9150611496565b90506020813d6020116114e4575b816114d560209383612e15565b81010312610ee5575138610bb5565b3d91506114c8565b90506020813d602011611516575b8161150760209383612e15565b81010312610ee5575138610b86565b3d91506114fa565b918392845b818403811061155d5750505060051c7f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680155388080610b4d565b90919360206115836001928460ff895116919060ff809160031b9316831b921b19161790565b9501929101611523565b83845b602081106115c557507f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68820155600101610b35565b845190949160019160209160ff600389901b81811b199092169216901b1792019401611590565b61163290601f850160051c601f7f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c689281881680611638575b500160051c820191016130e8565b38610b2c565b611672907f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6785019060001982549160200360031b1c169055565b38611624565b602483634e487b7160e01b81526041600452fd5b6116a891503d8084833e6116a08183612e15565b8101906130ff565b38610af7565b918392845b81840381106116ed5750505060051c7f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6720155388080610abe565b90919360206117136001928460ff895116919060ff809160031b9316831b921b19161790565b95019291016116b3565b83845b6020811061175557507f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae672820155600101610aa6565b845190949160019160209160ff600389901b81811b199092169216901b1792019401611720565b6117c190601f850160051c601f7f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67292818816806117c757500160051c820191016130e8565b38610a9d565b611672907f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67185019060001982549160200360031b1c169055565b61181591503d8084833e6116a08183612e15565b38610a68565b918392845b818403811061185a5750505060051c7f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020155388080610a2f565b90919360206118806001928460ff895116919060ff809160031b9316831b921b19161790565b9501929101611820565b83845b602081106118c257507f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802820155600101610a17565b845190949160019160209160ff600389901b81811b199092169216901b179201940161188d565b61192e90601f850160051c601f7f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802928188168061193457500160051c820191016130e8565b38610a0e565b611672907f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80185019060001982549160200360031b1c169055565b61198291503d8084833e6116a08183612e15565b386109d9565b92506020833d6020116119b5575b816119a360209383612e15565b81010312610f3d5791519160ff610981565b3d9150611996565b918392845b81840381106119fc5750505060051c7fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0155388080610946565b9091936020611a226001928460ff895116919060ff809160031b9316831b921b19161790565b95019291016119c2565b83845b60208110611a6457507fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd82015560010161092e565b845190949160019160209160ff600389901b81811b199092169216901b1792019401611a2f565b611ad090601f850160051c601f7fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd9281881680611ad657500160051c820191016130e8565b38610925565b611672907fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fc85019060001982549160200360031b1c169055565b611b2491503d8084833e6116a08183612e15565b386108f0565b918392845b8184038110611b695750505060041c7fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb501553880806108b7565b825161ffff908116600483901b90811b91901b199095169490941793602090920191600101611b2f565b83845b60108110611bcb57507fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5820155600101610881565b845190949160019160209161ffff600489901b81811b199092169216901b1792019401611b96565b611c3d90600f850160041c600f7fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb592601e8860011b1680611c43575b500160041c820191016130e8565b38610878565b611c7d907fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb485019060001982549160200360031b1c169055565b38611c2f565b90503d8083833e611c948183612e15565b810190602081830312610ee55780519067ffffffffffffffff821161052c57019080601f83011215610ee557815190611ccc8261304a565b92611cda6040519485612e15565b82845260208085019360051b820101918211611d1f57602001915b818310611d055750505038610843565b82518060010b81036105df57815260209283019201611cf5565b8480fd5b506020833d602011611d4e575b81611d3d60209383612e15565b81010312610f3d57602492516107fb565b3d9150611d30565b506020813d602011611d8e575b81611d7060209383612e15565b81010312610ee557611d896001600160a01b0391612e38565b6107b3565b3d9150611d63565b506020813d602011611dce575b81611db060209383612e15565b81010312610ee557611dc96001600160a01b0391612e38565b61076d565b3d9150611da3565b506020813d602011611e0e575b81611df060209383612e15565b81010312610ee557611e096001600160a01b0391612e38565b610727565b3d9150611de3565b506020813d602011611e4e575b81611e3060209383612e15565b81010312610ee557611e496001600160a01b0391612e38565b6106e1565b3d9150611e23565b506020813d602011611e8e575b81611e7060209383612e15565b81010312610ee557611e896001600160a01b0391612e38565b61069b565b3d9150611e63565b60046040517fe1010280000000000000000000000000000000000000000000000000000000008152fd5b503461011857602060031936011261011857611eda612d66565b6001600160a01b03600754166040517fdf0fbb650000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024916020828481845afa9182156122e15785926128ae575b50604051907f527335610000000000000000000000000000000000000000000000000000000082526001600160a01b03851660048301526020828581845afa9182156125c057869261288d575b50859260175442106125cb575b505090611fa463ffffffff611fa9935116612f93565b612e95565b8382856001600160a01b03600a5416604051928380927f9d138fb80000000000000000000000000000000000000000000000000000000082526001600160a01b038a1660048301525afa80156125c05786918791612494575b50805190816122ec575b50505061201891612e95565b918390846001600160a01b038481600b54169360405194859384927f074fece60000000000000000000000000000000000000000000000000000000084521660048301525afa80156122e157859086928791612275575b50607d036120cf575050606481018091116120bc57925b662386f26fc10000938481029481860414901517156120ab57602061019c8585612e95565b634e487b7160e01b81526011600452fd5b5082634e487b7160e01b81526011600452fd5b60019593909290918690855b85519260ff8083169485108061226a575b156121875760066120fd868a613062565b511015612130575050612111879387613062565b5115612126575b612121906130d7565b6120db565b9597508795612118565b909361213c9088613062565b5161214683612caf565b929054600393841b1c1614612160575b50612121906130d7565b849194018091116121745792612121612156565b8487634e487b7160e01b81526011600452fd5b509198939495505082915081612262575b501561224857506002810180911161223557935b825b815160ff908183169081108061222a575b15612220576121cf829185613062565b516121d984612d29565b929054600393841b1c16146121f9575b50506121f4906130d7565b6121ae565b9661221891839861220c6121f495612c5c565b9054911b1c1690612e95565b9590386121e9565b5050505090612086565b5060105481106121bf565b5090634e487b7160e01b81526011600452fd5b949094156121ac57936001810180911161223557936121ac565b905038612198565b50600f5485106120ec565b925050503d8086833e6122888183612e15565b8101906060818303126105df57805167ffffffffffffffff908181116122dd57836122b4918401613076565b9260208301519182116122dd576122d1604091607d938501613076565b9201519291929061206f565b8780fd5b6040513d87823e3d90fd5b600954929391928891906001600160a01b03165b84831061239957505050662386f26fc1000090818102918183041490151715612174578160011b9082820460021483151715612386579161ffff608061234e61201897969461236f96612f66565b93015116036123785766ffffffffffffff666a94d74f4300005b1690612e95565b9091388061200c565b66ffffffffffffff87612368565b8588634e487b7160e01b81526011600452fd5b9091926123a68484613062565b5151604051907f4378a6e300000000000000000000000000000000000000000000000000000000825260048201526080818a81865afa908115612489578b91612409575b5060019161ffff60206124009301511690612e95565b93019190612300565b90506080813d608011612481575b8161242460809383612e15565b8101031261247d5760019161ffff6020612400936040519061244582612de5565b80518252612454838201612ea2565b8383015261246460408201612ea2565b60408301526060809101519082015293505050916123ea565b8a80fd5b3d9150612417565b6040513d8d823e3d90fd5b9150503d8087833e6124a68183612e15565b6101208282810103126125bc576124bc82612e38565b506124cc81830160208401612ebf565b9061010083015167ffffffffffffffff81116125b857830190808401601f830112156125b8578151906124fe8261304a565b9461250c6040519687612e15565b828652602086019382820160208560061b830101116125b45760208101945b60208560061b8301018610612547575050505050509038612002565b60408685850103126125b05760405180604081011067ffffffffffffffff60408301111761259d57602080939282604080940184528951815261258b838b01612e4c565b8382015281520196019590915061252b565b8b8e634e487b7160e01b81526041600452fd5b8c80fd5b8b80fd5b8880fd5b8680fd5b6040513d88823e3d90fd5b909580959493505084906001600160a01b036008541660405180917f664d88840000000000000000000000000000000000000000000000000000000082526001600160a01b0388166004830152818760809485935afa988915612882578891899a6127e8575b50826001600160a01b0360408c01511688604051809481937fd4f4babe00000000000000000000000000000000000000000000000000000000835260048301525afa9283156127dd578993612772575b505061269f575b50949550929350909190611fa463ffffffff611f8e565b602090519701918251977f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff89168903612386576126fc81611fa99798999a6126f4670de0b6b3a764000094859260011b612dbc565b049551612dbc565b0460011c928083106127235750505050611fa463ffffffff6016545b918796959450612688565b8383611fa49563ffffffff95101561273e575b505050612718565b61276a93509061275e612764926127588360165492612f86565b90612dbc565b92612f86565b90612f66565b388080612736565b9080929350813d83116127d6575b61278a8183612e15565b810103126122dd576127c96060604051926127a484612de5565b80518452602081015160208501526127be60408201612eb1565b604085015201612f59565b6060820152903880612681565b503d612780565b6040513d8b823e3d90fd5b9150985080823d841161287b575b6128008183612e15565b8101038281126125b8576060601f1961281884612f59565b9201126125b857604051916060830183811067ffffffffffffffff8211176128685761285b91606091604052602081015185526040810151602086015201612e38565b6040830152909838612631565b888b634e487b7160e01b81526041600452fd5b503d6127f6565b6040513d8a823e3d90fd5b6128a791925060203d6020116101ca576101bc8183612e15565b9038611f81565b9091506020813d6020116128da575b816128ca60209383612e15565b81010312611d1f57519038611f34565b3d91506128bd565b5034610118578060031936011261011857602060ff60125416604051908152f35b50346101185760206003193601126101185760043590600d5482101561011857602061292e83612d7c565b90546040519160031b1c60010b8152f35b503461011857604060031936011261011857612959612d66565b6001600160a01b0390818354166040519263bcaa0c5560e01b808552600c60048601526020948581602481875afa8015612b0c5783918891612ad4575b50168015612aa3573303612a795784906024604051809581938252600c60048301525afa80156122e15784928691612a41575b50604490868360405196879586947faad3ec960000000000000000000000000000000000000000000000000000000086521660048501526024356024850152165af18015610ef157612a19578280f35b813d8311612a3a575b612a2c8183612e15565b810103126101185738808280f35b503d612a22565b83819492503d8311612a72575b612a588183612e15565b81010312611d1f576044612a6c8593612e38565b906129c9565b503d612a4e565b60046040517f1a48f084000000000000000000000000000000000000000000000000000000008152fd5b60246040517f92bc2cd0000000000000000000000000000000000000000000000000000000008152600c6004820152fd5b809250878092503d8311612b05575b612aed8183612e15565b810103126125bc57612aff8391612e38565b38612996565b503d612ae3565b6040513d89823e3d90fd5b50346101185780600319360112610118576001600160a01b036020915416604051908152f35b503461011857806003193601126101185760206001600160a01b0360035416604051908152f35b50346101185760206003193601126101185760043590600e5482101561011857602060ff61020984612cec565b503461011857806003193601126101185760206001600160a01b0360055416604051908152f35b50346101185760206003193601126101185760043590600f5482101561011857602060ff61020984612caf565b5034610118576020600319360112610118576004359060115482101561011857602060ff61020984612c5c565b905034610f3d5781600319360112610f3d57600c54662386f26fc1000090818102918183041490151715612c4857602092508152f35b602483634e487b7160e01b81526011600452fd5b90601154821015612c99576011600052601f8260051c7f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6801921690565b634e487b7160e01b600052603260045260246000fd5b90600f54821015612c9957600f600052601f8260051c7f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80201921690565b90600e54821015612c9957600e600052601f8260051c7fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd01921690565b90601054821015612c99576010600052601f8260051c7f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67201921690565b600435906001600160a01b0382168203610fc757565b90600d54821015612c9957600d600052601e8260041c7fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5019260011b1690565b81810292918115918404141715612dcf57565b634e487b7160e01b600052601160045260246000fd5b6080810190811067ffffffffffffffff82111761137b57604052565b67ffffffffffffffff811161137b57604052565b90601f601f19910116810190811067ffffffffffffffff82111761137b57604052565b51906001600160a01b0382168203610fc757565b519063ffffffff82168203610fc757565b90816020910312610fc75760405190602082019082821067ffffffffffffffff83111761137b57612e9091604052612e4c565b815290565b91908201809211612dcf57565b519061ffff82168203610fc757565b519060ff82168203610fc757565b91908260e0910312610fc75760405160e0810181811067ffffffffffffffff82111761137b576040528092612ef381612e4c565b8252612f0160208201612e4c565b6020830152612f1260408201612e4c565b60408301526060810151906006821015610fc75760c0612f549181936060860152612f3f60808201612ea2565b608086015260a081015160a086015201612e38565b910152565b51908115158203610fc757565b8115612f70570490565b634e487b7160e01b600052601260045260246000fd5b91908203918211612dcf57565b906000916000906201518063ffffffff8092160416601e811015612fb5575050565b909192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2810190811161303657668e1bc9bf040000918183029283048203613022576701f161421c8e00009180830292830403613022575090600f603c61301f93049104612e95565b90565b80634e487b7160e01b602492526011600452fd5b602482634e487b7160e01b81526011600452fd5b67ffffffffffffffff811161137b5760051b60200190565b8051821015612c995760209160051b010190565b9080601f83011215610fc7578151906020916130918161304a565b9361309f6040519586612e15565b81855260208086019260051b820101928311610fc757602001905b8282106130c8575050505090565b815181529083019083016130ba565b60ff1660ff8114612dcf5760010190565b8181106130f3575050565b600081556001016130e8565b6020908181840312610fc75780519067ffffffffffffffff8211610fc757019180601f84011215610fc75782516131358161304a565b936131436040519586612e15565b818552838086019260051b820101928311610fc7578301905b82821061316a575050505090565b83809161317684612eb1565b81520191019061315c565b6001600160a01b038091169081156132935780600154161561328f5760035481168061322e57503082036131c5575b505b6001600160a01b03196003541617600355565b60015416803b15610fc757600080916024604051809481937feb8646980000000000000000000000000000000000000000000000000000000083528760048401525af1801561322257156131b05761321c90612e01565b386131b0565b6040513d6000823e3d90fd5b8091503b15610fc757600080916024604051809481937f3a74bfd70000000000000000000000000000000000000000000000000000000083528760048401525af1801561322257613280575b506131b2565b61328990612e01565b3861327a565b5050565b60046040517f05d8ce3d000000000000000000000000000000000000000000000000000000008152fdfea26469706673582212204464f9c7259dafca3bdf8f971cb155d07eea27a4daad525c42ca2556cf17532c64736f6c63430008190033000000000000000000000000ef173bb4b36525974bf6711357d2c6c12b8001ec
Deployed Bytecode
0x608080604052600436101561001357600080fd5b600090813560e01c9081631389930314612c12575080631714818b14612be55780631f89561e14612bb857806331a0edec14612b9157806339928cf714612b645780633cdad82c14612b3d578063443b178614612b175780634b03eeb41461293f5780634f73a920146129035780635c806e9f146128e2578063679c93b914611ec05780638da52e931461064e578063ad5c464814610627578063b930b48214610600578063c049072214610237578063ce7842f514610219578063d5994276146101dc578063df89ff781461011b5763fce14af6146100f257600080fd5b3461011857806003193601126101185760206001600160a01b0360015416604051908152f35b80fd5b503461011857602060031936011261011857610135612d66565b60206001600160a01b03602481600754169360405194859384927f527335610000000000000000000000000000000000000000000000000000000084521660048301525afa9081156101d15761019c9163ffffffff91602094916101a4575b505116612f93565b604051908152f35b6101c49150843d86116101ca575b6101bc8183612e15565b810190612e5d565b38610194565b503d6101b2565b6040513d84823e3d90fd5b5034610118576020600319360112610118576004359060105482101561011857602060ff61020984612d29565b9190546040519260031b1c168152f35b50346101185780600319360112610118576020600c54604051908152f35b503461011857604060031936011261011857610251612d66565b90602491826001600160a01b039160a08360095416604051938480927fd20264ca000000000000000000000000000000000000000000000000000000008252823560048301525afa918215610537578492610542575b5082600a54166040519384927f5c12cd4b00000000000000000000000000000000000000000000000000000000845216600483015281866101009384935afa9283156105375784936104eb575b50508051600781101561048857600e54111561049c57805191600783101561048857610321604093612cec565b93905492015190600682101561046257600582029180830460051490151715610475576060015160068110156104625761035a91612e95565b600d54811015610432579061037060ff92612d7c565b90549060031b1c840b9260031b1c16820b017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff80008112617fff8213176104205760010b662386f26fc10000908082029182050361042057602092507ffffffffffffffffffffffffffffffffffffffffffffffffffd39750f44ec0000908181121561041957505b670de0b6b3a76400009150818113156104125750604051908152f35b905061019c565b90506103f6565b50634e487b7160e01b81526011600452fd5b8490604051907f1dd219080000000000000000000000000000000000000000000000000000000082526004820152fd5b8585634e487b7160e01b81526021600452fd5b8585634e487b7160e01b81526011600452fd5b505050634e487b7160e01b81526021600452fd5b9050519060078210156104d85750604051907f526a55b60000000000000000000000000000000000000000000000000000000082526004820152fd5b9050634e487b7160e01b81526021600452fd5b90809293503d8311610530575b6105028183612e15565b8101918183031261052c579060208261051d61052494612e38565b5001612ebf565b9038806102f4565b8380fd5b503d6104f8565b6040513d86823e3d90fd5b90915060a0813d60a0116105f8575b8161055e60a09383612e15565b8101031261052c576040519060a0820182811067ffffffffffffffff8211176105e357604052805160078110156105df57825261059d60208201612ea2565b6020830152604081015160068110156105df576105d39160809160408501526105c860608201612eb1565b606085015201612e4c565b608082015290386102a7565b8580fd5b86634e487b7160e01b60005260416004526000fd5b3d9150610551565b503461011857806003193601126101185760206001600160a01b0360025416604051908152f35b503461011857806003193601126101185760206001600160a01b0360065416604051908152f35b50346101185780600319360112610118576001600160a01b03815416803303611e965760405163bcaa0c5560e01b815260056004820152602081602481855afa8015610ef1578390611e56575b6001600160a01b039150166001600160a01b0319600854161760085560405163bcaa0c5560e01b815260026004820152602081602481855afa8015610ef1578390611e16575b6001600160a01b039150166001600160a01b0319600754161760075560405163bcaa0c5560e01b815260156004820152602081602481855afa8015610ef1578390611dd6575b6001600160a01b039150166001600160a01b0319600954161760095560405163bcaa0c5560e01b815260036004820152602081602481855afa8015610ef1578390611d96575b6001600160a01b039150166001600160a01b0319600a541617600a5560405163bcaa0c5560e01b815260096004820152602081602481855afa8015610ef1578390611d56575b6001600160a01b039150166001600160a01b0319600b541617600b5581604051916342ab14dd60e01b835260216004840152602083602481845afa80156101d1578290611d23575b60249350600c55604051928380927fb371dd90000000000000000000000000000000000000000000000000000000008252602260048301525afa9081156101d1578291611c83575b5080519067ffffffffffffffff82116116785768010000000000000000821161167857602090600d5483600d55808410611bf3575b500190600d8352825b8160041c8110611b9357507ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff08116808203611b2a575b5050506024816001600160a01b03815416604051928380926341a2549360e11b8252602360048301525afa9081156101d1578291611b10575b5080519067ffffffffffffffff82116116785768010000000000000000821161167857602090600e5483600e55808410611a8b575b500190600e8352825b8160051c8110611a2c5750601f1981168082036119bd575b5050506001600160a01b0381541681604051916342ab14dd60e01b835260266004840152602083602481845afa9283156101d1578293611988575b5060ff602493167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff006012541617601255604051928380926341a2549360e11b8252602760048301525afa9081156101d157829161196e575b5080519067ffffffffffffffff82116116785768010000000000000000821161167857602090600f5483600f558084106118e9575b500190600f8352825b8160051c811061188a5750601f19811680820361181b575b5050506024816001600160a01b03815416604051928380926341a2549360e11b8252602860048301525afa9081156101d1578291611801575b5080519067ffffffffffffffff821161167857680100000000000000008211611678576020906010548360105580841061177c575b50019060108352825b8160051c811061171d5750601f1981168082036116ae575b5050506024816001600160a01b03815416604051928380926341a2549360e11b8252602960048301525afa9081156101d157829161168c575b5080519067ffffffffffffffff82116116785768010000000000000000821161167857602090601154836011558084106115ec575b50019060118352825b8160051c811061158d5750601f19811680820361151e575b5050506001600160a01b038154166040516342ab14dd60e01b8152602f6004820152602081602481855afa908115610ef15783916114ec575b506013556040516342ab14dd60e01b815260306004820152602081602481855afa908115610ef15783916114ba575b506014556040516342ab14dd60e01b815260316004820152602081602481855afa908115610ef1578391611488575b506015556040516342ab14dd60e01b8152603d6004820152602081602481855afa908115610ef1578391611456575b506016556040516342ab14dd60e01b8152603e6004820152602081602481855afa908115610ef1578391611423575b50602492916020916017556040519384809263bcaa0c5560e01b8252600f60048301525afa9182156114165781926113da575b506001546001600160a01b038316906001600160a01b038116820361122b575b505090506001600160a01b038154168160405163bcaa0c5560e01b815260106004820152602081602481865afa9081156101d15782916111f1575b506001600160a01b036002549116906001600160a01b03811682036110df575b505090506001600160a01b038154166040519063bcaa0c5560e01b825260126004830152602082602481845afa918215610ef157839261109e575b5060206024916040519283809263bcaa0c5560e01b8252601360048301525afa918215610ef1578391829361105c575b506001600160a01b0360055491166001600160a01b0382168103610fd3575b5050506001600160a01b0360065491166001600160a01b0382168103610f49575b505060206001600160a01b0360249254166040519283809263bcaa0c5560e01b8252600c60048301525afa9081156101d1578291610f0b575b506001600160a01b038116610efc575b5080546040517ff2aac76c000000000000000000000000000000000000000000000000000000008152600160048201526020816024816001600160a01b0386165afa908115610ef1578391610e7b575b5074ff00000000000000000000000000000000000000007fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff91151560a01b16911617815580f35b90506020813d602011610ee9575b81610e9660209383612e15565b81010312610ee55774ff0000000000000000000000000000000000000000610ede7fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff92612f59565b9150610e34565b8280fd5b3d9150610e89565b6040513d85823e3d90fd5b610f0590613181565b38610de4565b90506020813d602011610f41575b81610f2660209383612e15565b81010312610f3d57610f3790612e38565b38610dd4565b5080fd5b3d9150610f19565b806001600160a01b031960209316176006556024604051809481937f1a33757d000000000000000000000000000000000000000000000000000000008352600260048401525af180156101d157610fa3575b808291610d9b565b602090813d8311610fcc575b610fb98183612e15565b81010312610fc75738610f9b565b600080fd5b503d610faf565b806001600160a01b031960209316176005556024604051809481937f1a33757d000000000000000000000000000000000000000000000000000000008352600260048401525af18015610ef15761102d575b808391610d7a565b6020809293503d8311611055575b6110458183612e15565b81010312610fc757819038611025565b503d61103b565b915091506020813d602011611096575b8161107960209383612e15565b810103126110925761108b8391612e38565b9138610d5b565b5050fd5b3d915061106c565b9091506020813d6020116110d7575b816110ba60209383612e15565b810103126110925760206110cf602492612e38565b929150610d2b565b3d91506110ad565b6020602494836001600160a01b03198416176002556040519586809263bcaa0c5560e01b8252601160048301525afa938415610ef15783946111b5575b506001600160a01b0360045416610cf05782161791823b15610f3d57816001600160a01b036024829360405194859384927f36b91f2b00000000000000000000000000000000000000000000000000000000845216978860048401525af180156101d1576111a1575b50506001600160a01b0319600454161760045538818180610cf0565b6111aa90612e01565b610f3d578138611185565b9093506020813d6020116111e9575b816111d160209383612e15565b81010312610ee5576111e290612e38565b923861111c565b3d91506111c4565b90506020813d602011611223575b8161120c60209383612e15565b81010312610f3d5761121d90612e38565b38610cd0565b3d91506111ff565b6001600160a01b03191681176001556040517ffe9fbb80000000000000000000000000000000000000000000000000000000008152306004820152602081602481855afa908115610ef15783916113a0575b50611289575b80610c95565b803b15610f3d578180916004604051809481937f4e606c470000000000000000000000000000000000000000000000000000000083525af180156101d157611391575b509060405160208101917ff098767a00000000000000000000000000000000000000000000000000000000835260048252604082019282841067ffffffffffffffff85111761137b5784809493819460405251925af1503d15611376573d67ffffffffffffffff811161136257604051906113516020601f19601f8401160183612e15565b81528160203d92013e5b8038611283565b602482634e487b7160e01b81526041600452fd5b61135b565b634e487b7160e01b600052604160045260246000fd5b61139a90612e01565b386112cc565b90506020813d6020116113d2575b816113bb60209383612e15565b81010312610ee5576113cc90612f59565b3861127d565b3d91506113ae565b9091506020813d60201161140e575b816113f660209383612e15565b81010312610f3d5761140790612e38565b9038610c75565b3d91506113e9565b50604051903d90823e3d90fd5b90506020813d60201161144e575b8161143e60209383612e15565b81010312610ee557516024610c42565b3d9150611431565b90506020813d602011611480575b8161147160209383612e15565b81010312610ee5575138610c13565b3d9150611464565b90506020813d6020116114b2575b816114a360209383612e15565b81010312610ee5575138610be4565b3d9150611496565b90506020813d6020116114e4575b816114d560209383612e15565b81010312610ee5575138610bb5565b3d91506114c8565b90506020813d602011611516575b8161150760209383612e15565b81010312610ee5575138610b86565b3d91506114fa565b918392845b818403811061155d5750505060051c7f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c680155388080610b4d565b90919360206115836001928460ff895116919060ff809160031b9316831b921b19161790565b9501929101611523565b83845b602081106115c557507f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c68820155600101610b35565b845190949160019160209160ff600389901b81811b199092169216901b1792019401611590565b61163290601f850160051c601f7f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c689281881680611638575b500160051c820191016130e8565b38610b2c565b611672907f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6785019060001982549160200360031b1c169055565b38611624565b602483634e487b7160e01b81526041600452fd5b6116a891503d8084833e6116a08183612e15565b8101906130ff565b38610af7565b918392845b81840381106116ed5750505060051c7f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6720155388080610abe565b90919360206117136001928460ff895116919060ff809160031b9316831b921b19161790565b95019291016116b3565b83845b6020811061175557507f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae672820155600101610aa6565b845190949160019160209160ff600389901b81811b199092169216901b1792019401611720565b6117c190601f850160051c601f7f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67292818816806117c757500160051c820191016130e8565b38610a9d565b611672907f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67185019060001982549160200360031b1c169055565b61181591503d8084833e6116a08183612e15565b38610a68565b918392845b818403811061185a5750505060051c7f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020155388080610a2f565b90919360206118806001928460ff895116919060ff809160031b9316831b921b19161790565b9501929101611820565b83845b602081106118c257507f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802820155600101610a17565b845190949160019160209160ff600389901b81811b199092169216901b179201940161188d565b61192e90601f850160051c601f7f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802928188168061193457500160051c820191016130e8565b38610a0e565b611672907f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80185019060001982549160200360031b1c169055565b61198291503d8084833e6116a08183612e15565b386109d9565b92506020833d6020116119b5575b816119a360209383612e15565b81010312610f3d5791519160ff610981565b3d9150611996565b918392845b81840381106119fc5750505060051c7fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0155388080610946565b9091936020611a226001928460ff895116919060ff809160031b9316831b921b19161790565b95019291016119c2565b83845b60208110611a6457507fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd82015560010161092e565b845190949160019160209160ff600389901b81811b199092169216901b1792019401611a2f565b611ad090601f850160051c601f7fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd9281881680611ad657500160051c820191016130e8565b38610925565b611672907fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fc85019060001982549160200360031b1c169055565b611b2491503d8084833e6116a08183612e15565b386108f0565b918392845b8184038110611b695750505060041c7fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb501553880806108b7565b825161ffff908116600483901b90811b91901b199095169490941793602090920191600101611b2f565b83845b60108110611bcb57507fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5820155600101610881565b845190949160019160209161ffff600489901b81811b199092169216901b1792019401611b96565b611c3d90600f850160041c600f7fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb592601e8860011b1680611c43575b500160041c820191016130e8565b38610878565b611c7d907fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb485019060001982549160200360031b1c169055565b38611c2f565b90503d8083833e611c948183612e15565b810190602081830312610ee55780519067ffffffffffffffff821161052c57019080601f83011215610ee557815190611ccc8261304a565b92611cda6040519485612e15565b82845260208085019360051b820101918211611d1f57602001915b818310611d055750505038610843565b82518060010b81036105df57815260209283019201611cf5565b8480fd5b506020833d602011611d4e575b81611d3d60209383612e15565b81010312610f3d57602492516107fb565b3d9150611d30565b506020813d602011611d8e575b81611d7060209383612e15565b81010312610ee557611d896001600160a01b0391612e38565b6107b3565b3d9150611d63565b506020813d602011611dce575b81611db060209383612e15565b81010312610ee557611dc96001600160a01b0391612e38565b61076d565b3d9150611da3565b506020813d602011611e0e575b81611df060209383612e15565b81010312610ee557611e096001600160a01b0391612e38565b610727565b3d9150611de3565b506020813d602011611e4e575b81611e3060209383612e15565b81010312610ee557611e496001600160a01b0391612e38565b6106e1565b3d9150611e23565b506020813d602011611e8e575b81611e7060209383612e15565b81010312610ee557611e896001600160a01b0391612e38565b61069b565b3d9150611e63565b60046040517fe1010280000000000000000000000000000000000000000000000000000000008152fd5b503461011857602060031936011261011857611eda612d66565b6001600160a01b03600754166040517fdf0fbb650000000000000000000000000000000000000000000000000000000081526001600160a01b03831660048201526024916020828481845afa9182156122e15785926128ae575b50604051907f527335610000000000000000000000000000000000000000000000000000000082526001600160a01b03851660048301526020828581845afa9182156125c057869261288d575b50859260175442106125cb575b505090611fa463ffffffff611fa9935116612f93565b612e95565b8382856001600160a01b03600a5416604051928380927f9d138fb80000000000000000000000000000000000000000000000000000000082526001600160a01b038a1660048301525afa80156125c05786918791612494575b50805190816122ec575b50505061201891612e95565b918390846001600160a01b038481600b54169360405194859384927f074fece60000000000000000000000000000000000000000000000000000000084521660048301525afa80156122e157859086928791612275575b50607d036120cf575050606481018091116120bc57925b662386f26fc10000938481029481860414901517156120ab57602061019c8585612e95565b634e487b7160e01b81526011600452fd5b5082634e487b7160e01b81526011600452fd5b60019593909290918690855b85519260ff8083169485108061226a575b156121875760066120fd868a613062565b511015612130575050612111879387613062565b5115612126575b612121906130d7565b6120db565b9597508795612118565b909361213c9088613062565b5161214683612caf565b929054600393841b1c1614612160575b50612121906130d7565b849194018091116121745792612121612156565b8487634e487b7160e01b81526011600452fd5b509198939495505082915081612262575b501561224857506002810180911161223557935b825b815160ff908183169081108061222a575b15612220576121cf829185613062565b516121d984612d29565b929054600393841b1c16146121f9575b50506121f4906130d7565b6121ae565b9661221891839861220c6121f495612c5c565b9054911b1c1690612e95565b9590386121e9565b5050505090612086565b5060105481106121bf565b5090634e487b7160e01b81526011600452fd5b949094156121ac57936001810180911161223557936121ac565b905038612198565b50600f5485106120ec565b925050503d8086833e6122888183612e15565b8101906060818303126105df57805167ffffffffffffffff908181116122dd57836122b4918401613076565b9260208301519182116122dd576122d1604091607d938501613076565b9201519291929061206f565b8780fd5b6040513d87823e3d90fd5b600954929391928891906001600160a01b03165b84831061239957505050662386f26fc1000090818102918183041490151715612174578160011b9082820460021483151715612386579161ffff608061234e61201897969461236f96612f66565b93015116036123785766ffffffffffffff666a94d74f4300005b1690612e95565b9091388061200c565b66ffffffffffffff87612368565b8588634e487b7160e01b81526011600452fd5b9091926123a68484613062565b5151604051907f4378a6e300000000000000000000000000000000000000000000000000000000825260048201526080818a81865afa908115612489578b91612409575b5060019161ffff60206124009301511690612e95565b93019190612300565b90506080813d608011612481575b8161242460809383612e15565b8101031261247d5760019161ffff6020612400936040519061244582612de5565b80518252612454838201612ea2565b8383015261246460408201612ea2565b60408301526060809101519082015293505050916123ea565b8a80fd5b3d9150612417565b6040513d8d823e3d90fd5b9150503d8087833e6124a68183612e15565b6101208282810103126125bc576124bc82612e38565b506124cc81830160208401612ebf565b9061010083015167ffffffffffffffff81116125b857830190808401601f830112156125b8578151906124fe8261304a565b9461250c6040519687612e15565b828652602086019382820160208560061b830101116125b45760208101945b60208560061b8301018610612547575050505050509038612002565b60408685850103126125b05760405180604081011067ffffffffffffffff60408301111761259d57602080939282604080940184528951815261258b838b01612e4c565b8382015281520196019590915061252b565b8b8e634e487b7160e01b81526041600452fd5b8c80fd5b8b80fd5b8880fd5b8680fd5b6040513d88823e3d90fd5b909580959493505084906001600160a01b036008541660405180917f664d88840000000000000000000000000000000000000000000000000000000082526001600160a01b0388166004830152818760809485935afa988915612882578891899a6127e8575b50826001600160a01b0360408c01511688604051809481937fd4f4babe00000000000000000000000000000000000000000000000000000000835260048301525afa9283156127dd578993612772575b505061269f575b50949550929350909190611fa463ffffffff611f8e565b602090519701918251977f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff89168903612386576126fc81611fa99798999a6126f4670de0b6b3a764000094859260011b612dbc565b049551612dbc565b0460011c928083106127235750505050611fa463ffffffff6016545b918796959450612688565b8383611fa49563ffffffff95101561273e575b505050612718565b61276a93509061275e612764926127588360165492612f86565b90612dbc565b92612f86565b90612f66565b388080612736565b9080929350813d83116127d6575b61278a8183612e15565b810103126122dd576127c96060604051926127a484612de5565b80518452602081015160208501526127be60408201612eb1565b604085015201612f59565b6060820152903880612681565b503d612780565b6040513d8b823e3d90fd5b9150985080823d841161287b575b6128008183612e15565b8101038281126125b8576060601f1961281884612f59565b9201126125b857604051916060830183811067ffffffffffffffff8211176128685761285b91606091604052602081015185526040810151602086015201612e38565b6040830152909838612631565b888b634e487b7160e01b81526041600452fd5b503d6127f6565b6040513d8a823e3d90fd5b6128a791925060203d6020116101ca576101bc8183612e15565b9038611f81565b9091506020813d6020116128da575b816128ca60209383612e15565b81010312611d1f57519038611f34565b3d91506128bd565b5034610118578060031936011261011857602060ff60125416604051908152f35b50346101185760206003193601126101185760043590600d5482101561011857602061292e83612d7c565b90546040519160031b1c60010b8152f35b503461011857604060031936011261011857612959612d66565b6001600160a01b0390818354166040519263bcaa0c5560e01b808552600c60048601526020948581602481875afa8015612b0c5783918891612ad4575b50168015612aa3573303612a795784906024604051809581938252600c60048301525afa80156122e15784928691612a41575b50604490868360405196879586947faad3ec960000000000000000000000000000000000000000000000000000000086521660048501526024356024850152165af18015610ef157612a19578280f35b813d8311612a3a575b612a2c8183612e15565b810103126101185738808280f35b503d612a22565b83819492503d8311612a72575b612a588183612e15565b81010312611d1f576044612a6c8593612e38565b906129c9565b503d612a4e565b60046040517f1a48f084000000000000000000000000000000000000000000000000000000008152fd5b60246040517f92bc2cd0000000000000000000000000000000000000000000000000000000008152600c6004820152fd5b809250878092503d8311612b05575b612aed8183612e15565b810103126125bc57612aff8391612e38565b38612996565b503d612ae3565b6040513d89823e3d90fd5b50346101185780600319360112610118576001600160a01b036020915416604051908152f35b503461011857806003193601126101185760206001600160a01b0360035416604051908152f35b50346101185760206003193601126101185760043590600e5482101561011857602060ff61020984612cec565b503461011857806003193601126101185760206001600160a01b0360055416604051908152f35b50346101185760206003193601126101185760043590600f5482101561011857602060ff61020984612caf565b5034610118576020600319360112610118576004359060115482101561011857602060ff61020984612c5c565b905034610f3d5781600319360112610f3d57600c54662386f26fc1000090818102918183041490151715612c4857602092508152f35b602483634e487b7160e01b81526011600452fd5b90601154821015612c99576011600052601f8260051c7f31ecc21a745e3968a04e9570e4425bc18fa8019c68028196b546d1669c200c6801921690565b634e487b7160e01b600052603260045260246000fd5b90600f54821015612c9957600f600052601f8260051c7f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac80201921690565b90600e54821015612c9957600e600052601f8260051c7fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd01921690565b90601054821015612c99576010600052601f8260051c7f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae67201921690565b600435906001600160a01b0382168203610fc757565b90600d54821015612c9957600d600052601e8260041c7fd7b6990105719101dabeb77144f2a3385c8033acd3af97e9423a695e81ad1eb5019260011b1690565b81810292918115918404141715612dcf57565b634e487b7160e01b600052601160045260246000fd5b6080810190811067ffffffffffffffff82111761137b57604052565b67ffffffffffffffff811161137b57604052565b90601f601f19910116810190811067ffffffffffffffff82111761137b57604052565b51906001600160a01b0382168203610fc757565b519063ffffffff82168203610fc757565b90816020910312610fc75760405190602082019082821067ffffffffffffffff83111761137b57612e9091604052612e4c565b815290565b91908201809211612dcf57565b519061ffff82168203610fc757565b519060ff82168203610fc757565b91908260e0910312610fc75760405160e0810181811067ffffffffffffffff82111761137b576040528092612ef381612e4c565b8252612f0160208201612e4c565b6020830152612f1260408201612e4c565b60408301526060810151906006821015610fc75760c0612f549181936060860152612f3f60808201612ea2565b608086015260a081015160a086015201612e38565b910152565b51908115158203610fc757565b8115612f70570490565b634e487b7160e01b600052601260045260246000fd5b91908203918211612dcf57565b906000916000906201518063ffffffff8092160416601e811015612fb5575050565b909192507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe2810190811161303657668e1bc9bf040000918183029283048203613022576701f161421c8e00009180830292830403613022575090600f603c61301f93049104612e95565b90565b80634e487b7160e01b602492526011600452fd5b602482634e487b7160e01b81526011600452fd5b67ffffffffffffffff811161137b5760051b60200190565b8051821015612c995760209160051b010190565b9080601f83011215610fc7578151906020916130918161304a565b9361309f6040519586612e15565b81855260208086019260051b820101928311610fc757602001905b8282106130c8575050505090565b815181529083019083016130ba565b60ff1660ff8114612dcf5760010190565b8181106130f3575050565b600081556001016130e8565b6020908181840312610fc75780519067ffffffffffffffff8211610fc757019180601f84011215610fc75782516131358161304a565b936131436040519586612e15565b818552838086019260051b820101928311610fc7578301905b82821061316a575050505090565b83809161317684612eb1565b81520191019061315c565b6001600160a01b038091169081156132935780600154161561328f5760035481168061322e57503082036131c5575b505b6001600160a01b03196003541617600355565b60015416803b15610fc757600080916024604051809481937feb8646980000000000000000000000000000000000000000000000000000000083528760048401525af1801561322257156131b05761321c90612e01565b386131b0565b6040513d6000823e3d90fd5b8091503b15610fc757600080916024604051809481937f3a74bfd70000000000000000000000000000000000000000000000000000000083528760048401525af1801561322257613280575b506131b2565b61328990612e01565b3861327a565b5050565b60046040517f05d8ce3d000000000000000000000000000000000000000000000000000000008152fdfea26469706673582212204464f9c7259dafca3bdf8f971cb155d07eea27a4daad525c42ca2556cf17532c64736f6c63430008190033
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
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.