ERC-20
Overview
Max Total Supply
90,674,971.785358746105779966 GRILLA
Holders
1,067
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
2,766.033565 GRILLAValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
GrillaToken
Compiler Version
v0.8.12+commit.f00d7308
Contract Source Code (Solidity Multiple files format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import "./ERC20.sol"; import "./Ownable.sol"; import "./JungleSerum.sol"; import "./CyberGorillasStaking.sol"; /* ______ __ ______ _ ____ / ____/_ __/ /_ ___ _____/ ____/___ _____(_) / /___ ______ / / / / / / __ \/ _ \/ ___/ / __/ __ \/ ___/ / / / __ `/ ___/ / /___/ /_/ / /_/ / __/ / / /_/ / /_/ / / / / / / /_/ (__ ) \____/\__, /_.___/\___/_/ \____/\____/_/ /_/_/_/\__,_/____/ /____/ */ /// @title Grilla Token /// @author delta devs (https://twitter.com/deltadevelopers) contract GrillaToken is ERC20, Ownable { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ /// @notice Emitted by `buyOffChainUtility` function. /// @dev Event logging when utility has been purchased. /// @param sender Address of purchaser. /// @param itemId Item identifier tied to utility. event UtilityPurchase(address indexed sender, uint256 indexed itemId); /*/////////////////////////////////////////////////////////////// STORAGE //////////////////////////////////////////////////////////////*/ /// @notice An instance of the JungleSerum contract. JungleSerum serumContract; /// @notice Retrieves price tied to specific utility item ID. mapping(uint256 => uint256) utilityPrices; /// @notice Returns true if address is authorized to make stake function calls. mapping(address => bool) authorizedStakingContracts; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor() ERC20("GRILLA", "GRILLA", 18) {} /*/////////////////////////////////////////////////////////////// MINTING LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Allows the contract deployer to mint GRILLA. /// @param account The address which will receive the minted amount. /// @param amount The amount of tokens to mint. function ownerMint(address account, uint256 amount) public onlyOwner { _mint(account, amount); } /// @notice Allows authorized staking contracts to mint GRILLA. /// @param account The address which will receive the minted amount. /// @param amount The amount of tokens to mint. function stakerMint(address account, uint256 amount) public { require( authorizedStakingContracts[msg.sender], "Request only valid from staking contract" ); _mint(account, amount); } /*/////////////////////////////////////////////////////////////// CONTRACT SETTERS //////////////////////////////////////////////////////////////*/ /// @notice Allows the contract deployer to authorize a contract to stake. /// @param staker The address to authorize. function addStakingContract(address staker) public onlyOwner { authorizedStakingContracts[staker] = true; } /// @notice Allows the contract deployer to unauthorize a contract to stake. /// @param staker The address to remove authority from. function removeStakingContract(address staker) public onlyOwner { authorizedStakingContracts[staker] = false; } /// @notice Sets the address of the JungleSerum contract. /// @param serumContractAddress The address of the JungleSerum contract. function setSerumContract(address serumContractAddress) public onlyOwner { serumContract = JungleSerum(serumContractAddress); } /*/////////////////////////////////////////////////////////////// UTILITY PURCHASING LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Purchase JungleSerum. function buySerum() public { transfer(address(serumContract), serumContract.serumPrice()); serumContract.mint(msg.sender); } /*/////////////////////////////////////////////////////////////// OFFCHAIN UTILITY PURCHASING LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Retrieves the price of a specific utility. /// @param itemId The identifier of the utility item. /// @return The price of a specific utility. function getUtilityPrice(uint256 itemId) public view returns (uint256) { return utilityPrices[itemId]; } /// @notice Allows the contract deployer to add off-chain utility data. /// @param itemId The identifier of the utility item. /// @param itemPrice The price of the utility item. function addOffchainUtility(uint256 itemId, uint256 itemPrice) public onlyOwner { utilityPrices[itemId] = itemPrice; } /// @notice Allows the contract deployer to remove off-chain utility data. /// @param itemId The identifier of the utility item. function deleteUtilityPrice(uint256 itemId) public onlyOwner { delete utilityPrices[itemId]; } /// @notice Allows the contract deployer to add off-chain utility data for multiple items. /// @param items List of multiple utility item identifiers. /// @param prices List of multiple utility item prices. function uploadUtilityPrices( uint256[] memory items, uint256[] memory prices ) public onlyOwner { for (uint256 i = 0; i < items.length; i++) { utilityPrices[items[i]] = prices[i]; } } /// @notice Buy the requested off chain utility. /// @param itemId The identifier of the utility item. function buyOffchainUtility(uint256 itemId) public { require(utilityPrices[itemId] > 0, "Invalid utility id"); transfer(address(serumContract), utilityPrices[itemId]); emit UtilityPurchase(msg.sender, itemId); } }
// SPDX-License-Identifier: Unlicense pragma solidity ^0.8.10; import "./Ownable.sol"; import "./Strings.sol"; import "./ERC721.sol"; /* ______ __ ______ _ ____ / ____/_ __/ /_ ___ _____/ ____/___ _____(_) / /___ ______ / / / / / / __ \/ _ \/ ___/ / __/ __ \/ ___/ / / / __ `/ ___/ / /___/ /_/ / /_/ / __/ / / /_/ / /_/ / / / / / / /_/ (__ ) \____/\__, /_.___/\___/_/ \____/\____/_/ /_/_/_/\__,_/____/ /____/ */ /// @title Cyber Gorillas Babies /// @author delta devs (https://twitter.com/deltadevelopers) contract CyberGorillaBabies is ERC721, Ownable { using Strings for uint256; /// @notice The address which is allowed to breed Cyber Gorillas. address private gorillaBreeder; /// @notice Base URI pointing to CyberGorillaBabies metadata. string public baseURI; /// @notice Returns true if the requested gorilla baby has the genesis trait, false otherwise. mapping(uint256 => bool) public isGenesis; constructor(string memory initialBaseURI) ERC721("Cyber Gorilla Babies", "CyberGorillaBabies") { baseURI = initialBaseURI; } /// @notice Set the address which is allowed to breed gorillas. /// @param newGorillaBreeder The target address, authorized to breed. function setGorillaBreeder(address newGorillaBreeder) public onlyOwner { gorillaBreeder = newGorillaBreeder; } /// @notice Allows the contract deployer to set the Base URI for CyberGorillaBabies' metadata. /// @param newBaseURI The new Base URI. function setBaseURI(string memory newBaseURI) public onlyOwner { baseURI = newBaseURI; } /// @notice Allows the authorized breeder address to mint a gorilla baby to a specific address. /// @param to The address to receive the minted gorilla baby. /// @param _isGenesis Whether the baby to be minted has the genesis trait or not. function mintBaby(address to, bool _isGenesis) public { require(msg.sender == gorillaBreeder, "Not Authorized"); isGenesis[totalSupply] = _isGenesis; _mint(to, totalSupply); } /// @notice Returns the token URI of a specific gorilla baby. /// @param tokenId The token ID of the requested gorilla baby. /// @return The full URI of the requested gorilla baby. function tokenURI(uint256 tokenId) public view override returns (string memory) { return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString(), ".json")) : ""; } function supportsInterface(bytes4 interfaceId) public pure override(ERC721, Ownable) returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 interfaceId == 0x5b5e139f || // ERC165 Interface ID for ERC721Metadata interfaceId == 0x7f5828d0; // ERC165 Interface ID for ERC173 } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import "./Strings.sol"; import "./ERC721.sol"; import "./Ownable.sol"; error SoldOut(); error SaleClosed(); error InvalidMintParameters(); error MintingTooMany(); error NotWhitelisted(); error NotAuthorized(); /* ______ __ ______ _ ____ / ____/_ __/ /_ ___ _____/ ____/___ _____(_) / /___ ______ / / / / / / __ \/ _ \/ ___/ / __/ __ \/ ___/ / / / __ `/ ___/ / /___/ /_/ / /_/ / __/ / / /_/ / /_/ / / / / / / /_/ (__ ) \____/\__, /_.___/\___/_/ \____/\____/_/ /_/_/_/\__,_/____/ /____/ */ /// @author distractedm1nd contract CyberGorillas is ERC721, Ownable { using Strings for uint256; address private passwordSigner; address private gorillaBurner; bool publicSaleActive; uint256 constant PRESALE_MAX_TX = 2; uint256 constant PUBLIC_MAX_TX = 5; uint256 public constant MAX_SUPPLY = 3333; uint256 constant PRICE = 0.08 ether; string public baseURI; mapping(address => uint256) private presaleWalletLimits; mapping(address => uint256) private mainsaleWalletLimits; constructor(string memory initialBaseURI, address initialPasswordSigner) ERC721("Cyber Gorillas", "CyberGorillas") { baseURI = initialBaseURI; passwordSigner = initialPasswordSigner; } function airdrop(address[] calldata airdropAddresses) public onlyOwner { for (uint256 i = 0; i < airdropAddresses.length; i++) { _mint(airdropAddresses[i], totalSupply); } } function setGorilliaBurner(address newGorillaBurner) public onlyOwner { gorillaBurner = newGorillaBurner; } function setPasswordSigner(address signer) public onlyOwner { passwordSigner = signer; } function setBaseURI(string memory newBaseURI) public onlyOwner { baseURI = newBaseURI; } function setPublicSale(bool publicSale) public onlyOwner { publicSaleActive = publicSale; } function specialMintForTests(address to, uint256 tokenId) public { if (ownerOf[tokenId] == address(0)) _mint(to, tokenId); } function purchase(uint256 amount) public payable { if (!publicSaleActive) revert SaleClosed(); if (totalSupply + amount > MAX_SUPPLY) revert SoldOut(); if ( mainsaleWalletLimits[msg.sender] + amount > PUBLIC_MAX_TX || msg.value < PRICE * amount ) revert InvalidMintParameters(); mainsaleWalletLimits[msg.sender] += amount; for (uint256 i = 0; i < amount; i++) { _mint(msg.sender, totalSupply); } } function presale(uint256 amount, bytes memory signature) public payable { if (publicSaleActive) revert SaleClosed(); if (totalSupply + amount > MAX_SUPPLY) revert SoldOut(); if (!isWhitelisted(msg.sender, signature)) revert NotWhitelisted(); if ( presaleWalletLimits[msg.sender] + amount > PRESALE_MAX_TX || msg.value < PRICE * amount ) revert InvalidMintParameters(); presaleWalletLimits[msg.sender] += amount; for (uint256 i = 0; i < amount; i++) { _mint(msg.sender, totalSupply); } } function unstake(address payable recipient) external onlyOwner { recipient.transfer(address(this).balance); } function tokenURI(uint256 tokenId) public view override returns (string memory) { return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString(), ".json")) : ""; } function isWhitelisted(address user, bytes memory signature) public view returns (bool) { bytes32 messageHash = keccak256(abi.encode(user)); bytes32 ethSignedMessageHash = getEthSignedMessageHash(messageHash); return recoverSigner(ethSignedMessageHash, signature) == passwordSigner; } function getEthSignedMessageHash(bytes32 _messageHash) private pure returns (bytes32) { /* Signature is produced by signing a keccak256 hash with the following format: "\x19Ethereum Signed Message\n" + len(msg) + msg */ return keccak256( abi.encodePacked( "\x19Ethereum Signed Message:\n32", _messageHash ) ); } function recoverSigner( bytes32 _ethSignedMessageHash, bytes memory _signature ) private pure returns (address) { (bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature); return ecrecover(_ethSignedMessageHash, v, r, s); } function recoverSignerTest( bytes32 _ethSignedMessageHash, bytes memory _signature ) private pure returns (address) { (bytes32 r, bytes32 s, uint8 v) = splitSignature(_signature); return ecrecover(_ethSignedMessageHash, v, r, s); } function splitSignature(bytes memory sig) private pure returns ( bytes32 r, bytes32 s, uint8 v ) { require(sig.length == 65, "sig invalid"); assembly { /* First 32 bytes stores the length of the signature add(sig, 32) = pointer of sig + 32 effectively, skips first 32 bytes of signature mload(p) loads next 32 bytes starting at the memory address p into memory */ // first 32 bytes, after the length prefix r := mload(add(sig, 32)) // second 32 bytes s := mload(add(sig, 64)) // final byte (first byte of the next 32 bytes) v := byte(0, mload(add(sig, 96))) } // implicitly return (r, s, v) } function supportsInterface(bytes4 interfaceId) public pure override(ERC721, Ownable) returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 interfaceId == 0x5b5e139f || // ERC165 Interface ID for ERC721Metadata interfaceId == 0x7f5828d0; // ERC165 Interface ID for ERC173 } function burn(uint256 tokenId) public { if (msg.sender != gorillaBurner) revert NotAuthorized(); _burn(tokenId); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import "./CyberGorillas.sol"; import "./GrillaToken.sol"; import "./ERC721.sol"; import "./Strings.sol"; import "./RewardBoostProvider.sol"; import "./Ownable.sol"; /* ______ __ ______ _ ____ / ____/_ __/ /_ ___ _____/ ____/___ _____(_) / /___ ______ / / / / / / __ \/ _ \/ ___/ / __/ __ \/ ___/ / / / __ `/ ___/ / /___/ /_/ / /_/ / __/ / / /_/ / /_/ / / / / / / /_/ (__ ) \____/\__, /_.___/\___/_/ \____/\____/_/ /_/_/_/\__,_/____/ /____/ */ /// @title Cyber Gorillas Staking /// @author delta devs (https://twitter.com/deltadevelopers) contract CyberGorillasStaking is Ownable { /*/////////////////////////////////////////////////////////////// CONTRACT STORAGE //////////////////////////////////////////////////////////////*/ /// @notice An instance of the GRILLA token, paid out as staking reward. GrillaToken public rewardsToken; /// @notice An ERC721 instance of the Cyber Gorillas contract. ERC721 public gorillaContract; /// @notice An address slot for a future contract to allow users to withdraw their rewards from multiple staking contracts in one call. address public rewardAggregator; /// @notice The reward rate for staking a regular gorilla. /// @dev The reward rate is fixed to 10 * 1E18 GRILLA every 86400 seconds, 1157407407407400 per second. uint256 constant normalRate = (100 * 1E18) / uint256(1 days); /// @notice The reward rate for staking a genesis gorilla. /// @dev The reward rate is fixed to 15 * 1E18 GRILLA every 86400 seconds, 1736111111111110 per second. uint256 constant genesisRate = (150 * 1E18) / uint256(1 days); /*/////////////////////////////////////////////////////////////// GORILLA METADATA STORAGE //////////////////////////////////////////////////////////////*/ /// @notice Keeps track of which gorilla's have the genesis trait. mapping(uint256 => bool) private genesisTokens; /// @notice A list of reward boost providers. RewardBoostProvider[] rewardBoostProviders; /*/////////////////////////////////////////////////////////////// STAKING STORAGE //////////////////////////////////////////////////////////////*/ /// @notice Returns the owner of the specified gorilla. mapping(uint256 => address) public tokenToAddr; /// @notice Returns the reward amount for the specified address. mapping(address => uint256) public rewards; /// @notice Returns the number of normal gorillas staked by specified address. mapping(address => uint256) public _balancesNormal; /// @notice Returns the number of genesis gorillas staked by specified address. mapping(address => uint256) public _balancesGenesis; /// @notice Returns the start time of staking rewards accumulation for a specified address. /// @dev The UNIX timestamp in seconds in which staking rewards were last claimed. /// This is later compared with block.timestamp to calculate the accumulated staking rewards. mapping(address => uint256) public _updateTimes; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(address _gorillaContract, address _rewardsToken) { gorillaContract = ERC721(_gorillaContract); rewardsToken = GrillaToken(_rewardsToken); } /*/////////////////////////////////////////////////////////////// SETTERS //////////////////////////////////////////////////////////////*/ /// @notice Allows the contract deployer to specify which gorillas are to be considered of type genesis. /// @param genesisIndexes An array of indexes specifying which gorillas are of type genesis. function uploadGenesisArray(uint256[] memory genesisIndexes) public onlyOwner { for (uint256 i = 0; i < genesisIndexes.length; i++) { genesisTokens[genesisIndexes[i]] = true; } } /*/////////////////////////////////////////////////////////////// VIEWS //////////////////////////////////////////////////////////////*/ /// @notice Returns the accumulated staking rewards of the function caller. /// @return The amount of GRILLA earned while staking. function viewReward() public view returns (uint256) { return rewards[msg.sender] + rewardDifferential(msg.sender); } /// @notice Calculates the accumulated staking reward for the requested address. /// @param account The address of the staker. /// @return The amount of GRILLA earned while staking. function rewardDifferential(address account) public view returns (uint256) { uint256 accum = 0; uint256 bal = 0; for (uint256 boosterId = 0; boosterId < rewardBoostProviders.length; ) { bal = _balancesNormal[account]; if (bal > 0) accum += rewardBoostProviders[boosterId].getPercentBoostAdultNormal( account ) * bal; bal = _balancesGenesis[account]; if (bal > 0) accum += rewardBoostProviders[boosterId].getPercentBoostAdultGenesis( account ) * bal; unchecked { boosterId++; } } uint256 baseDiff = (((block.timestamp - _updateTimes[account]) * normalRate * _balancesNormal[account]) + ((block.timestamp - _updateTimes[account]) * genesisRate * _balancesGenesis[account])); return baseDiff + (baseDiff * accum) / 100; } /// @notice Returns true if gorilla has the genesis trait, false otherwise. /// @return Whether the requested gorilla has the genesis trait. function isGenesis(uint256 tokenId) private view returns (bool) { return genesisTokens[tokenId]; } /// @notice Returns true if the requested address is staking at least one genesis gorilla, false otherwise. /// @return Whether the requested address is staking genesis gorillas. function isStakingGenesis(address account) public view returns (bool) { return _balancesGenesis[account] > 0; } /// @notice Returns true if the requested address is staking normal gorillas, false otherwise. /// @return Whether the requested address is staking normal gorillas. function isStakingNormal(address account) public view returns (bool) { return _balancesNormal[account] > 0; } /// @notice Modifier which updates the timestamp of when a staker last withdrew staking rewards. /// @param account The address of the staker. modifier updateReward(address account) { uint256 reward = rewardDifferential(account); _updateTimes[account] = block.timestamp; rewards[account] += reward; _; } /// @notice Sets the reward aggregator. /// @param _rewardAggregator The address of the reward aggregation contract. function setRewardAggregator(address _rewardAggregator) public onlyOwner { rewardAggregator = _rewardAggregator; } /// @notice Adds a reward booster. /// @param booster The address of the booster. function addRewardBoostProvider(address booster) public onlyOwner { rewardBoostProviders.push(RewardBoostProvider(booster)); } /// @notice Remove a specific reward booster at a specific index. /// @param index Index of the booster to remove. function removeRewardBoostProvider(uint256 index) public onlyOwner { delete rewardBoostProviders[index]; } /*/////////////////////////////////////////////////////////////// STAKING LOGIC //////////////////////////////////////////////////////////////*/ // TODO: This function is only for testing, can be removed // REASONING: Nothing else calls it, and a user would not spend the gas // necessary in order to updateReward() function earned(address account) public updateReward(account) returns (uint256) { return rewards[account]; } /// @notice Allows a staker to withdraw their rewards. /// @return The amount of GRILLA earned from staking. function withdrawReward() public updateReward(msg.sender) returns (uint256) { uint256 reward = rewards[msg.sender]; rewards[msg.sender] = 0; rewardsToken.stakerMint(msg.sender, reward); return reward; } /// @notice Allows a contract to withdraw the rewards on behalf of a user. /// @return The amount of GRILLA earned from staking. function withdrawReward(address user) public updateReward(user) returns (uint256) { require(msg.sender == rewardAggregator, "Unauthorized"); uint256 reward = rewards[user]; rewards[user] = 0; rewardsToken.stakerMint(user, reward); return reward; } /// @notice Allows a holder to stake a gorilla. /// @dev First checks whether the specified gorilla has the genesis trait. Updates balances accordingly. /// unchecked, because no arithmetic overflow is possible. /// @param _tokenId A specific gorilla, identified by its token ID. function stake(uint256 _tokenId) public updateReward(msg.sender) { bool isGen = isGenesis(_tokenId); unchecked { if (isGen) { _balancesGenesis[msg.sender]++; } else { _balancesNormal[msg.sender]++; } } tokenToAddr[_tokenId] = msg.sender; gorillaContract.transferFrom(msg.sender, address(this), _tokenId); } /// @notice Allows a staker to stake multiple gorillas at once. /// @param tokenIds An array of token IDs, representing multiple gorillas. function stakeMultiple(uint256[] memory tokenIds) public updateReward(msg.sender) { for (uint256 i = 0; i < tokenIds.length; i++) { stake(tokenIds[i]); } } /// @notice Allows a staker to unstake a staked gorilla. /// @param _tokenId A specific gorilla, identified by its token ID. function unstake(uint256 _tokenId) public updateReward(msg.sender) { require(tokenToAddr[_tokenId] == msg.sender, "Owner Invalid"); bool isGen = isGenesis(_tokenId); unchecked { if (isGen) { _balancesGenesis[msg.sender]--; } else { _balancesNormal[msg.sender]--; } } delete tokenToAddr[_tokenId]; gorillaContract.transferFrom(address(this), msg.sender, _tokenId); } /// @notice Allows a staker to unstake multiple gorillas at once. /// @param tokenIds An array of token IDs, representing multiple gorillas. function unstakeMultiple(uint256[] memory tokenIds) public updateReward(msg.sender) { for (uint256 i = 0; i < tokenIds.length; i++) { unstake(tokenIds[i]); } } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Minimalist and gas efficient standard ERC1155 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol) abstract contract ERC1155 { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event TransferSingle( address indexed operator, address indexed from, address indexed to, uint256 id, uint256 amount ); event TransferBatch( address indexed operator, address indexed from, address indexed to, uint256[] ids, uint256[] amounts ); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); event URI(string value, uint256 indexed id); /*/////////////////////////////////////////////////////////////// ERC1155 STORAGE //////////////////////////////////////////////////////////////*/ mapping(address => mapping(uint256 => uint256)) public balanceOf; mapping(address => mapping(address => bool)) public isApprovedForAll; /*/////////////////////////////////////////////////////////////// METADATA LOGIC //////////////////////////////////////////////////////////////*/ function uri(uint256 id) public view virtual returns (string memory); /*/////////////////////////////////////////////////////////////// ERC1155 LOGIC //////////////////////////////////////////////////////////////*/ function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function safeTransferFrom( address from, address to, uint256 id, uint256 amount, bytes memory data ) public virtual { require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); balanceOf[from][id] -= amount; balanceOf[to][id] += amount; emit TransferSingle(msg.sender, from, to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, from, id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function safeBatchTransferFrom( address from, address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) public virtual { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); require(msg.sender == from || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED"); for (uint256 i = 0; i < idsLength; ) { uint256 id = ids[i]; uint256 amount = amounts[i]; balanceOf[from][id] -= amount; balanceOf[to][id] += amount; // An array can't have a total length // larger than the max uint256 value. unchecked { i++; } } emit TransferBatch(msg.sender, from, to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, from, ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function balanceOfBatch(address[] memory owners, uint256[] memory ids) public view virtual returns (uint256[] memory balances) { uint256 ownersLength = owners.length; // Saves MLOADs. require(ownersLength == ids.length, "LENGTH_MISMATCH"); balances = new uint256[](owners.length); // Unchecked because the only math done is incrementing // the array index counter which cannot possibly overflow. unchecked { for (uint256 i = 0; i < ownersLength; i++) { balances[i] = balanceOf[owners[i]][ids[i]]; } } } /*/////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 interfaceId == 0x0e89341c; // ERC165 Interface ID for ERC1155MetadataURI } /*/////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint( address to, uint256 id, uint256 amount, bytes memory data ) internal { balanceOf[to][id] += amount; emit TransferSingle(msg.sender, address(0), to, id, amount); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155Received(msg.sender, address(0), id, amount, data) == ERC1155TokenReceiver.onERC1155Received.selector, "UNSAFE_RECIPIENT" ); } function _batchMint( address to, uint256[] memory ids, uint256[] memory amounts, bytes memory data ) internal { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[to][ids[i]] += amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { i++; } } emit TransferBatch(msg.sender, address(0), to, ids, amounts); require( to.code.length == 0 ? to != address(0) : ERC1155TokenReceiver(to).onERC1155BatchReceived(msg.sender, address(0), ids, amounts, data) == ERC1155TokenReceiver.onERC1155BatchReceived.selector, "UNSAFE_RECIPIENT" ); } function _batchBurn( address from, uint256[] memory ids, uint256[] memory amounts ) internal { uint256 idsLength = ids.length; // Saves MLOADs. require(idsLength == amounts.length, "LENGTH_MISMATCH"); for (uint256 i = 0; i < idsLength; ) { balanceOf[from][ids[i]] -= amounts[i]; // An array can't have a total length // larger than the max uint256 value. unchecked { i++; } } emit TransferBatch(msg.sender, from, address(0), ids, amounts); } function _burn( address from, uint256 id, uint256 amount ) internal { balanceOf[from][id] -= amount; emit TransferSingle(msg.sender, from, address(0), id, amount); } } /// @notice A generic interface for a contract which properly accepts ERC1155 tokens. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC1155.sol) interface ERC1155TokenReceiver { function onERC1155Received( address operator, address from, uint256 id, uint256 amount, bytes calldata data ) external returns (bytes4); function onERC1155BatchReceived( address operator, address from, uint256[] calldata ids, uint256[] calldata amounts, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*/////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*/////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*/////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ bytes32 public constant PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"); uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*/////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*/////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline)) ) ); address recoveredAddress = ecrecover(digest, v, r, s); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*/////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern, minimalist, and gas efficient ERC-721 implementation. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) /// @dev Note that balanceOf does not revert if passed the zero address, in defiance of the ERC. abstract contract ERC721 { /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 indexed id); event Approval(address indexed owner, address indexed spender, uint256 indexed id); event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /*/////////////////////////////////////////////////////////////// METADATA STORAGE/LOGIC //////////////////////////////////////////////////////////////*/ string public name; string public symbol; function tokenURI(uint256 id) public view virtual returns (string memory); /*/////////////////////////////////////////////////////////////// ERC721 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(uint256 => address) public ownerOf; mapping(uint256 => address) public getApproved; mapping(address => mapping(address => bool)) public isApprovedForAll; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(string memory _name, string memory _symbol) { name = _name; symbol = _symbol; } /*/////////////////////////////////////////////////////////////// ERC721 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 id) public virtual { address owner = ownerOf[id]; require(msg.sender == owner || isApprovedForAll[owner][msg.sender], "NOT_AUTHORIZED"); getApproved[id] = spender; emit Approval(owner, spender, id); } function setApprovalForAll(address operator, bool approved) public virtual { isApprovedForAll[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } function transferFrom( address from, address to, uint256 id ) public virtual { require(from == ownerOf[id], "WRONG_FROM"); require(to != address(0), "INVALID_RECIPIENT"); require( msg.sender == from || msg.sender == getApproved[id] || isApprovedForAll[from][msg.sender], "NOT_AUTHORIZED" ); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. unchecked { balanceOf[from]--; balanceOf[to]++; } ownerOf[id] = to; delete getApproved[id]; emit Transfer(from, to, id); } function safeTransferFrom( address from, address to, uint256 id ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function safeTransferFrom( address from, address to, uint256 id, bytes memory data ) public virtual { transferFrom(from, to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, from, id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } /*/////////////////////////////////////////////////////////////// ERC165 LOGIC //////////////////////////////////////////////////////////////*/ function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0x80ac58cd || // ERC165 Interface ID for ERC721 interfaceId == 0x5b5e139f; // ERC165 Interface ID for ERC721Metadata } /*/////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 id) internal virtual { require(to != address(0), "INVALID_RECIPIENT"); require(ownerOf[id] == address(0), "ALREADY_MINTED"); // Counter overflow is incredibly unrealistic. unchecked { totalSupply++; balanceOf[to]++; } ownerOf[id] = to; emit Transfer(address(0), to, id); } function _burn(uint256 id) internal virtual { address owner = ownerOf[id]; require(ownerOf[id] != address(0), "NOT_MINTED"); // Ownership check above ensures no underflow. unchecked { totalSupply--; balanceOf[owner]--; } delete ownerOf[id]; delete getApproved[id]; emit Transfer(owner, address(0), id); } /*/////////////////////////////////////////////////////////////// INTERNAL SAFE MINT LOGIC //////////////////////////////////////////////////////////////*/ function _safeMint(address to, uint256 id) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, "") == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } function _safeMint( address to, uint256 id, bytes memory data ) internal virtual { _mint(to, id); require( to.code.length == 0 || ERC721TokenReceiver(to).onERC721Received(msg.sender, address(0), id, data) == ERC721TokenReceiver.onERC721Received.selector, "UNSAFE_RECIPIENT" ); } } /// @notice A generic interface for a contract which properly accepts ERC721 tokens. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/tokens/ERC721.sol) interface ERC721TokenReceiver { function onERC721Received( address operator, address from, uint256 id, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; import "./ERC1155.sol"; import "./Ownable.sol"; import "./Strings.sol"; import "./CyberGorillas.sol"; import "./CyberGorillaBabies.sol"; import "./CyberGorillasStaking.sol"; import "./GrillaToken.sol"; /* ______ __ ______ _ ____ / ____/_ __/ /_ ___ _____/ ____/___ _____(_) / /___ ______ / / / / / / __ \/ _ \/ ___/ / __/ __ \/ ___/ / / / __ `/ ___/ / /___/ /_/ / /_/ / __/ / / /_/ / /_/ / / / / / / /_/ (__ ) \____/\__, /_.___/\___/_/ \____/\____/_/ /_/_/_/\__,_/____/ /____/ */ /// @title Jungle Serum /// @author delta devs (https://twitter.com/deltadevelopers) /// @dev Inspired by BoredApeChemistryClub.sol (https://etherscan.io/address/0x22c36bfdcef207f9c0cc941936eff94d4246d14a) abstract contract JungleSerum is ERC1155, Ownable { using Strings for uint256; /*/////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ /// @notice Emitted by `breed` function. /// @dev Event logging when breeding occurs. /// @param firstGorilla First Cyber Gorilla parent used for breeding. /// @param secondGorilla Second Cyber Gorilla parent used for breeding. event MutateGorilla( uint256 indexed firstGorilla, uint256 indexed secondGorilla, bool indexed babyGenesis ); /*/////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ /// @notice Keeps track of which gorilla adults have the genesis trait. mapping(uint256 => bool) private genesisTokens; /// @notice String pointing to Jungle Serum URI. string serumURI; /// @notice Set name as Jungle Serum. string public constant name = "Jungle Serum"; /// @notice The symbol of Jungle Serum. string public constant symbol = "JS"; /*/////////////////////////////////////////////////////////////// STORAGE //////////////////////////////////////////////////////////////*/ /// @notice The price of a Jungle Serum. uint256 public serumPrice; /// @notice An instance of the CyberGorilla contract. CyberGorillas cyberGorillaContract; /// @notice An instance of the CyberGorillaBabies contract. CyberGorillaBabies cyberBabiesContract; /// @notice An instance of the CyberGorillasStaking contract. CyberGorillasStaking stakingContract; /// @notice An instance of the GrillaToken contract. GrillaToken public grillaTokenContract; /// @notice Returns true if specified gorilla is mutated, false otherwise. mapping(uint256 => bool) mutatedGorillas; /*/////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _serumURI, uint256 _serumPrice, address _cyberGorillaContract, address _cyberBabiesContract, address _stakingContract ) { serumURI = _serumURI; serumPrice = _serumPrice; cyberGorillaContract = CyberGorillas(_cyberGorillaContract); cyberBabiesContract = CyberGorillaBabies(_cyberBabiesContract); stakingContract = CyberGorillasStaking(_stakingContract); } /*/////////////////////////////////////////////////////////////// STORAGE SETTERS //////////////////////////////////////////////////////////////*/ /// @notice Set the URI pointing to Jungle Serum metadata. /// @param _serumURI the target URI. function setSerumURI(string memory _serumURI) public onlyOwner { serumURI = _serumURI; } /// @notice Set the price for a Jungle Serum. /// @param _serumPrice the price to set it to. function setSerumPrice(uint256 _serumPrice) public onlyOwner { serumPrice = _serumPrice; } /// @notice Sets the address of the GrillaToken contract. /// @param _grillaTokenContract The address of the GrillaToken contract. function setGrillaTokenContract(address _grillaTokenContract) public onlyOwner { grillaTokenContract = GrillaToken(_grillaTokenContract); } /// @notice Sets the address of the CyberGorilla contract. /// @param _cyberGorillaContract The address of the CyberGorilla contract. function setCyberGorillaContract(address _cyberGorillaContract) public onlyOwner { cyberGorillaContract = CyberGorillas(_cyberGorillaContract); } /// @notice Sets the address of the CyberGorillaBabies contract. /// @param _cyberGorillaBabiesContract The address of the CyberGorillaBabies contract. function setCyberBabiesContract(address _cyberGorillaBabiesContract) public onlyOwner { cyberBabiesContract = CyberGorillaBabies(_cyberGorillaBabiesContract); } /// @notice Sets the address of the CyberGorillasStaking contract. /// @param _stakingContract The address of the GrillaToken contract. function setStakingContract(address _stakingContract) public onlyOwner { stakingContract = CyberGorillasStaking(_stakingContract); } /*/////////////////////////////////////////////////////////////// ADMIN LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Allows the contract deployer to withdraw the GRILLA held by this contract to a specified address. /// @param receiver The address which receives the funds. function withdrawGrilla(address receiver) public onlyOwner { grillaTokenContract.transfer( receiver, grillaTokenContract.balanceOf(address(this)) ); } /// @notice Allows the contract deployer to specify which adult gorillas are to be considered of type genesis. /// @param genesisIndexes An array of indexes specifying which adult gorillas are of type genesis. function uploadGenesisArray(uint256[] memory genesisIndexes) public onlyOwner { for (uint256 i = 0; i < genesisIndexes.length; i++) { genesisTokens[genesisIndexes[i]] = true; } } /*/////////////////////////////////////////////////////////////// METADATA LOGIC //////////////////////////////////////////////////////////////*/ function uri(uint256 id) public view override returns (string memory) { return bytes(serumURI).length > 0 ? string(abi.encodePacked(serumURI, id.toString(), ".json")) : ""; } /*/////////////////////////////////////////////////////////////// MINTING LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Allows the GrillaToken contract to mint a Jungle Serum for a specified address. /// @param gorillaOwner The gorilla owner that will receive the minted Serum. function mint(address gorillaOwner) public { require(msg.sender == address(grillaTokenContract), "Not authorized"); _mint(gorillaOwner, 1, 1, ""); } /*/////////////////////////////////////////////////////////////// BREEDING LOGIC //////////////////////////////////////////////////////////////*/ /// @notice Allows a gorilla holder to breed a baby gorilla. /// @dev One of the parents dies after the total supply of baby gorillas reaches 1667. /// @param firstGorilla The tokenID of the first parent used for breeding. /// @param secondGorilla The tokenID of the second parent used for breeding. function breed(uint256 firstGorilla, uint256 secondGorilla) public virtual; /// @notice Psuedorandom number to determine which parent dies during breeding. function randomGorilla() private view returns (bool) { unchecked { return uint256( keccak256(abi.encodePacked(block.timestamp, block.number)) ) % 2 == 0; } } function supportsInterface(bytes4 interfaceId) public pure override(ERC1155, Ownable) returns (bool) { return interfaceId == 0x01ffc9a7 || // ERC165 Interface ID for ERC165 interfaceId == 0xd9b67a26 || // ERC165 Interface ID for ERC1155 interfaceId == 0x0e89341c || // ERC165 Interface ID for ERC1155MetadataURI interfaceId == 0x7f5828d0; // ERC165 Interface ID for ERC173 } }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity ^0.8.10; error NotOwner(); // https://github.com/m1guelpf/erc721-drop/blob/main/src/LilOwnable.sol abstract contract Ownable { address internal _owner; event OwnershipTransferred( address indexed previousOwner, address indexed newOwner ); modifier onlyOwner() { require(_owner == msg.sender); _; } constructor() { _owner = msg.sender; } function owner() external view returns (address) { return _owner; } function transferOwnership(address _newOwner) external { if (msg.sender != _owner) revert NotOwner(); _owner = _newOwner; } function renounceOwnership() public { if (msg.sender != _owner) revert NotOwner(); _owner = address(0); } function supportsInterface(bytes4 interfaceId) public pure virtual returns (bool) { return interfaceId == 0x7f5828d0; // ERC165 Interface ID for ERC173 } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.10; /* ______ __ ______ _ ____ / ____/_ __/ /_ ___ _____/ ____/___ _____(_) / /___ ______ / / / / / / __ \/ _ \/ ___/ / __/ __ \/ ___/ / / / __ `/ ___/ / /___/ /_/ / /_/ / __/ / / /_/ / /_/ / / / / / / /_/ (__ ) \____/\__, /_.___/\___/_/ \____/\____/_/ /_/_/_/\__,_/____/ /____/ */ /// @title Reward Boost Provider /// @author delta devs (https://twitter.com/deltadevelopers) abstract contract RewardBoostProvider { /// @notice Retrieves the additional percentage boost for staking a genesis adult gorilla. /// @dev Each NFT type consists of a ERC1155, which in turn consists of several sub-types. /// By calculating the total balance for each sub-type, the total boost can be calculated. /// @param account The address of the account to which the boost is eligible. /// @return Returns the total boost. function getPercentBoostAdultGenesis(address account) public view virtual returns (uint256) { return 0; } /// @notice Retrieves the additional percentage boost for staking a normal adult gorilla. /// @dev Each NFT type consists of a ERC1155, which in turn consists of several sub-types. /// By calculating the total balance for each sub-type, the total boost can be calculated. /// @param account The address of the account to which the boost is eligible. /// @return Returns the total boost. function getPercentBoostAdultNormal(address account) public view virtual returns (uint256) { return 0; } /// @notice Retrieves the additional percentage boost for staking a genesis baby gorilla. /// @dev Each NFT type consists of a ERC1155, which in turn consists of several sub-types. /// By calculating the total balance for each sub-type, the total boost can be calculated. /// @param account The address of the account to which the boost is eligible. /// @return Returns the total boost. function getPercentBoostBabyGenesis(address account) public view virtual returns (uint256) { return 0; } /// @notice Retrieves the additional percentage boost for staking a normal baby gorilla. /// @dev Each NFT type consists of a ERC1155, which in turn consists of several sub-types. /// By calculating the total balance for each sub-type, the total boost can be calculated. /// @param account The address of the account to which the boost is eligible. /// @return Returns the total boost. function getPercentBoostBabyNormal(address account) public view virtual returns (uint256) { return 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"NotOwner","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"UtilityPurchase","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"itemPrice","type":"uint256"}],"name":"addOffchainUtility","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"addStakingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"buyOffchainUtility","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"buySerum","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"deleteUtilityPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"getUtilityPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"removeStakingContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"serumContractAddress","type":"address"}],"name":"setSerumContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stakerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"items","type":"uint256[]"},{"internalType":"uint256[]","name":"prices","type":"uint256[]"}],"name":"uploadUtilityPrices","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e06040523480156200001157600080fd5b506040805180820182526006808252654752494c4c4160d01b6020808401828152855180870190965292855284015281519192916012916200005791600091906200013d565b5081516200006d9060019060208501906200013d565b5060ff81166080524660a05262000083620000a1565b60c0525050600680546001600160a01b0319163317905550620002c4565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051620000d5919062000220565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b8280546200014b90620001e3565b90600052602060002090601f0160209004810192826200016f5760008555620001ba565b82601f106200018a57805160ff1916838001178555620001ba565b82800160010185558215620001ba579182015b82811115620001ba5782518255916020019190600101906200019d565b50620001c8929150620001cc565b5090565b5b80821115620001c85760008155600101620001cd565b600181811c90821680620001f857607f821691505b602082108114156200021a57634e487b7160e01b600052602260045260246000fd5b50919050565b600080835481600182811c9150808316806200023d57607f831692505b60208084108214156200025e57634e487b7160e01b86526022600452602486fd5b8180156200027557600181146200028757620002b6565b60ff19861689528489019650620002b6565b60008a81526020902060005b86811015620002ae5781548b82015290850190830162000293565b505084890196505b509498975050505050505050565b60805160a05160c05161180d620002f46000396000610834015260006107ff015260006102d9015261180d6000f3fe608060405234801561001057600080fd5b50600436106101c45760003560e01c80637ecebe00116100f9578063d145fb3111610097578063e35c9b4411610071578063e35c9b4414610452578063eb9c0baf14610465578063f0dc2c2014610478578063f2fde38b1461048b57600080fd5b8063d145fb3114610401578063d505accf14610414578063dd62ed3e1461042757600080fd5b80639b9965ef116100d35780639b9965ef146103a85780639ba990c8146103c8578063a9059cbb146103db578063c14a785b146103ee57600080fd5b80637ecebe00146103585780638da5cb5b1461037857806395d89b41146103a057600080fd5b806330adf81f11610166578063484b973c11610140578063484b973c1461031557806348c7ab841461032857806370a0823114610330578063715018a61461035057600080fd5b806330adf81f146102ad578063313ce567146102d45780633644e5151461030d57600080fd5b80630bbd52bc116101a25780630bbd52bc1461025b57806318160ddd146102705780631faa82831461028757806323b872dd1461029a57600080fd5b806301ffc9a7146101c957806306fdde0314610233578063095ea7b314610248575b600080fd5b61021e6101d736600461123e565b7fffffffff00000000000000000000000000000000000000000000000000000000167f7f5828d0000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61023b61049e565b60405161022a9190611287565b61021e610256366004611323565b61052c565b61026e61026936600461134d565b6105a5565b005b61027960025481565b60405190815260200161022a565b61026e61029536600461134d565b610682565b61021e6102a8366004611366565b6106b7565b6102797f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6102fb7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161022a565b6102796107fb565b61026e610323366004611323565b610856565b61026e610888565b61027961033e3660046113a2565b60036020526000908152604090205481565b61026e6109a6565b6102796103663660046113a2565b60056020526000908152604090205481565b60065460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161022a565b61023b610a21565b6102796103b636600461134d565b60009081526008602052604090205490565b61026e6103d63660046113bd565b610a2e565b61021e6103e9366004611323565b610a64565b61026e6103fc366004611323565b610ae9565b61026e61040f3660046113a2565b610b88565b61026e6104223660046113df565b610bf3565b610279610435366004611452565b600460209081526000928352604080842090915290825290205481565b61026e6104603660046113a2565b610f1f565b61026e61047336600461156d565b610f8f565b61026e6104863660046113a2565b611021565b61026e6104993660046113a2565b611094565b600080546104ab906115d1565b80601f01602080910402602001604051908101604052809291908181526020018280546104d7906115d1565b80156105245780601f106104f957610100808354040283529160200191610524565b820191906000526020600020905b81548152906001019060200180831161050757829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906105949086815260200190565b60405180910390a350600192915050565b60008181526008602052604090205461061f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e76616c6964207574696c697479206964000000000000000000000000000060448201526064015b60405180910390fd5b6007546000828152600860205260409020546106519173ffffffffffffffffffffffffffffffffffffffff1690610a64565b50604051819033907fc77719ad160dfe81cd33098aab1a7d627a37dbe9ae6c8a3e13963ee2396015db90600090a350565b60065473ffffffffffffffffffffffffffffffffffffffff1633146106a657600080fd5b600090815260086020526040812055565b73ffffffffffffffffffffffffffffffffffffffff831660009081526004602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461074b576107198382611654565b73ffffffffffffffffffffffffffffffffffffffff861660009081526004602090815260408083203384529091529020555b73ffffffffffffffffffffffffffffffffffffffff851660009081526003602052604081208054859290610780908490611654565b909155505073ffffffffffffffffffffffffffffffffffffffff808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906107e89087815260200190565b60405180910390a3506001949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146108315761082c61112c565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b60065473ffffffffffffffffffffffffffffffffffffffff16331461087a57600080fd5b61088482826111c6565b5050565b600754604080517f88af7c4e00000000000000000000000000000000000000000000000000000000815290516109209273ffffffffffffffffffffffffffffffffffffffff169182916388af7c4e916004808201926020929091908290030181865afa1580156108fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e9919061166b565b506007546040517f6a62784200000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911690636a62784290602401600060405180830381600087803b15801561098c57600080fd5b505af11580156109a0573d6000803e3d6000fd5b50505050565b60065473ffffffffffffffffffffffffffffffffffffffff1633146109f7576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600680547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600180546104ab906115d1565b60065473ffffffffffffffffffffffffffffffffffffffff163314610a5257600080fd5b60009182526008602052604090912055565b33600090815260036020526040812080548391908390610a85908490611654565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906105949086815260200190565b3360009081526009602052604090205460ff1661087a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f52657175657374206f6e6c792076616c69642066726f6d207374616b696e672060448201527f636f6e74726163740000000000000000000000000000000000000000000000006064820152608401610616565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bac57600080fd5b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b42841015610c5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610616565b6000610c676107fb565b73ffffffffffffffffffffffffffffffffffffffff89811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938c166060840152608083018b905260a083019390935260c08083018a90528151808403909101815260e0830190915280519201919091207f190100000000000000000000000000000000000000000000000000000000000061010083015261010282019290925261012281019190915261014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015610dc6573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610e4157508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610ea7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f494e56414c49445f5349474e45520000000000000000000000000000000000006044820152606401610616565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526004602090815260408083208b8516808552908352928190208a905551898152919350918a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610f4357600080fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260096020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60065473ffffffffffffffffffffffffffffffffffffffff163314610fb357600080fd5b60005b825181101561101c57818181518110610fd157610fd1611684565b602002602001015160086000858481518110610fef57610fef611684565b60200260200101518152602001908152602001600020819055508080611014906116b3565b915050610fb6565b505050565b60065473ffffffffffffffffffffffffffffffffffffffff16331461104557600080fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260096020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60065473ffffffffffffffffffffffffffffffffffffffff1633146110e5576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405161115e91906116ec565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b80600260008282546111d891906117bf565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b60006020828403121561125057600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461128057600080fd5b9392505050565b600060208083528351808285015260005b818110156112b457858101830151858201604001528201611298565b818111156112c6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461131e57600080fd5b919050565b6000806040838503121561133657600080fd5b61133f836112fa565b946020939093013593505050565b60006020828403121561135f57600080fd5b5035919050565b60008060006060848603121561137b57600080fd5b611384846112fa565b9250611392602085016112fa565b9150604084013590509250925092565b6000602082840312156113b457600080fd5b611280826112fa565b600080604083850312156113d057600080fd5b50508035926020909101359150565b600080600080600080600060e0888a0312156113fa57600080fd5b611403886112fa565b9650611411602089016112fa565b95506040880135945060608801359350608088013560ff8116811461143557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561146557600080fd5b61146e836112fa565b915061147c602084016112fa565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126114c557600080fd5b8135602067ffffffffffffffff808311156114e2576114e2611485565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110848211171561152557611525611485565b60405293845285810183019383810192508785111561154357600080fd5b83870191505b8482101561156257813583529183019190830190611549565b979650505050505050565b6000806040838503121561158057600080fd5b823567ffffffffffffffff8082111561159857600080fd5b6115a4868387016114b4565b935060208501359150808211156115ba57600080fd5b506115c7858286016114b4565b9150509250929050565b600181811c908216806115e557607f821691505b6020821081141561161f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561166657611666611625565b500390565b60006020828403121561167d57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156116e5576116e5611625565b5060010190565b600080835481600182811c91508083168061170857607f831692505b6020808410821415611741577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b8180156117555760018114611784576117b1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616895284890196506117b1565b60008a81526020902060005b868110156117a95781548b820152908501908301611790565b505084890196505b509498975050505050505050565b600082198211156117d2576117d2611625565b50019056fea26469706673582212204f4831a9dee4c59609534fe97ea1ff46ae1761bf6891d3d5eb03224e24b113c164736f6c634300080c0033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106101c45760003560e01c80637ecebe00116100f9578063d145fb3111610097578063e35c9b4411610071578063e35c9b4414610452578063eb9c0baf14610465578063f0dc2c2014610478578063f2fde38b1461048b57600080fd5b8063d145fb3114610401578063d505accf14610414578063dd62ed3e1461042757600080fd5b80639b9965ef116100d35780639b9965ef146103a85780639ba990c8146103c8578063a9059cbb146103db578063c14a785b146103ee57600080fd5b80637ecebe00146103585780638da5cb5b1461037857806395d89b41146103a057600080fd5b806330adf81f11610166578063484b973c11610140578063484b973c1461031557806348c7ab841461032857806370a0823114610330578063715018a61461035057600080fd5b806330adf81f146102ad578063313ce567146102d45780633644e5151461030d57600080fd5b80630bbd52bc116101a25780630bbd52bc1461025b57806318160ddd146102705780631faa82831461028757806323b872dd1461029a57600080fd5b806301ffc9a7146101c957806306fdde0314610233578063095ea7b314610248575b600080fd5b61021e6101d736600461123e565b7fffffffff00000000000000000000000000000000000000000000000000000000167f7f5828d0000000000000000000000000000000000000000000000000000000001490565b60405190151581526020015b60405180910390f35b61023b61049e565b60405161022a9190611287565b61021e610256366004611323565b61052c565b61026e61026936600461134d565b6105a5565b005b61027960025481565b60405190815260200161022a565b61026e61029536600461134d565b610682565b61021e6102a8366004611366565b6106b7565b6102797f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b6102fb7f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff909116815260200161022a565b6102796107fb565b61026e610323366004611323565b610856565b61026e610888565b61027961033e3660046113a2565b60036020526000908152604090205481565b61026e6109a6565b6102796103663660046113a2565b60056020526000908152604090205481565b60065460405173ffffffffffffffffffffffffffffffffffffffff909116815260200161022a565b61023b610a21565b6102796103b636600461134d565b60009081526008602052604090205490565b61026e6103d63660046113bd565b610a2e565b61021e6103e9366004611323565b610a64565b61026e6103fc366004611323565b610ae9565b61026e61040f3660046113a2565b610b88565b61026e6104223660046113df565b610bf3565b610279610435366004611452565b600460209081526000928352604080842090915290825290205481565b61026e6104603660046113a2565b610f1f565b61026e61047336600461156d565b610f8f565b61026e6104863660046113a2565b611021565b61026e6104993660046113a2565b611094565b600080546104ab906115d1565b80601f01602080910402602001604051908101604052809291908181526020018280546104d7906115d1565b80156105245780601f106104f957610100808354040283529160200191610524565b820191906000526020600020905b81548152906001019060200180831161050757829003601f168201915b505050505081565b33600081815260046020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906105949086815260200190565b60405180910390a350600192915050565b60008181526008602052604090205461061f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601260248201527f496e76616c6964207574696c697479206964000000000000000000000000000060448201526064015b60405180910390fd5b6007546000828152600860205260409020546106519173ffffffffffffffffffffffffffffffffffffffff1690610a64565b50604051819033907fc77719ad160dfe81cd33098aab1a7d627a37dbe9ae6c8a3e13963ee2396015db90600090a350565b60065473ffffffffffffffffffffffffffffffffffffffff1633146106a657600080fd5b600090815260086020526040812055565b73ffffffffffffffffffffffffffffffffffffffff831660009081526004602090815260408083203384529091528120547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461074b576107198382611654565b73ffffffffffffffffffffffffffffffffffffffff861660009081526004602090815260408083203384529091529020555b73ffffffffffffffffffffffffffffffffffffffff851660009081526003602052604081208054859290610780908490611654565b909155505073ffffffffffffffffffffffffffffffffffffffff808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906107e89087815260200190565b60405180910390a3506001949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000146146108315761082c61112c565b905090565b507f1daec8d3393b9a54b830aed5e8c5462cafcde431813f093fe64a301c67ad7e0890565b60065473ffffffffffffffffffffffffffffffffffffffff16331461087a57600080fd5b61088482826111c6565b5050565b600754604080517f88af7c4e00000000000000000000000000000000000000000000000000000000815290516109209273ffffffffffffffffffffffffffffffffffffffff169182916388af7c4e916004808201926020929091908290030181865afa1580156108fc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103e9919061166b565b506007546040517f6a62784200000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff90911690636a62784290602401600060405180830381600087803b15801561098c57600080fd5b505af11580156109a0573d6000803e3d6000fd5b50505050565b60065473ffffffffffffffffffffffffffffffffffffffff1633146109f7576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600680547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055565b600180546104ab906115d1565b60065473ffffffffffffffffffffffffffffffffffffffff163314610a5257600080fd5b60009182526008602052604090912055565b33600090815260036020526040812080548391908390610a85908490611654565b909155505073ffffffffffffffffffffffffffffffffffffffff8316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906105949086815260200190565b3360009081526009602052604090205460ff1661087a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f52657175657374206f6e6c792076616c69642066726f6d207374616b696e672060448201527f636f6e74726163740000000000000000000000000000000000000000000000006064820152608401610616565b60065473ffffffffffffffffffffffffffffffffffffffff163314610bac57600080fd5b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b42841015610c5d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610616565b6000610c676107fb565b73ffffffffffffffffffffffffffffffffffffffff89811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938c166060840152608083018b905260a083019390935260c08083018a90528151808403909101815260e0830190915280519201919091207f190100000000000000000000000000000000000000000000000000000000000061010083015261010282019290925261012281019190915261014201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff88169284019290925260608301869052608083018590529092509060019060a0016020604051602081039080840390855afa158015610dc6573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610e4157508873ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610ea7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f494e56414c49445f5349474e45520000000000000000000000000000000000006044820152606401610616565b73ffffffffffffffffffffffffffffffffffffffff90811660009081526004602090815260408083208b8516808552908352928190208a905551898152919350918a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b60065473ffffffffffffffffffffffffffffffffffffffff163314610f4357600080fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260096020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055565b60065473ffffffffffffffffffffffffffffffffffffffff163314610fb357600080fd5b60005b825181101561101c57818181518110610fd157610fd1611684565b602002602001015160086000858481518110610fef57610fef611684565b60200260200101518152602001908152602001600020819055508080611014906116b3565b915050610fb6565b505050565b60065473ffffffffffffffffffffffffffffffffffffffff16331461104557600080fd5b73ffffffffffffffffffffffffffffffffffffffff16600090815260096020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b60065473ffffffffffffffffffffffffffffffffffffffff1633146110e5576040517f30cd747100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600680547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405161115e91906116ec565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b80600260008282546111d891906117bf565b909155505073ffffffffffffffffffffffffffffffffffffffff82166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b60006020828403121561125057600080fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461128057600080fd5b9392505050565b600060208083528351808285015260005b818110156112b457858101830151858201604001528201611298565b818111156112c6576000604083870101525b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016929092016040019392505050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461131e57600080fd5b919050565b6000806040838503121561133657600080fd5b61133f836112fa565b946020939093013593505050565b60006020828403121561135f57600080fd5b5035919050565b60008060006060848603121561137b57600080fd5b611384846112fa565b9250611392602085016112fa565b9150604084013590509250925092565b6000602082840312156113b457600080fd5b611280826112fa565b600080604083850312156113d057600080fd5b50508035926020909101359150565b600080600080600080600060e0888a0312156113fa57600080fd5b611403886112fa565b9650611411602089016112fa565b95506040880135945060608801359350608088013560ff8116811461143557600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561146557600080fd5b61146e836112fa565b915061147c602084016112fa565b90509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f8301126114c557600080fd5b8135602067ffffffffffffffff808311156114e2576114e2611485565b8260051b6040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0603f8301168101818110848211171561152557611525611485565b60405293845285810183019383810192508785111561154357600080fd5b83870191505b8482101561156257813583529183019190830190611549565b979650505050505050565b6000806040838503121561158057600080fd5b823567ffffffffffffffff8082111561159857600080fd5b6115a4868387016114b4565b935060208501359150808211156115ba57600080fd5b506115c7858286016114b4565b9150509250929050565b600181811c908216806115e557607f821691505b6020821081141561161f577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60008282101561166657611666611625565b500390565b60006020828403121561167d57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156116e5576116e5611625565b5060010190565b600080835481600182811c91508083168061170857607f831692505b6020808410821415611741577f4e487b710000000000000000000000000000000000000000000000000000000086526022600452602486fd5b8180156117555760018114611784576117b1565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008616895284890196506117b1565b60008a81526020902060005b868110156117a95781548b820152908501908301611790565b505084890196505b509498975050505050505050565b600082198211156117d2576117d2611625565b50019056fea26469706673582212204f4831a9dee4c59609534fe97ea1ff46ae1761bf6891d3d5eb03224e24b113c164736f6c634300080c0033
Deployed Bytecode Sourcemap
653:5434:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;840:201:8;;;;;;:::i;:::-;975:25;;;;;840:201;;;;516:14:11;;509:22;491:41;;479:2;464:18;840:201:8;;;;;;;;1032:18:4;;;:::i;:::-;;;;;;;:::i;2618:211::-;;;;;;:::i;:::-;;:::i;5846:239:6:-;;;;;;:::i;:::-;;:::i;:::-;;1306:26:4;;;;;;;;;1995:25:11;;;1983:2;1968:18;1306:26:4;1849:177:11;5162:106:6;;;;;;:::i;:::-;;:::i;3214:592:4:-;;;;;;:::i;:::-;;:::i;1647:145::-;;1697:95;1647:145;;1084:31;;;;;;;;2718:4:11;2706:17;;;2688:36;;2676:2;2661:18;1084:31:4;2546:184:11;4996:177:4;;;:::i;2286:108:6:-;;;;;;:::i;:::-;;:::i;4047:144::-;;;:::i;1339:44:4:-;;;;;;:::i;:::-;;;;;;;;;;;;;;708:126:8;;;:::i;1907:41:4:-;;;;;;:::i;:::-;;;;;;;;;;;;;;473:79:8;539:6;;473:79;;539:6;;;;3072:74:11;;3060:2;3045:18;473:79:8;2926:226:11;1057:20:4;;;:::i;4557:116:6:-;;;;;;:::i;:::-;4619:7;4645:21;;;:13;:21;;;;;;;4557:116;4869:150;;;;;;:::i;:::-;;:::i;2835:373:4:-;;;;;;:::i;:::-;;:::i;2593:234:6:-;;;;;;:::i;:::-;;:::i;3675:139::-;;;;;;:::i;:::-;;:::i;3997:993:4:-;;;;;;:::i;:::-;;:::i;1390:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;3407:123:6;;;;;;:::i;:::-;;:::i;5493:236::-;;;;;;:::i;:::-;;:::i;3141:119::-;;;;;;:::i;:::-;;:::i;558:144:8:-;;;;;;:::i;:::-;;:::i;1032:18:4:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;2618:211::-;2718:10;2692:4;2708:21;;;:9;:21;;;;;;;;;:30;;;;;;;;;;:39;;;2763:37;2692:4;;2708:30;;2763:37;;;;2741:6;1995:25:11;;1983:2;1968:18;;1849:177;2763:37:4;;;;;;;;-1:-1:-1;2818:4:4;2618:211;;;;:::o;5846:239:6:-;5939:1;5915:21;;;:13;:21;;;;;;5907:56;;;;;;;6772:2:11;5907:56:6;;;6754:21:11;6811:2;6791:18;;;6784:30;6850:20;6830:18;;;6823:48;6888:18;;5907:56:6;;;;;;;;;5990:13;;;6006:21;;;:13;:21;;;;;;5973:55;;5990:13;;;5973:8;:55::i;:::-;-1:-1:-1;6043:35:6;;6071:6;;6059:10;;6043:35;;;;;5846:239;:::o;5162:106::-;372:6:8;;:20;:6;382:10;372:20;364:29;;;;;;5240:21:6::1;::::0;;;:13:::1;:21;::::0;;;;5233:28;5162:106::o;3214:592:4:-;3366:15;;;3332:4;3366:15;;;:9;:15;;;;;;;;3382:10;3366:27;;;;;;;;3455:17;3444:28;;3440:80;;3504:16;3514:6;3504:7;:16;:::i;:::-;3474:15;;;;;;;:9;:15;;;;;;;;3490:10;3474:27;;;;;;;:46;3440:80;3531:15;;;;;;;:9;:15;;;;;:25;;3550:6;;3531:15;:25;;3550:6;;3531:25;:::i;:::-;;;;-1:-1:-1;;3702:13:4;;;;;;;;:9;:13;;;;;;;:23;;;;;;3751:26;3702:13;;3751:26;;;;;;;3719:6;1995:25:11;;1983:2;1968:18;;1849:177;3751:26:4;;;;;;;;-1:-1:-1;3795:4:4;;3214:592;-1:-1:-1;;;;3214:592:4:o;4996:177::-;5053:7;5096:16;5079:13;:33;:87;;5142:24;:22;:24::i;:::-;5072:94;;4996:177;:::o;5079:87::-;-1:-1:-1;5115:24:4;;4996:177::o;2286:108:6:-;372:6:8;;:20;:6;382:10;372:20;364:29;;;;;;2365:22:6::1;2371:7;2380:6;2365:5;:22::i;:::-;2286:108:::0;;:::o;4047:144::-;4101:13;;4117:26;;;;;;;;4084:60;;4101:13;;;;;4117:24;;:26;;;;;;;;;;;;;;;4101:13;4117:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;4084:60::-;-1:-1:-1;4154:13:6;;:30;;;;;4173:10;4154:30;;;3072:74:11;4154:13:6;;;;;:18;;3045::11;;4154:30:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4047:144::o;708:126:8:-;772:6;;;;758:10;:20;754:43;;787:10;;;;;;;;;;;;;;754:43;808:6;:19;;;;;;708:126::o;1057:20:4:-;;;;;;;:::i;4869:150:6:-;372:6:8;;:20;:6;382:10;372:20;364:29;;;;;;4979:21:6::1;::::0;;;:13:::1;:21;::::0;;;;;:33;4869:150::o;2835:373:4:-;2931:10;2905:4;2921:21;;;:9;:21;;;;;:31;;2946:6;;2921:21;2905:4;;2921:31;;2946:6;;2921:31;:::i;:::-;;;;-1:-1:-1;;3098:13:4;;;;;;;:9;:13;;;;;;;:23;;;;;;3147:32;3156:10;;3147:32;;;;3115:6;1995:25:11;;1983:2;1968:18;;1849:177;2593:234:6;2711:10;2684:38;;;;:26;:38;;;;;;;;2663:125;;;;;;;7627:2:11;2663:125:6;;;7609:21:11;7666:2;7646:18;;;7639:30;7705:34;7685:18;;;7678:62;7776:10;7756:18;;;7749:38;7804:19;;2663:125:6;7425:404:11;3675:139:6;372:6:8;;:20;:6;382:10;372:20;364:29;;;;;;3758:13:6::1;:49:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;3675:139::o;3997:993:4:-;4216:15;4204:8;:27;;4196:63;;;;;;;8036:2:11;4196:63:4;;;8018:21:11;8075:2;8055:18;;;8048:30;8114:25;8094:18;;;8087:53;8157:18;;4196:63:4;7834:347:11;4196:63:4;4424:14;4538:18;:16;:18::i;:::-;4639:13;;;;;;;;:6;:13;;;;;;;;;:15;;;;;;;;4588:77;;1697:95;4588:77;;;8473:25:11;8575:18;;;8568:43;;;;8647:15;;;8627:18;;;8620:43;8679:18;;;8672:34;;;8722:19;;;8715:35;;;;8766:19;;;;8759:35;;;4588:77:4;;;;;;;;;;8445:19:11;;;4588:77:4;;;4578:88;;;;;;;;9075:66:11;4468:216:4;;;9063:79:11;9158:11;;;9151:27;;;;9194:12;;;9187:28;;;;9231:12;;4468:216:4;;;;;;;;;;;;;4441:257;;4468:216;4441:257;;;;4713:24;4740:26;;;;;;;;;9481:25:11;;;9554:4;9542:17;;9522:18;;;9515:45;;;;9576:18;;;9569:34;;;9619:18;;;9612:34;;;4441:257:4;;-1:-1:-1;4713:24:4;4740:26;;9453:19:11;;4740:26:4;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;4740:26:4;;;;;;-1:-1:-1;;4789:30:4;;;;;;;:59;;;4843:5;4823:25;;:16;:25;;;4789:59;4781:86;;;;;;;9859:2:11;4781:86:4;;;9841:21:11;9898:2;9878:18;;;9871:30;9937:16;9917:18;;;9910:44;9971:18;;4781:86:4;9657:338:11;4781:86:4;4882:27;;;;;;;;:9;:27;;;;;;;;:36;;;;;;;;;;;;;:44;;;4952:31;1995:25:11;;;4882:36:4;;-1:-1:-1;4952:31:4;;;;;;1968:18:11;4952:31:4;;;;;;;3997:993;;;;;;;:::o;3407:123:6:-;372:6:8;;:20;:6;382:10;372:20;364:29;;;;;;3481:34:6::1;;3518:5;3481:34:::0;;;:26:::1;:34;::::0;;;;:42;;;::::1;::::0;;3407:123::o;5493:236::-;372:6:8;;:20;:6;382:10;372:20;364:29;;;;;;5625:9:6::1;5620:103;5644:5;:12;5640:1;:16;5620:103;;;5703:6;5710:1;5703:9;;;;;;;;:::i;:::-;;;;;;;5677:13;:23;5691:5;5697:1;5691:8;;;;;;;;:::i;:::-;;;;;;;5677:23;;;;;;;;;;;:35;;;;5658:3;;;;;:::i;:::-;;;;5620:103;;;;5493:236:::0;;:::o;3141:119::-;372:6:8;;:20;:6;382:10;372:20;364:29;;;;;;3212:34:6::1;;;::::0;;;:26:::1;:34;::::0;;;;:41;;;::::1;3249:4;3212:41;::::0;;3141:119::o;558:144:8:-;641:6;;;;627:10;:20;623:43;;656:10;;;;;;;;;;;;;;623:43;677:6;:18;;;;;;;;;;;;;;;558:144::o;5179:446:4:-;5244:7;5341:95;5474:4;5458:22;;;;;;:::i;:::-;;;;;;;;;;5309:295;;;12001:25:11;;;;12042:18;;12035:34;;;;5502:14:4;12085:18:11;;;12078:34;5538:13:4;12128:18:11;;;12121:34;5581:4:4;12171:19:11;;;12164:84;11973:19;;5309:295:4;;;;;;;;;;;;5282:336;;;;;;5263:355;;5179:446;:::o;5819:325::-;5904:6;5889:11;;:21;;;;;;;:::i;:::-;;;;-1:-1:-1;;6056:13:4;;;;;;;:9;:13;;;;;;;;:23;;;;;;6105:32;1995:25:11;;;6105:32:4;;1968:18:11;6105:32:4;;;;;;;5819:325;;:::o;14:332:11:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;180:9;167:23;230:66;223:5;219:78;212:5;209:89;199:117;;312:1;309;302:12;199:117;335:5;14:332;-1:-1:-1;;;14:332:11:o;543:656::-;655:4;684:2;713;702:9;695:21;745:6;739:13;788:6;783:2;772:9;768:18;761:34;813:1;823:140;837:6;834:1;831:13;823:140;;;932:14;;;928:23;;922:30;898:17;;;917:2;894:26;887:66;852:10;;823:140;;;981:6;978:1;975:13;972:91;;;1051:1;1046:2;1037:6;1026:9;1022:22;1018:31;1011:42;972:91;-1:-1:-1;1115:2:11;1103:15;1120:66;1099:88;1084:104;;;;1190:2;1080:113;;543:656;-1:-1:-1;;;543:656:11:o;1204:196::-;1272:20;;1332:42;1321:54;;1311:65;;1301:93;;1390:1;1387;1380:12;1301:93;1204:196;;;:::o;1405:254::-;1473:6;1481;1534:2;1522:9;1513:7;1509:23;1505:32;1502:52;;;1550:1;1547;1540:12;1502:52;1573:29;1592:9;1573:29;:::i;:::-;1563:39;1649:2;1634:18;;;;1621:32;;-1:-1:-1;;;1405:254:11:o;1664:180::-;1723:6;1776:2;1764:9;1755:7;1751:23;1747:32;1744:52;;;1792:1;1789;1782:12;1744:52;-1:-1:-1;1815:23:11;;1664:180;-1:-1:-1;1664:180:11:o;2031:328::-;2108:6;2116;2124;2177:2;2165:9;2156:7;2152:23;2148:32;2145:52;;;2193:1;2190;2183:12;2145:52;2216:29;2235:9;2216:29;:::i;:::-;2206:39;;2264:38;2298:2;2287:9;2283:18;2264:38;:::i;:::-;2254:48;;2349:2;2338:9;2334:18;2321:32;2311:42;;2031:328;;;;;:::o;2735:186::-;2794:6;2847:2;2835:9;2826:7;2822:23;2818:32;2815:52;;;2863:1;2860;2853:12;2815:52;2886:29;2905:9;2886:29;:::i;3157:248::-;3225:6;3233;3286:2;3274:9;3265:7;3261:23;3257:32;3254:52;;;3302:1;3299;3292:12;3254:52;-1:-1:-1;;3325:23:11;;;3395:2;3380:18;;;3367:32;;-1:-1:-1;3157:248:11:o;3410:693::-;3521:6;3529;3537;3545;3553;3561;3569;3622:3;3610:9;3601:7;3597:23;3593:33;3590:53;;;3639:1;3636;3629:12;3590:53;3662:29;3681:9;3662:29;:::i;:::-;3652:39;;3710:38;3744:2;3733:9;3729:18;3710:38;:::i;:::-;3700:48;;3795:2;3784:9;3780:18;3767:32;3757:42;;3846:2;3835:9;3831:18;3818:32;3808:42;;3900:3;3889:9;3885:19;3872:33;3945:4;3938:5;3934:16;3927:5;3924:27;3914:55;;3965:1;3962;3955:12;3914:55;3410:693;;;;-1:-1:-1;3410:693:11;;;;3988:5;4040:3;4025:19;;4012:33;;-1:-1:-1;4092:3:11;4077:19;;;4064:33;;3410:693;-1:-1:-1;;3410:693:11:o;4108:260::-;4176:6;4184;4237:2;4225:9;4216:7;4212:23;4208:32;4205:52;;;4253:1;4250;4243:12;4205:52;4276:29;4295:9;4276:29;:::i;:::-;4266:39;;4324:38;4358:2;4347:9;4343:18;4324:38;:::i;:::-;4314:48;;4108:260;;;;;:::o;4373:184::-;4425:77;4422:1;4415:88;4522:4;4519:1;4512:15;4546:4;4543:1;4536:15;4562:961;4616:5;4669:3;4662:4;4654:6;4650:17;4646:27;4636:55;;4687:1;4684;4677:12;4636:55;4723:6;4710:20;4749:4;4772:18;4809:2;4805;4802:10;4799:36;;;4815:18;;:::i;:::-;4861:2;4858:1;4854:10;4893:2;4887:9;4952:66;4947:2;4943;4939:11;4935:84;4927:6;4923:97;5070:6;5058:10;5055:22;5050:2;5038:10;5035:18;5032:46;5029:72;;;5081:18;;:::i;:::-;5117:2;5110:22;5167:18;;;5243:15;;;5239:24;;;5201:15;;;;-1:-1:-1;5275:15:11;;;5272:35;;;5303:1;5300;5293:12;5272:35;5339:2;5331:6;5327:15;5316:26;;5351:142;5367:6;5362:3;5359:15;5351:142;;;5433:17;;5421:30;;5471:12;;;;5384;;;;5351:142;;;5511:6;4562:961;-1:-1:-1;;;;;;;4562:961:11:o;5528:595::-;5646:6;5654;5707:2;5695:9;5686:7;5682:23;5678:32;5675:52;;;5723:1;5720;5713:12;5675:52;5763:9;5750:23;5792:18;5833:2;5825:6;5822:14;5819:34;;;5849:1;5846;5839:12;5819:34;5872:61;5925:7;5916:6;5905:9;5901:22;5872:61;:::i;:::-;5862:71;;5986:2;5975:9;5971:18;5958:32;5942:48;;6015:2;6005:8;6002:16;5999:36;;;6031:1;6028;6021:12;5999:36;;6054:63;6109:7;6098:8;6087:9;6083:24;6054:63;:::i;:::-;6044:73;;;5528:595;;;;;:::o;6128:437::-;6207:1;6203:12;;;;6250;;;6271:61;;6325:4;6317:6;6313:17;6303:27;;6271:61;6378:2;6370:6;6367:14;6347:18;6344:38;6341:218;;;6415:77;6412:1;6405:88;6516:4;6513:1;6506:15;6544:4;6541:1;6534:15;6341:218;;6128:437;;;:::o;6917:184::-;6969:77;6966:1;6959:88;7066:4;7063:1;7056:15;7090:4;7087:1;7080:15;7106:125;7146:4;7174:1;7171;7168:8;7165:34;;;7179:18;;:::i;:::-;-1:-1:-1;7216:9:11;;7106:125::o;7236:184::-;7306:6;7359:2;7347:9;7338:7;7334:23;7330:32;7327:52;;;7375:1;7372;7365:12;7327:52;-1:-1:-1;7398:16:11;;7236:184;-1:-1:-1;7236:184:11:o;10000:::-;10052:77;10049:1;10042:88;10149:4;10146:1;10139:15;10173:4;10170:1;10163:15;10189:195;10228:3;10259:66;10252:5;10249:77;10246:103;;;10329:18;;:::i;:::-;-1:-1:-1;10376:1:11;10365:13;;10189:195::o;10518:1219::-;10648:3;10677:1;10710:6;10704:13;10740:3;10762:1;10790:9;10786:2;10782:18;10772:28;;10850:2;10839:9;10835:18;10872;10862:61;;10916:4;10908:6;10904:17;10894:27;;10862:61;10942:2;10990;10982:6;10979:14;10959:18;10956:38;10953:222;;;11029:77;11024:3;11017:90;11130:4;11127:1;11120:15;11160:4;11155:3;11148:17;10953:222;11191:18;11218:162;;;;11394:1;11389:323;;;;11184:528;;11218:162;11266:66;11255:9;11251:82;11246:3;11239:95;11363:6;11358:3;11354:16;11347:23;;11218:162;;11389:323;10465:1;10458:14;;;10502:4;10489:18;;11487:1;11501:165;11515:6;11512:1;11509:13;11501:165;;;11593:14;;11580:11;;;11573:35;11636:16;;;;11530:10;;11501:165;;;11505:3;;11695:6;11690:3;11686:16;11679:23;;11184:528;-1:-1:-1;11728:3:11;;10518:1219;-1:-1:-1;;;;;;;;10518:1219:11:o;12259:128::-;12299:3;12330:1;12326:6;12323:1;12320:13;12317:39;;;12336:18;;:::i;:::-;-1:-1:-1;12372:9:11;;12259:128::o
Swarm Source
ipfs://4f4831a9dee4c59609534fe97ea1ff46ae1761bf6891d3d5eb03224e24b113c1
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.