ETH Price: $3,336.34 (-0.38%)
Gas: 2.65 Gwei
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer215043332024-12-28 23:46:233 days ago1735429583IN
0x171b6148...DC1159Cd2
0 ETH0.000264725.44563364
Approve214499682024-12-21 9:24:3510 days ago1734773075IN
0x171b6148...DC1159Cd2
0 ETH0.000222879.20736207
Approve214498382024-12-21 8:58:3510 days ago1734771515IN
0x171b6148...DC1159Cd2
0 ETH0.000408228.78100938
Approve206129682024-08-26 13:08:59127 days ago1724677739IN
0x171b6148...DC1159Cd2
0 ETH0.000078052.96345245
Approve206129662024-08-26 13:08:35127 days ago1724677715IN
0x171b6148...DC1159Cd2
0 ETH0.000143283.09885337
Approve205643102024-08-19 17:57:59134 days ago1724090279IN
0x171b6148...DC1159Cd2
0 ETH0.000225914.85945267
Approve204926382024-08-09 17:49:11144 days ago1723225751IN
0x171b6148...DC1159Cd2
0 ETH0.000197794.26016364
Approve204064592024-07-28 17:11:35156 days ago1722186695IN
0x171b6148...DC1159Cd2
0 ETH0.000080451.73198953
Approve202025872024-06-30 6:03:35185 days ago1719727415IN
0x171b6148...DC1159Cd2
0 ETH0.000091721.98690341
Approve200305302024-06-06 4:53:59209 days ago1717649639IN
0x171b6148...DC1159Cd2
0 ETH0.000330247.15338532
Approve199988152024-06-01 18:39:11213 days ago1717267151IN
0x171b6148...DC1159Cd2
0 ETH0.000362657.80079741
Transfer199976812024-06-01 14:51:23213 days ago1717253483IN
0x171b6148...DC1159Cd2
0 ETH0.0005141510.01144017
Transfer199953982024-06-01 7:12:47213 days ago1717225967IN
0x171b6148...DC1159Cd2
0 ETH0.000264825.15784903
Approve197577432024-04-29 1:39:23247 days ago1714354763IN
0x171b6148...DC1159Cd2
0 ETH0.000366787.88960895
Permit186270202023-11-22 11:36:47405 days ago1700653007IN
0x171b6148...DC1159Cd2
0 ETH0.0015846329.15718418
Approve182812312023-10-05 2:08:35454 days ago1696471715IN
0x171b6148...DC1159Cd2
0 ETH0.000330097.1004248
Approve182508332023-09-30 20:13:35458 days ago1696104815IN
0x171b6148...DC1159Cd2
0 ETH0.000403898.69897984
Approve182089222023-09-24 23:26:11464 days ago1695597971IN
0x171b6148...DC1159Cd2
0 ETH0.000334267.23118464
Approve178302892023-08-02 22:26:23517 days ago1691015183IN
0x171b6148...DC1159Cd2
0 ETH0.0009145719.80550722
Approve176587862023-07-09 21:22:23541 days ago1688937743IN
0x171b6148...DC1159Cd2
0 ETH0.0007871617.04635284
Approve174006172023-06-03 14:01:35577 days ago1685800895IN
0x171b6148...DC1159Cd2
0 ETH0.0018697840.44886037
Approve173897062023-06-02 1:08:59579 days ago1685668139IN
0x171b6148...DC1159Cd2
0 ETH0.0010277622.13578931
Approve173896922023-06-02 1:06:11579 days ago1685667971IN
0x171b6148...DC1159Cd2
0 ETH0.0011478624.72242717
Approve173634252023-05-29 8:21:47582 days ago1685348507IN
0x171b6148...DC1159Cd2
0 ETH0.0016970736.50404239
Approve173336142023-05-25 3:52:35587 days ago1684986755IN
0x171b6148...DC1159Cd2
0 ETH0.0013173928.33712235
View all transactions

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
172035502023-05-06 19:12:11605 days ago1683400331
0x171b6148...DC1159Cd2
0.02885011 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Popepe

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 5 : Popepe.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.17;

import "solmate/tokens/ERC20.sol";
import "solmate/auth/Owned.sol";
import "openzeppelin-contracts/utils/structs/EnumerableMap.sol";

/* Popepe Token
 * All memes are created equal
 * Telegram: https://t.me/popepe777
 * Twitter: https://twitter.com/popepe777
 */
/*
                            :                   ::   -==+==  ==++==  ===*    :.           
                           :.                 .:     -+++=+.=+=.:==+:===*     ::          
                          -.               .::.      :+===*=++:  :+=++==*      .:         
                         :.               ::         .+=+==+:-*:.+- .===+.       -.       
                        .:              ::            *==++  .-..-: .=+=+:        :.      
                        -             ::              *=+==+-=+..-+++=*==-         ::     
                       .:           .:                +=+=++=+:. .==+-+==-          :.    
                       :          .::                 +=+=+::=+=-+==. ====           :    
                       :         ::                   =====-  :=+==   ====           :    
                       :        :.                    ======  :+==+.  ====           :    
                      :.      .-                      -+=+=+  *=++==  -==+           :    
                      :      ::                       -+===* .+====+-:-==+           ..   
                      =     :.                        :+===*==+::::=+=++=*           .:   
                      -    .:                         :+=+===--    :-=+==*           ..   
                     ::   -.                          .+=+=+: .:. .-  -+=*.          :    
                     -.  -.                           .+===-::..=--..::+=+.          :    
                     -  -                              +==+.  .=+=+:.  :=+:         .:    
                     : :                               +===-.:::+=+::: :=+:         -     
                     :.:                               +=+=+=  :: .:  :+==-        .-     
                     -=                                ==++=+-::   :: =====        -.     
                     -.                                -+=+==++:.  :=+=+===       .=      
                     .-                                -+++=+=======+-.-===     .-+:      
                      :.                               :+===+. :+=+=*  -===  .:=+=+       
                       :                               :++===: .+===+  :+++-=+====-       
                       :-::::......                    :+====:  .++*=--=++=====+=*        
                       .+====+++=++++++++++++===========++++++++++=====+==+==#==+=        
                        =++++++=====+++=========+++=====+=+=======++==+--:. =+==*.        
                         -...:::-=*+==+=+-:::-++===+++++++=====*++:.-+==:  -+===+         
                         .: ....:+==+-.  -. .-  :=+==:       :+++=:.-+==+==+===*:         
                          -+=++++==-...:::+-+:::...==+++=--:=+-..-:.-.  -++++==*          
                           ===+++=+:   ..=+=+-..   -=======+==-..=-.=+-=+-..+=+-          
                           .:....====:.. .:.-. .::===+===-:..==++=  .===:.-===+           
                            ====-=+===-.::   -.:-+=+=         :=++=-+=*==+===+.           
.                          .=====++++===+=====+==+*=-----------=++=+==+==+=++.            
                          -***++++==+==+==+==================+=+=+=++===+**:              
                        :**++++++***+++++++==========++===+=+====++++****+*+.             
                       -*++++*++++********######*******#**********++++*******-            
                      =*++++++****+*******************++**#++++++++**********#*+-.        
                     +*++*++*#*+****+++++++++++**********+*#*+++++****+**********#=       
                    =*++++++*++*#+++++++++++++++++++*#*+**++#*++*#***#**++*+++*#*#.       
                   -*++++++****#**=----=%#+%%%%%%%=::::-+***+*+++*=*#%@%%*===+***#        
                  .*+++++++++++++**+=..#@#+@@%-:*@#     .***#*++*.**.+@%*+#.  .:=+        
                  =++*++++++++++++**+**#%%+%@%=-*@@.      +****=. @@*#@*. +=    :*        
                 .*++*+++++++*+++++**+++++*#%%@@@@=       :#*+*=-.#@%@@@@@@:.-=+*=        
                 =*+*++++++++++++++*+*******+++***++===+++*****+*************+**=         
                =#++++++**++*+++*+*+++++++**************#****+***##*****++****#=          
               -*#+**+++++++***++++++++++++++***++++++*#*+*+++++*+****+++*******=         
              .*+#+++++++++**+++*++++++++++++*+++++****+++*+++++++++****+++++*++*=        
              =++*++*+***+******+++++++++++++++*****++++++++++++++*++++*+++++++++#*=.     
              *++*++++++*****#*#**+++++++++++***++++++++++++++++++++++++++++++++*#*#=     
             -*++*++++++++##*###*###***+++++++++++++++++++++++++++++++++++++++**#**+.     
            :+*++++++++*++*##*###%#***######****+++++++++++++++++++++++++++++**#**=       
          .:. =*+++++========+++*++**+++*++++++*#####***********************#####:        
         .:    =*+++=+*= :+++++**###****#######+######**#*******#######*****##%#*=        
        .:      :+*+=**- .+*****+***#####*##***+###############################**-        
        -         :++*=: :=++++++++++++*****++-=*#########################*#*##*-         
       .:           -*-:-=**+:..::----------::.+*##########################***#.          
      :. ...        =*##*++**=   .:----:...  .+*+++++********************+++++*.          
     .      ...    -#**++***+::-=+***##:.   -#*++++++++++++++++++++++++++++***-           
    .          ...:#++*+*%#******++****-:--**++*++++++++++++++++++++++++++++*+:..         
    .            :#+*++***++****+##**++***#*++++++++++++++++++++++++++++++++:    ::       
    .          =:+#+++++**+*+*######*+++**#++***+++++++++++++++***++++++**- .      ...    
   .          .*:**++++++++*####**+++**#*-.....:::::::=+=:::=++-:::::::::.. .         .   
  ..            -#+++++++++**+*++++******=.           :      .           ....          .. 
  .           :+#++++++++++++*******++++*=            :      .             -             .
 .            :@*+*++++++++++++**++++*#+..        ...:*... ..:.        ...:.              
.             --=*+*++++++++++*+++**=-. .......: :    +=..   :.  ..::..   :               
              -: =+*+*+++++++++*#%-.      . ...  ..    *:.    - ...       :               
               +- :+*+++++++++++#:          -..   ..  .==   ..            .               
                -=. :=+*+*+++****           :  ..   . :++. :.            :                
                  -*-. .:=#+=:..            :    .:--=++=---:.           :                
                   -:::...                  :      -==***==--            :                
*/
contract Popepe is ERC20, Owned {
    using EnumerableMap for EnumerableMap.AddressToUintMap;
    EnumerableMap.AddressToUintMap internal sacrifices;

    uint256 public maxWallet;
    mapping(address => bool) public isExcludedFromMaxWallet;
    

    event ExcludedFromMaxWallet(address indexed wallet, bool isExcluded);
    event UpdateMaxWallet(uint256 newMaxWallet, uint256 oldMaxWallet);
    event TokenSacrifice(address indexed wallet, uint256 amount);

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _totalSupply,
        uint256 _maxWallet,
        address _owner
    ) ERC20(_name, _symbol, _decimals) Owned(_owner) payable {
        maxWallet = _maxWallet;
        isExcludedFromMaxWallet[address(this)] = true;
        isExcludedFromMaxWallet[address(0xdead)] = true;
        isExcludedFromMaxWallet[address(0)] = true;
        isExcludedFromMaxWallet[msg.sender] = true;
        isExcludedFromMaxWallet[_owner] = true;
        emit ExcludedFromMaxWallet(address(this), true);
        emit ExcludedFromMaxWallet(address(0xdead), true);
        emit ExcludedFromMaxWallet(address(0), true);
        emit ExcludedFromMaxWallet(msg.sender, true);
        emit ExcludedFromMaxWallet(_owner, true);
        _mint(_owner, _totalSupply);
    }

    function updateMaxWallet(uint256 _maxWallet) public onlyOwner {
        require(_maxWallet >= 777777777000000000000, "Popepe: maxWallet !< 777777777000000000000");
        emit UpdateMaxWallet(_maxWallet, maxWallet);
        maxWallet = _maxWallet;
    }

    function excludeFromMaxWallet(address _wallet, bool _status) public onlyOwner {
        require(isExcludedFromMaxWallet[_wallet] != _status, "Popepe: wallet status unchanged");
        isExcludedFromMaxWallet[_wallet] = _status;
        emit ExcludedFromMaxWallet(_wallet, _status);
    }

    function excludeFromMaxWalletBatch(address[] memory _wallets, bool _status) public onlyOwner {
        for (uint i; i < _wallets.length;) {
            isExcludedFromMaxWallet[_wallets[i]] = _status;
            unchecked { ++i; }
        }
    }

    function transfer(address _to, uint256 _amount) public override returns (bool) {
        if (!isExcludedFromMaxWallet[_to]) {
            require(_amount <= maxWallet, "Popepe: TX amount > max wallet limit");
            require((balanceOf[_to] + _amount) <= maxWallet, 
                "Popepe: Recipient balance would exceed max wallet limit");
        }
        return super.transfer(_to, _amount);
    }

    function transferFrom(
        address _from,
        address _to,
        uint256 _amount
    ) public override returns (bool) {
        if (!isExcludedFromMaxWallet[_to]) {
            require(_amount <= maxWallet, "Popepe: TX amount > max wallet limit");
            require((balanceOf[_to] + _amount) <= maxWallet, 
                "Popepe: Recipient balance would exceed max wallet limit");
        }
        return super.transferFrom(_from, _to, _amount);
    }

    function sacrifice(uint256 _amount) public returns (bool) {
        require(balanceOf[msg.sender] >= _amount, "Popepe: sacrifice > balance");
        _burn(msg.sender, _amount);
        uint256 totalBurned;
        if (EnumerableMap.contains(sacrifices, msg.sender)) {
            totalBurned += EnumerableMap.get(sacrifices, msg.sender);
        }
        totalBurned += _amount;
        EnumerableMap.set(sacrifices, msg.sender, totalBurned);
        emit TokenSacrifice(msg.sender, _amount);
        return true;
    }

    function listSacrificers() public view returns (address[] memory) {
        return EnumerableMap.keys(sacrifices);
    }

    function getSacrifice(address _wallet) public view returns (uint256) {
        return EnumerableMap.get(sacrifices, _wallet);
    }
}

File 2 of 5 : EnumerableMap.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableMap.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableMap.js.

pragma solidity ^0.8.0;

import "./EnumerableSet.sol";

/**
 * @dev Library for managing an enumerable variant of Solidity's
 * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
 * type.
 *
 * Maps have the following properties:
 *
 * - Entries are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Entries are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```solidity
 * contract Example {
 *     // Add the library methods
 *     using EnumerableMap for EnumerableMap.UintToAddressMap;
 *
 *     // Declare a set state variable
 *     EnumerableMap.UintToAddressMap private myMap;
 * }
 * ```
 *
 * The following map types are supported:
 *
 * - `uint256 -> address` (`UintToAddressMap`) since v3.0.0
 * - `address -> uint256` (`AddressToUintMap`) since v4.6.0
 * - `bytes32 -> bytes32` (`Bytes32ToBytes32Map`) since v4.6.0
 * - `uint256 -> uint256` (`UintToUintMap`) since v4.7.0
 * - `bytes32 -> uint256` (`Bytes32ToUintMap`) since v4.7.0
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableMap, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableMap.
 * ====
 */
library EnumerableMap {
    using EnumerableSet for EnumerableSet.Bytes32Set;

    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Map type with
    // bytes32 keys and values.
    // The Map implementation uses private functions, and user-facing
    // implementations (such as Uint256ToAddressMap) are just wrappers around
    // the underlying Map.
    // This means that we can only create new EnumerableMaps for types that fit
    // in bytes32.

    struct Bytes32ToBytes32Map {
        // Storage of keys
        EnumerableSet.Bytes32Set _keys;
        mapping(bytes32 => bytes32) _values;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(Bytes32ToBytes32Map storage map, bytes32 key, bytes32 value) internal returns (bool) {
        map._values[key] = value;
        return map._keys.add(key);
    }

    /**
     * @dev Removes a key-value pair from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(Bytes32ToBytes32Map storage map, bytes32 key) internal returns (bool) {
        delete map._values[key];
        return map._keys.remove(key);
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool) {
        return map._keys.contains(key);
    }

    /**
     * @dev Returns the number of key-value pairs in the map. O(1).
     */
    function length(Bytes32ToBytes32Map storage map) internal view returns (uint256) {
        return map._keys.length();
    }

    /**
     * @dev Returns the key-value pair stored at position `index` in the map. O(1).
     *
     * Note that there are no guarantees on the ordering of entries inside the
     * array, and it may change when more entries are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32ToBytes32Map storage map, uint256 index) internal view returns (bytes32, bytes32) {
        bytes32 key = map._keys.at(index);
        return (key, map._values[key]);
    }

    /**
     * @dev Tries to returns the value associated with `key`. O(1).
     * Does not revert if `key` is not in the map.
     */
    function tryGet(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bool, bytes32) {
        bytes32 value = map._values[key];
        if (value == bytes32(0)) {
            return (contains(map, key), bytes32(0));
        } else {
            return (true, value);
        }
    }

    /**
     * @dev Returns the value associated with `key`. O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(Bytes32ToBytes32Map storage map, bytes32 key) internal view returns (bytes32) {
        bytes32 value = map._values[key];
        require(value != 0 || contains(map, key), "EnumerableMap: nonexistent key");
        return value;
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(
        Bytes32ToBytes32Map storage map,
        bytes32 key,
        string memory errorMessage
    ) internal view returns (bytes32) {
        bytes32 value = map._values[key];
        require(value != 0 || contains(map, key), errorMessage);
        return value;
    }

    /**
     * @dev Return the an array containing all the keys
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function keys(Bytes32ToBytes32Map storage map) internal view returns (bytes32[] memory) {
        return map._keys.values();
    }

    // UintToUintMap

    struct UintToUintMap {
        Bytes32ToBytes32Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(UintToUintMap storage map, uint256 key, uint256 value) internal returns (bool) {
        return set(map._inner, bytes32(key), bytes32(value));
    }

    /**
     * @dev Removes a value from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(UintToUintMap storage map, uint256 key) internal returns (bool) {
        return remove(map._inner, bytes32(key));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(UintToUintMap storage map, uint256 key) internal view returns (bool) {
        return contains(map._inner, bytes32(key));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(UintToUintMap storage map) internal view returns (uint256) {
        return length(map._inner);
    }

    /**
     * @dev Returns the element stored at position `index` in the map. O(1).
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintToUintMap storage map, uint256 index) internal view returns (uint256, uint256) {
        (bytes32 key, bytes32 value) = at(map._inner, index);
        return (uint256(key), uint256(value));
    }

    /**
     * @dev Tries to returns the value associated with `key`. O(1).
     * Does not revert if `key` is not in the map.
     */
    function tryGet(UintToUintMap storage map, uint256 key) internal view returns (bool, uint256) {
        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));
        return (success, uint256(value));
    }

    /**
     * @dev Returns the value associated with `key`. O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToUintMap storage map, uint256 key) internal view returns (uint256) {
        return uint256(get(map._inner, bytes32(key)));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(UintToUintMap storage map, uint256 key, string memory errorMessage) internal view returns (uint256) {
        return uint256(get(map._inner, bytes32(key), errorMessage));
    }

    /**
     * @dev Return the an array containing all the keys
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function keys(UintToUintMap storage map) internal view returns (uint256[] memory) {
        bytes32[] memory store = keys(map._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Bytes32ToBytes32Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
        return set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
        return remove(map._inner, bytes32(key));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
        return contains(map._inner, bytes32(key));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(UintToAddressMap storage map) internal view returns (uint256) {
        return length(map._inner);
    }

    /**
     * @dev Returns the element stored at position `index` in the map. O(1).
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
        (bytes32 key, bytes32 value) = at(map._inner, index);
        return (uint256(key), address(uint160(uint256(value))));
    }

    /**
     * @dev Tries to returns the value associated with `key`. O(1).
     * Does not revert if `key` is not in the map.
     */
    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
        (bool success, bytes32 value) = tryGet(map._inner, bytes32(key));
        return (success, address(uint160(uint256(value))));
    }

    /**
     * @dev Returns the value associated with `key`. O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
        return address(uint160(uint256(get(map._inner, bytes32(key)))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(
        UintToAddressMap storage map,
        uint256 key,
        string memory errorMessage
    ) internal view returns (address) {
        return address(uint160(uint256(get(map._inner, bytes32(key), errorMessage))));
    }

    /**
     * @dev Return the an array containing all the keys
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function keys(UintToAddressMap storage map) internal view returns (uint256[] memory) {
        bytes32[] memory store = keys(map._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressToUintMap

    struct AddressToUintMap {
        Bytes32ToBytes32Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(AddressToUintMap storage map, address key, uint256 value) internal returns (bool) {
        return set(map._inner, bytes32(uint256(uint160(key))), bytes32(value));
    }

    /**
     * @dev Removes a value from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(AddressToUintMap storage map, address key) internal returns (bool) {
        return remove(map._inner, bytes32(uint256(uint160(key))));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(AddressToUintMap storage map, address key) internal view returns (bool) {
        return contains(map._inner, bytes32(uint256(uint160(key))));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(AddressToUintMap storage map) internal view returns (uint256) {
        return length(map._inner);
    }

    /**
     * @dev Returns the element stored at position `index` in the map. O(1).
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressToUintMap storage map, uint256 index) internal view returns (address, uint256) {
        (bytes32 key, bytes32 value) = at(map._inner, index);
        return (address(uint160(uint256(key))), uint256(value));
    }

    /**
     * @dev Tries to returns the value associated with `key`. O(1).
     * Does not revert if `key` is not in the map.
     */
    function tryGet(AddressToUintMap storage map, address key) internal view returns (bool, uint256) {
        (bool success, bytes32 value) = tryGet(map._inner, bytes32(uint256(uint160(key))));
        return (success, uint256(value));
    }

    /**
     * @dev Returns the value associated with `key`. O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(AddressToUintMap storage map, address key) internal view returns (uint256) {
        return uint256(get(map._inner, bytes32(uint256(uint160(key)))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(
        AddressToUintMap storage map,
        address key,
        string memory errorMessage
    ) internal view returns (uint256) {
        return uint256(get(map._inner, bytes32(uint256(uint160(key))), errorMessage));
    }

    /**
     * @dev Return the an array containing all the keys
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function keys(AddressToUintMap storage map) internal view returns (address[] memory) {
        bytes32[] memory store = keys(map._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // Bytes32ToUintMap

    struct Bytes32ToUintMap {
        Bytes32ToBytes32Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(Bytes32ToUintMap storage map, bytes32 key, uint256 value) internal returns (bool) {
        return set(map._inner, key, bytes32(value));
    }

    /**
     * @dev Removes a value from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(Bytes32ToUintMap storage map, bytes32 key) internal returns (bool) {
        return remove(map._inner, key);
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool) {
        return contains(map._inner, key);
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(Bytes32ToUintMap storage map) internal view returns (uint256) {
        return length(map._inner);
    }

    /**
     * @dev Returns the element stored at position `index` in the map. O(1).
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32ToUintMap storage map, uint256 index) internal view returns (bytes32, uint256) {
        (bytes32 key, bytes32 value) = at(map._inner, index);
        return (key, uint256(value));
    }

    /**
     * @dev Tries to returns the value associated with `key`. O(1).
     * Does not revert if `key` is not in the map.
     */
    function tryGet(Bytes32ToUintMap storage map, bytes32 key) internal view returns (bool, uint256) {
        (bool success, bytes32 value) = tryGet(map._inner, key);
        return (success, uint256(value));
    }

    /**
     * @dev Returns the value associated with `key`. O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(Bytes32ToUintMap storage map, bytes32 key) internal view returns (uint256) {
        return uint256(get(map._inner, key));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(
        Bytes32ToUintMap storage map,
        bytes32 key,
        string memory errorMessage
    ) internal view returns (uint256) {
        return uint256(get(map._inner, key, errorMessage));
    }

    /**
     * @dev Return the an array containing all the keys
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the map grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function keys(Bytes32ToUintMap storage map) internal view returns (bytes32[] memory) {
        bytes32[] memory store = keys(map._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

File 3 of 5 : EnumerableSet.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```solidity
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        bytes32[] memory store = _values(set._inner);
        bytes32[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

File 4 of 5 : Owned.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Simple single owner authorization mixin.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/auth/Owned.sol)
abstract contract Owned {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event OwnershipTransferred(address indexed user, address indexed newOwner);

    /*//////////////////////////////////////////////////////////////
                            OWNERSHIP STORAGE
    //////////////////////////////////////////////////////////////*/

    address public owner;

    modifier onlyOwner() virtual {
        require(msg.sender == owner, "UNAUTHORIZED");

        _;
    }

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(address _owner) {
        owner = _owner;

        emit OwnershipTransferred(address(0), _owner);
    }

    /*//////////////////////////////////////////////////////////////
                             OWNERSHIP LOGIC
    //////////////////////////////////////////////////////////////*/

    function transferOwnership(address newOwner) public virtual onlyOwner {
        owner = newOwner;

        emit OwnershipTransferred(msg.sender, newOwner);
    }
}

File 5 of 5 : ERC20.sol
// 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/transmissions11/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
    //////////////////////////////////////////////////////////////*/

    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 {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                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);
    }
}

Settings
{
  "remappings": [
    "ds-test/=lib/solmate/lib/ds-test/src/",
    "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/",
    "forge-std/=lib/forge-std/src/",
    "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/",
    "openzeppelin/=lib/openzeppelin-contracts/contracts/",
    "solmate/=lib/solmate/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "metadata": {
    "bytecodeHash": "ipfs"
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "london",
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"},{"internalType":"uint256","name":"_totalSupply","type":"uint256"},{"internalType":"uint256","name":"_maxWallet","type":"uint256"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"payable","type":"constructor"},{"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":"wallet","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExcludedFromMaxWallet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"wallet","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"TokenSacrifice","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":false,"internalType":"uint256","name":"newMaxWallet","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"oldMaxWallet","type":"uint256"}],"name":"UpdateMaxWallet","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","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":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"excludeFromMaxWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_wallets","type":"address[]"},{"internalType":"bool","name":"_status","type":"bool"}],"name":"excludeFromMaxWalletBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"getSacrifice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isExcludedFromMaxWallet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"listSacrificers","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxWallet","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":"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":"uint256","name":"_amount","type":"uint256"}],"name":"sacrifice","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","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":"_maxWallet","type":"uint256"}],"name":"updateMaxWallet","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e060405260405162001cb338038062001cb38339810160408190526200002691620003f3565b8086868660006200003884826200053b565b5060016200004783826200053b565b5060ff81166080524660a0526200005d62000225565b60c0525050600680546001600160a01b0319166001600160a01b0384169081179091556040519091506000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600a829055306000818152600b602090815260408083208054600160ff1991821681179092557f44433eeeda1d04bdae79f62169cdb2ab0a6af287fa15706d3fafdbac5fac341580548216831790557fdf7de25b7f1fd6d0b5205f0e18f1f35bd7b8d84cce336588d184533ce43a6f76805482168317905533855282852080548216831790556001600160a01b038716855293829020805490941681179093555191825260008051602062001c93833981519152910160405180910390a26040516001815261dead9060008051602062001c938339815191529060200160405180910390a26040516001815260009060008051602062001c938339815191529060200160405180910390a260405160018152339060008051602062001c938339815191529060200160405180910390a2604051600181526001600160a01b0382169060008051602062001c938339815191529060200160405180910390a2620002198184620002c1565b505050505050620006ad565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f600060405162000259919062000607565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b8060026000828254620002d5919062000685565b90915550506001600160a01b0382166000818152600360209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200035657600080fd5b81516001600160401b03808211156200037357620003736200032e565b604051601f8301601f19908116603f011681019082821181831017156200039e576200039e6200032e565b81604052838152602092508683858801011115620003bb57600080fd5b600091505b83821015620003df5785820183015181830184015290820190620003c0565b600093810190920192909252949350505050565b60008060008060008060c087890312156200040d57600080fd5b86516001600160401b03808211156200042557600080fd5b620004338a838b0162000344565b975060208901519150808211156200044a57600080fd5b506200045989828a0162000344565b955050604087015160ff811681146200047157600080fd5b6060880151608089015160a08a015192965090945092506001600160a01b03811681146200049e57600080fd5b809150509295509295509295565b600181811c90821680620004c157607f821691505b602082108103620004e257634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200053657600081815260208120601f850160051c81016020861015620005115750805b601f850160051c820191505b8181101562000532578281556001016200051d565b5050505b505050565b81516001600160401b038111156200055757620005576200032e565b6200056f81620005688454620004ac565b84620004e8565b602080601f831160018114620005a757600084156200058e5750858301515b600019600386901b1c1916600185901b17855562000532565b600085815260208120601f198616915b82811015620005d857888601518255948401946001909101908401620005b7565b5085821015620005f75787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60008083546200061781620004ac565b60018281168015620006325760018114620006485762000679565b60ff198416875282151583028701945062000679565b8760005260208060002060005b85811015620006705781548a82015290840190820162000655565b50505082870194505b50929695505050505050565b80820180821115620006a757634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c0516115b6620006dd600039600061061b015260006105e6015260006101cc01526115b66000f3fe608060405234801561001057600080fd5b50600436106101425760003560e01c806383c5db63116100b8578063d505accf1161007c578063d505accf146102ec578063dd62ed3e146102ff578063e178e0511461032a578063edf593481461033d578063f2fde38b14610350578063f8b45b051461036357600080fd5b806383c5db63146102805780638da5cb5b1461029357806395d89b41146102be578063a9059cbb146102c6578063d2fcc001146102d957600080fd5b8063313ce5671161010a578063313ce567146101c75780633644e515146102005780634b9d9cc4146102085780636dd3d39f1461021d57806370a08231146102405780637ecebe001461026057600080fd5b806306fdde0314610147578063095ea7b31461016557806318160ddd146101885780631c499ab01461019f57806323b872dd146101b4575b600080fd5b61014f61036c565b60405161015c9190611070565b60405180910390f35b6101786101733660046110da565b6103fa565b604051901515815260200161015c565b61019160025481565b60405190815260200161015c565b6101b26101ad366004611104565b610467565b005b6101786101c236600461111d565b610548565b6101ee7f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff909116815260200161015c565b6101916105e2565b61021061063d565b60405161015c9190611159565b61017861022b3660046111a6565b600b6020526000908152604090205460ff1681565b61019161024e3660046111a6565b60036020526000908152604090205481565b61019161026e3660046111a6565b60056020526000908152604090205481565b6101b261028e3660046111e7565b610649565b6006546102a6906001600160a01b031681565b6040516001600160a01b03909116815260200161015c565b61014f6106d5565b6101786102d43660046110da565b6106e2565b6101b26102e73660046112be565b61077a565b6101b26102fa3660046112f1565b610873565b61019161030d366004611364565b600460209081526000928352604080842090915290825290205481565b610178610338366004611104565b610ab7565b61019161034b3660046111a6565b610ba1565b6101b261035e3660046111a6565b610bae565b610191600a5481565b600080546103799061138e565b80601f01602080910402602001604051908101604052809291908181526020018280546103a59061138e565b80156103f25780601f106103c7576101008083540402835291602001916103f2565b820191906000526020600020905b8154815290600101906020018083116103d557829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906104559086815260200190565b60405180910390a35060015b92915050565b6006546001600160a01b0316331461049a5760405162461bcd60e51b8152600401610491906113c8565b60405180910390fd5b682a29d5bf5695fc10008110156105065760405162461bcd60e51b815260206004820152602a60248201527f506f706570653a206d617857616c6c657420213c2037373737373737373730306044820152690303030303030303030360b41b6064820152608401610491565b600a546040805183815260208101929092527fff64d41f60feb77d52f64ae64a9fc3929d57a89d0cc55728762468bae5e0fe52910160405180910390a1600a55565b6001600160a01b0382166000908152600b602052604081205460ff166105cf57600a5482111561058a5760405162461bcd60e51b8152600401610491906113ee565b600a546001600160a01b0384166000908152600360205260409020546105b1908490611448565b11156105cf5760405162461bcd60e51b81526004016104919061145b565b6105da848484610c24565b949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000000461461061857610613610d16565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b60606106136007610db0565b6006546001600160a01b031633146106735760405162461bcd60e51b8152600401610491906113c8565b60005b82518110156106d05781600b6000858481518110610696576106966114b8565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101610676565b505050565b600180546103799061138e565b6001600160a01b0382166000908152600b602052604081205460ff1661076957600a548211156107245760405162461bcd60e51b8152600401610491906113ee565b600a546001600160a01b03841660009081526003602052604090205461074b908490611448565b11156107695760405162461bcd60e51b81526004016104919061145b565b6107738383610dbd565b9392505050565b6006546001600160a01b031633146107a45760405162461bcd60e51b8152600401610491906113c8565b6001600160a01b0382166000908152600b602052604090205481151560ff9091161515036108145760405162461bcd60e51b815260206004820152601f60248201527f506f706570653a2077616c6c65742073746174757320756e6368616e676564006044820152606401610491565b6001600160a01b0382166000818152600b6020908152604091829020805460ff191685151590811790915591519182527f817ed04ba7740905786c51bb255d8b90dc2b0989e59d2d8a3ecdfdd225ec94c7910160405180910390a25050565b428410156108c35760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610491565b600060016108cf6105e2565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa1580156109db573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610a115750876001600160a01b0316816001600160a01b0316145b610a4e5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610491565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b33600090815260036020526040812054821115610b165760405162461bcd60e51b815260206004820152601b60248201527f506f706570653a20736163726966696365203e2062616c616e636500000000006044820152606401610491565b610b203383610e35565b6000610b2d600733610eb0565b15610b4a57610b3d600733610ec5565b610b479082611448565b90505b610b548382611448565b9050610b6260073383610eda565b5060405183815233907f547854379c6db1916fb9096726470ab6346a4ce8921760b57e89c52e2216767f9060200160405180910390a250600192915050565b6000610461600783610ec5565b6006546001600160a01b03163314610bd85760405162461bcd60e51b8152600401610491906113c8565b600680546001600160a01b0319166001600160a01b03831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610c8057610c5b83826114ce565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610ca89084906114ce565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610d039087815260200190565b60405180910390a3506001949350505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051610d4891906114e1565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6060600061077383610ef0565b33600090815260036020526040812080548391908390610dde9084906114ce565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906104559086815260200190565b6001600160a01b03821660009081526003602052604081208054839290610e5d9084906114ce565b90915550506002805482900390556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6000610773836001600160a01b038416610efb565b6000610773836001600160a01b038416610f07565b60006105da846001600160a01b03851684610f77565b606061046182610f94565b60006107738383610fa1565b600081815260028301602052604081205480151580610f2b5750610f2b8484610efb565b6107735760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b657900006044820152606401610491565b600082815260028401602052604081208290556105da8484610fb9565b6060600061077383610fc5565b60008181526001830160205260408120541515610773565b60006107738383611021565b60608160000180548060200260200160405190810160405280929190818152602001828054801561101557602002820191906000526020600020905b815481526020019060010190808311611001575b50505050509050919050565b600081815260018301602052604081205461106857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610461565b506000610461565b600060208083528351808285015260005b8181101561109d57858101830151858201604001528201611081565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146110d557600080fd5b919050565b600080604083850312156110ed57600080fd5b6110f6836110be565b946020939093013593505050565b60006020828403121561111657600080fd5b5035919050565b60008060006060848603121561113257600080fd5b61113b846110be565b9250611149602085016110be565b9150604084013590509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561119a5783516001600160a01b031683529284019291840191600101611175565b50909695505050505050565b6000602082840312156111b857600080fd5b610773826110be565b634e487b7160e01b600052604160045260246000fd5b803580151581146110d557600080fd5b600080604083850312156111fa57600080fd5b823567ffffffffffffffff8082111561121257600080fd5b818501915085601f83011261122657600080fd5b813560208282111561123a5761123a6111c1565b8160051b604051601f19603f8301168101818110868211171561125f5761125f6111c1565b60405292835281830193508481018201928984111561127d57600080fd5b948201945b838610156112a257611293866110be565b85529482019493820193611282565b96506112b190508782016111d7565b9450505050509250929050565b600080604083850312156112d157600080fd5b6112da836110be565b91506112e8602084016111d7565b90509250929050565b600080600080600080600060e0888a03121561130c57600080fd5b611315886110be565b9650611323602089016110be565b95506040880135945060608801359350608088013560ff8116811461134757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561137757600080fd5b611380836110be565b91506112e8602084016110be565b600181811c908216806113a257607f821691505b6020821081036113c257634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b60208082526024908201527f506f706570653a20545820616d6f756e74203e206d61782077616c6c6574206c6040820152631a5b5a5d60e21b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8082018082111561046157610461611432565b60208082526037908201527f506f706570653a20526563697069656e742062616c616e636520776f756c642060408201527f657863656564206d61782077616c6c6574206c696d6974000000000000000000606082015260800190565b634e487b7160e01b600052603260045260246000fd5b8181038181111561046157610461611432565b600080835481600182811c9150808316806114fd57607f831692505b6020808410820361151c57634e487b7160e01b86526022600452602486fd5b818015611530576001811461154557611572565b60ff1986168952841515850289019650611572565b60008a81526020902060005b8681101561156a5781548b820152908501908301611551565b505084890196505b50949897505050505050505056fea26469706673582212209cf1f0b4a685d6690f4f5d31116f40b1f9b170667074461d4c8244a3d4a95dee64736f6c63430008110033817ed04ba7740905786c51bb255d8b90dc2b0989e59d2d8a3ecdfdd225ec94c700000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000002835cd9c6d6f2156b24000000000000000000000000000000000000000000000000a4b36af36a39e09e800000000000000000000000000024008d618bd73aa760bc58109fbbf8b9f578e5470000000000000000000000000000000000000000000000000000000000000006506f7065706500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006504f504550450000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101425760003560e01c806383c5db63116100b8578063d505accf1161007c578063d505accf146102ec578063dd62ed3e146102ff578063e178e0511461032a578063edf593481461033d578063f2fde38b14610350578063f8b45b051461036357600080fd5b806383c5db63146102805780638da5cb5b1461029357806395d89b41146102be578063a9059cbb146102c6578063d2fcc001146102d957600080fd5b8063313ce5671161010a578063313ce567146101c75780633644e515146102005780634b9d9cc4146102085780636dd3d39f1461021d57806370a08231146102405780637ecebe001461026057600080fd5b806306fdde0314610147578063095ea7b31461016557806318160ddd146101885780631c499ab01461019f57806323b872dd146101b4575b600080fd5b61014f61036c565b60405161015c9190611070565b60405180910390f35b6101786101733660046110da565b6103fa565b604051901515815260200161015c565b61019160025481565b60405190815260200161015c565b6101b26101ad366004611104565b610467565b005b6101786101c236600461111d565b610548565b6101ee7f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff909116815260200161015c565b6101916105e2565b61021061063d565b60405161015c9190611159565b61017861022b3660046111a6565b600b6020526000908152604090205460ff1681565b61019161024e3660046111a6565b60036020526000908152604090205481565b61019161026e3660046111a6565b60056020526000908152604090205481565b6101b261028e3660046111e7565b610649565b6006546102a6906001600160a01b031681565b6040516001600160a01b03909116815260200161015c565b61014f6106d5565b6101786102d43660046110da565b6106e2565b6101b26102e73660046112be565b61077a565b6101b26102fa3660046112f1565b610873565b61019161030d366004611364565b600460209081526000928352604080842090915290825290205481565b610178610338366004611104565b610ab7565b61019161034b3660046111a6565b610ba1565b6101b261035e3660046111a6565b610bae565b610191600a5481565b600080546103799061138e565b80601f01602080910402602001604051908101604052809291908181526020018280546103a59061138e565b80156103f25780601f106103c7576101008083540402835291602001916103f2565b820191906000526020600020905b8154815290600101906020018083116103d557829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925906104559086815260200190565b60405180910390a35060015b92915050565b6006546001600160a01b0316331461049a5760405162461bcd60e51b8152600401610491906113c8565b60405180910390fd5b682a29d5bf5695fc10008110156105065760405162461bcd60e51b815260206004820152602a60248201527f506f706570653a206d617857616c6c657420213c2037373737373737373730306044820152690303030303030303030360b41b6064820152608401610491565b600a546040805183815260208101929092527fff64d41f60feb77d52f64ae64a9fc3929d57a89d0cc55728762468bae5e0fe52910160405180910390a1600a55565b6001600160a01b0382166000908152600b602052604081205460ff166105cf57600a5482111561058a5760405162461bcd60e51b8152600401610491906113ee565b600a546001600160a01b0384166000908152600360205260409020546105b1908490611448565b11156105cf5760405162461bcd60e51b81526004016104919061145b565b6105da848484610c24565b949350505050565b60007f0000000000000000000000000000000000000000000000000000000000000001461461061857610613610d16565b905090565b507f20a52795d4b16d45862503b7222c0d17dffa893e599a40bd2c598182c9bc336190565b60606106136007610db0565b6006546001600160a01b031633146106735760405162461bcd60e51b8152600401610491906113c8565b60005b82518110156106d05781600b6000858481518110610696576106966114b8565b6020908102919091018101516001600160a01b03168252810191909152604001600020805460ff1916911515919091179055600101610676565b505050565b600180546103799061138e565b6001600160a01b0382166000908152600b602052604081205460ff1661076957600a548211156107245760405162461bcd60e51b8152600401610491906113ee565b600a546001600160a01b03841660009081526003602052604090205461074b908490611448565b11156107695760405162461bcd60e51b81526004016104919061145b565b6107738383610dbd565b9392505050565b6006546001600160a01b031633146107a45760405162461bcd60e51b8152600401610491906113c8565b6001600160a01b0382166000908152600b602052604090205481151560ff9091161515036108145760405162461bcd60e51b815260206004820152601f60248201527f506f706570653a2077616c6c65742073746174757320756e6368616e676564006044820152606401610491565b6001600160a01b0382166000818152600b6020908152604091829020805460ff191685151590811790915591519182527f817ed04ba7740905786c51bb255d8b90dc2b0989e59d2d8a3ecdfdd225ec94c7910160405180910390a25050565b428410156108c35760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f455850495245440000000000000000006044820152606401610491565b600060016108cf6105e2565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa1580156109db573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590610a115750876001600160a01b0316816001600160a01b0316145b610a4e5760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401610491565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b33600090815260036020526040812054821115610b165760405162461bcd60e51b815260206004820152601b60248201527f506f706570653a20736163726966696365203e2062616c616e636500000000006044820152606401610491565b610b203383610e35565b6000610b2d600733610eb0565b15610b4a57610b3d600733610ec5565b610b479082611448565b90505b610b548382611448565b9050610b6260073383610eda565b5060405183815233907f547854379c6db1916fb9096726470ab6346a4ce8921760b57e89c52e2216767f9060200160405180910390a250600192915050565b6000610461600783610ec5565b6006546001600160a01b03163314610bd85760405162461bcd60e51b8152600401610491906113c8565b600680546001600160a01b0319166001600160a01b03831690811790915560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610c8057610c5b83826114ce565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610ca89084906114ce565b90915550506001600160a01b03808516600081815260036020526040908190208054870190555190918716907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610d039087815260200190565b60405180910390a3506001949350505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051610d4891906114e1565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6060600061077383610ef0565b33600090815260036020526040812080548391908390610dde9084906114ce565b90915550506001600160a01b038316600081815260036020526040908190208054850190555133907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906104559086815260200190565b6001600160a01b03821660009081526003602052604081208054839290610e5d9084906114ce565b90915550506002805482900390556040518181526000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b6000610773836001600160a01b038416610efb565b6000610773836001600160a01b038416610f07565b60006105da846001600160a01b03851684610f77565b606061046182610f94565b60006107738383610fa1565b600081815260028301602052604081205480151580610f2b5750610f2b8484610efb565b6107735760405162461bcd60e51b815260206004820152601e60248201527f456e756d657261626c654d61703a206e6f6e6578697374656e74206b657900006044820152606401610491565b600082815260028401602052604081208290556105da8484610fb9565b6060600061077383610fc5565b60008181526001830160205260408120541515610773565b60006107738383611021565b60608160000180548060200260200160405190810160405280929190818152602001828054801561101557602002820191906000526020600020905b815481526020019060010190808311611001575b50505050509050919050565b600081815260018301602052604081205461106857508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610461565b506000610461565b600060208083528351808285015260005b8181101561109d57858101830151858201604001528201611081565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b03811681146110d557600080fd5b919050565b600080604083850312156110ed57600080fd5b6110f6836110be565b946020939093013593505050565b60006020828403121561111657600080fd5b5035919050565b60008060006060848603121561113257600080fd5b61113b846110be565b9250611149602085016110be565b9150604084013590509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561119a5783516001600160a01b031683529284019291840191600101611175565b50909695505050505050565b6000602082840312156111b857600080fd5b610773826110be565b634e487b7160e01b600052604160045260246000fd5b803580151581146110d557600080fd5b600080604083850312156111fa57600080fd5b823567ffffffffffffffff8082111561121257600080fd5b818501915085601f83011261122657600080fd5b813560208282111561123a5761123a6111c1565b8160051b604051601f19603f8301168101818110868211171561125f5761125f6111c1565b60405292835281830193508481018201928984111561127d57600080fd5b948201945b838610156112a257611293866110be565b85529482019493820193611282565b96506112b190508782016111d7565b9450505050509250929050565b600080604083850312156112d157600080fd5b6112da836110be565b91506112e8602084016111d7565b90509250929050565b600080600080600080600060e0888a03121561130c57600080fd5b611315886110be565b9650611323602089016110be565b95506040880135945060608801359350608088013560ff8116811461134757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561137757600080fd5b611380836110be565b91506112e8602084016110be565b600181811c908216806113a257607f821691505b6020821081036113c257634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252600c908201526b15539055551213d49256915160a21b604082015260600190565b60208082526024908201527f506f706570653a20545820616d6f756e74203e206d61782077616c6c6574206c6040820152631a5b5a5d60e21b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b8082018082111561046157610461611432565b60208082526037908201527f506f706570653a20526563697069656e742062616c616e636520776f756c642060408201527f657863656564206d61782077616c6c6574206c696d6974000000000000000000606082015260800190565b634e487b7160e01b600052603260045260246000fd5b8181038181111561046157610461611432565b600080835481600182811c9150808316806114fd57607f831692505b6020808410820361151c57634e487b7160e01b86526022600452602486fd5b818015611530576001811461154557611572565b60ff1986168952841515850289019650611572565b60008a81526020902060005b8681101561156a5781548b820152908501908301611551565b505084890196505b50949897505050505050505056fea26469706673582212209cf1f0b4a685d6690f4f5d31116f40b1f9b170667074461d4c8244a3d4a95dee64736f6c63430008110033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

00000000000000000000000000000000000000000000000000000000000000c000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000002835cd9c6d6f2156b24000000000000000000000000000000000000000000000000a4b36af36a39e09e800000000000000000000000000024008d618bd73aa760bc58109fbbf8b9f578e5470000000000000000000000000000000000000000000000000000000000000006506f7065706500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006504f504550450000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _name (string): Popepe
Arg [1] : _symbol (string): POPEPE
Arg [2] : _decimals (uint8): 18
Arg [3] : _totalSupply (uint256): 777777777000000000000000000
Arg [4] : _maxWallet (uint256): 777777777000000000000000
Arg [5] : _owner (address): 0x24008D618bd73aa760bC58109FBbf8b9F578e547

-----Encoded View---------------
10 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000100
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [3] : 000000000000000000000000000000000000000002835cd9c6d6f2156b240000
Arg [4] : 00000000000000000000000000000000000000000000a4b36af36a39e09e8000
Arg [5] : 00000000000000000000000024008d618bd73aa760bc58109fbbf8b9f578e547
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [7] : 506f706570650000000000000000000000000000000000000000000000000000
Arg [8] : 0000000000000000000000000000000000000000000000000000000000000006
Arg [9] : 504f504550450000000000000000000000000000000000000000000000000000


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.