Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Tib74, [4/22/2022 6:56 PM]
- /**
- *Submitted for verification at BscScan.com on 2021-11-21
- */
- // Dependency file: @openzeppelin/contracts/token/ERC20/IERC20.sol
- // SPDX-License-Identifier: MIT
- // pragma solidity ^0.8.0;
- /**
- * @dev Interface of the ERC20 standard as defined in the EIP.
- */
- interface IERC20 {
- /**
- * @dev Returns the amount of tokens in existence.
- */
- function totalSupply() external view returns (uint256);
- /**
- * @dev Returns the amount of tokens owned by account.
- */
- function balanceOf(address account) external view returns (uint256);
- /**
- * @dev Moves amount tokens from the caller's account to recipient.
- *
- * Returns a boolean value indicating whether the operation succeeded.
- *
- * Emits a {Transfer} event.
- */
- 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}. This is
- * zero by default.
- *
- * This value changes when {approve} or {transferFrom} are called.
- */
- function allowance(address owner, address spender) external view returns (uint256);
- /**
- * @dev Sets amount as the allowance of spender over the caller's tokens.
- *
- * Returns a boolean value indicating whether the operation succeeded.
- *
- * IMPORTANT: Beware that changing an allowance with this method brings the risk
- * that someone may use both the old and the new allowance by unfortunate
- * transaction ordering. One possible solution to mitigate this race
- * condition is to first reduce the spender's allowance to 0 and set the
- * desired value afterwards:
- * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
- *
- * Emits an {Approval} event.
- */
- function approve(address spender, uint256 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.
- *
- * Returns a boolean value indicating whether the operation succeeded.
- *
- * Emits a {Transfer} event.
- */
- function transferFrom(
- address sender,
- address recipient,
- uint256 amount
- ) external returns (bool);
- /**
- * @dev Emitted when value tokens are moved from one account (`from`) to
- * another (`to`).
- *
- * Note that value may be zero.
- */
- event Transfer(address indexed from, address indexed to, uint256 value);
- /**
- * @dev Emitted when the allowance of a spender for an owner is set by
- * a call to {approve}. value is the new allowance.
- */
- event Approval(address indexed owner, address indexed spender, uint256 value);
- }
- // Dependency file: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol
- // pragma solidity ^0.8.0;
- // import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
- /**
- * @dev Interface for the optional metadata functions from the ERC20 standard.
- *
- * _Available since v4.1._
- */
- interface IERC20Metadata is IERC20 {
- /**
- * @dev Returns the name of the token.
- */
- function name() external view returns (string memory);
- /**
- * @dev Returns the symbol of the token.
- */
- function symbol() external view returns (string memory);
- /**
- * @dev Returns the decimals places of the token.
- */
- function decimals() external view returns (uint8);
- }
- // Dependency file: @openzeppelin/contracts/utils/Context.sol
- // pragma solidity ^0.8.0;
- /**
- * @dev Provides information about the current execution context, including the
- * sender of the transaction and its data. While these are generally available
- * via msg.sender and msg.data, they should not be accessed in such a direct
- * manner, since when dealing with meta-transactions the account sending and
- * paying for execution may not be the actual sender (as far as an application
- * is concerned).
- *
- Tib74, [4/22/2022 6:56 PM]
- * This contract is only required for intermediate, library-like contracts.
- */
- abstract contract Context {
- function _msgSender() internal view virtual returns (address) {
- return msg.sender;
- }
- function _msgData() internal view virtual returns (bytes calldata) {
- return msg.data;
- }
- }
- // Dependency file: @openzeppelin/contracts/token/ERC20/ERC20.sol
- // pragma solidity ^0.8.0;
- // import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
- // import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
- // import "@openzeppelin/contracts/utils/Context.sol";
- /**
- * @dev Implementation of the {IERC20} interface.
- *
- * This implementation is agnostic to the way tokens are created. This means
- * that a supply mechanism has to be added in a derived contract using {_mint}.
- * For a generic mechanism see {ERC20PresetMinterPauser}.
- *
- * TIP: For a detailed writeup see our guide
- * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
- * to implement supply mechanisms].
- *
- * We have followed general OpenZeppelin Contracts guidelines: functions revert
- * instead returning false on failure. This behavior is nonetheless
- * conventional and does not conflict with the expectations of ERC20
- * applications.
- *
- * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
- * This allows applications to reconstruct the allowance for all accounts just
- * by listening to said events. Other implementations of the EIP may not emit
- * these events, as it isn't required by the specification.
- *
- * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
- * functions have been added to mitigate the well-known issues around setting
- * allowances. See {IERC20-approve}.
- */
- contract ERC20 is Context, IERC20, IERC20Metadata {
- mapping(address => uint256) private _balances;
- mapping(address => mapping(address => uint256)) private _allowances;
- uint256 private _totalSupply;
- string private _name;
- string private _symbol;
- /**
- * @dev Sets the values for {name} and {symbol}.
- *
- * The default value of {decimals} is 18. To select a different value for
- * {decimals} you should overload it.
- *
- * All two of these values are immutable: they can only be set once during
- * construction.
- */
- constructor(string memory name_, string memory symbol_) {
- _name = name_;
- _symbol = symbol_;
- }
- /**
- * @dev Returns the name of the token.
- */
- function name() public view virtual override returns (string memory) {
- return _name;
- }
- /**
- * @dev Returns the symbol of the token, usually a shorter version of the
- * name.
- */
- function symbol() public view virtual override returns (string memory) {
- return _symbol;
- }
- /**
- * @dev Returns the number of decimals used to get its user representation.
- * For example, if decimals equals 2, a balance of 505 tokens should
- * be displayed to a user as 5.05 (`505 / 10 ** 2`).
- *
- * Tokens usually opt for a value of 18, imitating the relationship between
- * Ether and Wei. This is the value {ERC20} uses, unless this function is
- * overridden;
- *
- * NOTE: This information is only used for _display_ purposes: it in
- * no way affects any of the arithmetic of the contract, including
- * {IERC20-balanceOf} and {IERC20-transfer}.
- */
- function decimals() public view virtual override returns (uint8) {
- return 18;
- }
- /**
- * @dev See {IERC20-totalSupply}.
- */
- function totalSupply() public view virtual override returns (uint256) {
- return _totalSupply;
- }
- /**
- * @dev See {IERC20-balanceOf}.
- */
- function balanceOf(address account) public view virtual override returns (uint256) {
- return _balances[account];
- }
- /**
- * @dev See {IERC20-transfer}.
- *
- * Requirements:
- *
- * - recipient cannot be the zero address.
- * - the caller must have a balance of at least amount.
- Tib74, [4/22/2022 6:56 PM]
- */
- function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
- _transfer(_msgSender(), recipient, amount);
- return true;
- }
- /**
- * @dev See {IERC20-allowance}.
- */
- function allowance(address owner, address spender) public view virtual override returns (uint256) {
- return _allowances[owner][spender];
- }
- /**
- * @dev See {IERC20-approve}.
- *
- * Requirements:
- *
- * - spender cannot be the zero address.
- */
- function approve(address spender, uint256 amount) public virtual override returns (bool) {
- _approve(_msgSender(), spender, amount);
- return true;
- }
- /**
- * @dev See {IERC20-transferFrom}.
- *
- * Emits an {Approval} event indicating the updated allowance. This is not
- * required by the EIP. See the note at the beginning of {ERC20}.
- *
- * Requirements:
- *
- * - sender and recipient cannot be the zero address.
- * - sender must have a balance of at least amount.
- * - the caller must have allowance for ``sender``'s tokens of at least
- * amount.
- */
- function transferFrom(
- address sender,
- address recipient,
- uint256 amount
- ) public virtual override returns (bool) {
- _transfer(sender, recipient, amount);
- uint256 currentAllowance = _allowances[sender][_msgSender()];
- require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
- unchecked {
- _approve(sender, _msgSender(), currentAllowance - amount);
- }
- return true;
- }
- /**
- * @dev Atomically increases the allowance granted to spender by the caller.
- *
- * This is an alternative to {approve} that can be used as a mitigation for
- * problems described in {IERC20-approve}.
- *
- * Emits an {Approval} event indicating the updated allowance.
- *
- * Requirements:
- *
- * - spender cannot be the zero address.
- */
- function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
- _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
- return true;
- }
- /**
- * @dev Atomically decreases the allowance granted to spender by the caller.
- *
- * This is an alternative to {approve} that can be used as a mitigation for
- * problems described in {IERC20-approve}.
- *
- * Emits an {Approval} event indicating the updated allowance.
- *
- * Requirements:
- *
- * - spender cannot be the zero address.
- * - spender must have allowance for the caller of at least
- * subtractedValue.
- */
- function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
- uint256 currentAllowance = _allowances[_msgSender()][spender];
- require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
- unchecked {
- _approve(_msgSender(), spender, currentAllowance - subtractedValue);
- }
- return true;
- }
- /**
- * @dev Moves amount of tokens from sender to recipient.
- *
- * This internal function is equivalent to {transfer}, and can be used to
- * e.g. implement automatic token fees, slashing mechanisms, etc.
- *
- * Emits a {Transfer} event.
- *
- * Requirements:
- *
- * - sender cannot be the zero address.
- * - recipient cannot be the zero address.
- * - sender must have a balance of at least amount.
- */
- function _transfer(
- address sender,
- address recipient,
- uint256 amount
- ) internal virtual {
- require(sender != address(0), "ERC20: transfer from the zero address");
- require(recipient != address(0), "ERC20: transfer to the zero address");
- _beforeTokenTransfer(sender, recipient, amount);
- uint256 senderBalance = _balances[sender];
- require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
- unchecked {
- Tib74, [4/22/2022 6:56 PM]
- _balances[sender] = senderBalance - amount;
- }
- _balances[recipient] += amount;
- emit Transfer(sender, recipient, amount);
- _afterTokenTransfer(sender, recipient, amount);
- }
- /** @dev Creates amount tokens and assigns them to account, increasing
- * the total supply.
- *
- * Emits a {Transfer} event with from set to the zero address.
- *
- * Requirements:
- *
- * - account cannot be the zero address.
- */
- function _mint(address account, uint256 amount) internal virtual {
- require(account != address(0), "ERC20: mint to the zero address");
- _beforeTokenTransfer(address(0), account, amount);
- _totalSupply += amount;
- _balances[account] += amount;
- emit Transfer(address(0), account, amount);
- _afterTokenTransfer(address(0), account, amount);
- }
- /**
- * @dev Destroys amount tokens from account, reducing the
- * total supply.
- *
- * Emits a {Transfer} event with to set to the zero address.
- *
- * Requirements:
- *
- * - account cannot be the zero address.
- * - account must have at least amount tokens.
- */
- function _burn(address account, uint256 amount) internal virtual {
- require(account != address(0), "ERC20: burn from the zero address");
- _beforeTokenTransfer(account, address(0), amount);
- uint256 accountBalance = _balances[account];
- require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
- unchecked {
- _balances[account] = accountBalance - amount;
- }
- _totalSupply -= amount;
- emit Transfer(account, address(0), amount);
- _afterTokenTransfer(account, address(0), amount);
- }
- /**
- * @dev Sets amount as the allowance of spender over the owner s tokens.
- *
- * This internal function is equivalent to approve, and can be used to
- * e.g. set automatic allowances for certain subsystems, etc.
- *
- * Emits an {Approval} event.
- *
- * Requirements:
- *
- * - owner cannot be the zero address.
- * - spender cannot be the zero address.
- */
- function _approve(
- address owner,
- address spender,
- uint256 amount
- ) internal virtual {
- 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);
- }
- /**
- * @dev Hook that is called before any transfer of tokens. This includes
- * minting and burning.
- *
- * Calling conditions:
- *
- * - when from and to are both non-zero, amount of ``from``'s tokens
- * will be transferred to to.
- * - when from is zero, amount tokens will be minted for to.
- * - when to is zero, amount of ``from``'s tokens will be burned.
- * - from and to are never both zero.
- *
- * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
- */
- function _beforeTokenTransfer(
- address from,
- address to,
- uint256 amount
- ) internal virtual {}
- /**
- * @dev Hook that is called after any transfer of tokens. This includes
- * minting and burning.
- *
- * Calling conditions:
- *
- * - when from and to are both non-zero, amount of ``from``'s tokens
- * has been transferred to to.
- * - when from is zero, amount tokens have been minted for to.
- * - when to is zero, amount of ``from``'s tokens have been burned.
- * - from and to are never both zero.
- *
- * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
- */
- function _afterTokenTransfer(
- address from,
- address to,
- uint256 amount
- ) internal virtual {}
- }
- // Dependency file: @openzeppelin/contracts/access/Ownable.sol
- // pragma solidity ^0.8.0;
- // import "@openzeppelin/contracts/utils/Context.sol";
- /**
- Tib74, [4/22/2022 6:56 PM]
- * @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 module is used through inheritance. It will make available the modifier
- * onlyOwner, which can be applied to your functions to restrict their use to
- * the owner.
- */
- abstract contract Ownable is Context {
- address private _owner;
- event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
- /**
- * @dev Initializes the contract setting the deployer as the initial owner.
- */
- constructor() {
- _setOwner(_msgSender());
- }
- /**
- * @dev Returns the address of the current owner.
- */
- function owner() public view virtual returns (address) {
- return _owner;
- }
- /**
- * @dev Throws if called by any account other than the owner.
- */
- 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.
- */
- function renounceOwnership() public virtual onlyOwner {
- _setOwner(address(0));
- }
- /**
- * @dev Transfers ownership of the contract to a new account (`newOwner`).
- * Can only be called by the current owner.
- */
- function transferOwnership(address newOwner) public virtual onlyOwner {
- require(newOwner != address(0), "Ownable: new owner is the zero address");
- _setOwner(newOwner);
- }
- function _setOwner(address newOwner) private {
- address oldOwner = _owner;
- _owner = newOwner;
- emit OwnershipTransferred(oldOwner, newOwner);
- }
- }
- // Dependency file: @openzeppelin/contracts/utils/math/SafeMath.sol
- // pragma solidity ^0.8.0;
- // CAUTION
- // This version of SafeMath should only be used with Solidity 0.8 or later,
- // because it relies on the compiler's built in overflow checks.
- /**
- * @dev Wrappers over Solidity's arithmetic operations.
- *
- * NOTE: SafeMath is no longer needed starting with Solidity 0.8. The compiler
- * now has built in overflow checking.
- */
- library SafeMath {
- /**
- * @dev Returns the addition of two unsigned integers, with an overflow flag.
- *
- * _Available since v3.4._
- */
- function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
- unchecked {
- uint256 c = a + b;
- if (c < a) return (false, 0);
- return (true, c);
- }
- }
- /**
- * @dev Returns the substraction of two unsigned integers, with an overflow flag.
- *
- * _Available since v3.4._
- */
- function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
- unchecked {
- if (b > a) return (false, 0);
- return (true, a - b);
- }
- }
- /**
- * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
- *
- * _Available since v3.4._
- */
- function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
- unchecked {
- // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
- // benefit is lost if 'b' is also tested.
- // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
- if (a == 0) return (true, 0);
- uint256 c = a * b;
- if (c / a != b) return (false, 0);
- return (true, c);
- }
- }
- /**
- * @dev Returns the division of two unsigned integers, with a division by zero flag.
- *
- * _Available since v3.4._
- */
- Tib74, [4/22/2022 6:56 PM]
- function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
- unchecked {
- if (b == 0) return (false, 0);
- return (true, a / b);
- }
- }
- /**
- * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
- *
- * _Available since v3.4._
- */
- function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
- unchecked {
- if (b == 0) return (false, 0);
- return (true, a % b);
- }
- }
- /**
- * @dev Returns the addition of two unsigned integers, reverting on
- * overflow.
- *
- * Counterpart to Solidity's + operator.
- *
- * Requirements:
- *
- * - Addition cannot overflow.
- */
- 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.
- */
- 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.
- */
- 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.
- */
- function div(uint256 a, uint256 b) internal pure returns (uint256) {
- 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.
- */
- function mod(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.
- */
- function sub(
- uint256 a,
- uint256 b,
- string memory errorMessage
- ) internal pure returns (uint256) {
- unchecked {
- require(b <= a, errorMessage);
- return a - b;
- }
- }
- /**
- * @dev Returns the integer division of two unsigned integers, reverting with custom message on
- * division by zero. The result is rounded towards zero.
- *
- * Counterpart to Solidity's / operator. Note: 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.
- */
- function div(
- uint256 a,
- uint256 b,
- string memory errorMessage
- ) internal pure returns (uint256) {
- unchecked {
- require(b > 0, errorMessage);
- return a / b;
- }
- }
- /**
- * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
- * reverting with custom message when dividing by zero.
- *
- Tib74, [4/22/2022 6:56 PM]
- * CAUTION: This function is deprecated because it requires allocating memory for the error
- * message unnecessarily. For custom revert reasons use {tryMod}.
- *
- * 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.
- */
- function mod(
- uint256 a,
- uint256 b,
- string memory errorMessage
- ) internal pure returns (uint256) {
- unchecked {
- require(b > 0, errorMessage);
- return a % b;
- }
- }
- }
- // Dependency file: @openzeppelin/contracts/proxy/Clones.sol
- // pragma solidity ^0.8.0;
- /**
- * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
- * deploying minimal proxy contracts, also known as "clones".
- *
- * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
- * > a minimal bytecode implementation that delegates all calls to a known, fixed address.
- *
- * The library includes functions to deploy a proxy using either create (traditional deployment) or create2
- * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
- * deterministic method.
- *
- * _Available since v3.4._
- */
- library Clones {
- /**
- * @dev Deploys and returns the address of a clone that mimics the behaviour of implementation.
- *
- * This function uses the create opcode, which should never revert.
- */
- function clone(address implementation) internal returns (address instance) {
- assembly {
- let ptr := mload(0x40)
- mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
- mstore(add(ptr, 0x14), shl(0x60, implementation))
- mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
- instance := create(0, ptr, 0x37)
- }
- require(instance != address(0), "ERC1167: create failed");
- }
- /**
- * @dev Deploys and returns the address of a clone that mimics the behaviour of implementation.
- *
- * This function uses the create2 opcode and a salt to deterministically deploy
- * the clone. Using the same implementation and salt multiple time will revert, since
- * the clones cannot be deployed twice at the same address.
- */
- function cloneDeterministic(address implementation, bytes32 salt) internal returns (address instance) {
- assembly {
- let ptr := mload(0x40)
- mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
- mstore(add(ptr, 0x14), shl(0x60, implementation))
- mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000)
- instance := create2(0, ptr, 0x37, salt)
- }
- require(instance != address(0), "ERC1167: create2 failed");
- }
- /**
- * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
- */
- function predictDeterministicAddress(
- address implementation,
- bytes32 salt,
- address deployer
- ) internal pure returns (address predicted) {
- assembly {
- let ptr := mload(0x40)
- mstore(ptr, 0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000)
- mstore(add(ptr, 0x14), shl(0x60, implementation))
- mstore(add(ptr, 0x28), 0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000)
- mstore(add(ptr, 0x38), shl(0x60, deployer))
- mstore(add(ptr, 0x4c), salt)
- mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
- predicted := keccak256(add(ptr, 0x37), 0x55)
- }
- }
- /**
- * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
- */
- function predictDeterministicAddress(address implementation, bytes32 salt)
- internal
- Tib74, [4/22/2022 6:56 PM]
- view
- returns (address predicted)
- {
- return predictDeterministicAddress(implementation, salt, address(this));
- }
- }
- // Dependency file: contracts/interfaces/IUniswapV2Factory.sol
- // pragma solidity >=0.5.0;
- interface IUniswapV2Factory {
- event PairCreated(
- address indexed token0,
- address indexed token1,
- address pair,
- uint256
- );
- function feeTo() external view returns (address);
- function feeToSetter() external view returns (address);
- function getPair(address tokenA, address tokenB)
- external
- view
- returns (address pair);
- function allPairs(uint256) external view returns (address pair);
- function allPairsLength() external view returns (uint256);
- function createPair(address tokenA, address tokenB)
- external
- returns (address pair);
- function setFeeTo(address) external;
- function setFeeToSetter(address) external;
- }
- // Dependency file: contracts/interfaces/IUniswapV2Router02.sol
- // pragma solidity >=0.6.2;
- interface IUniswapV2Router01 {
- function factory() external pure returns (address);
- function WETH() external pure returns (address);
- 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
- );
- function addLiquidityETH(
- address token,
- uint256 amountTokenDesired,
- uint256 amountTokenMin,
- uint256 amountETHMin,
- address to,
- uint256 deadline
- )
- external
- payable
- returns (
- uint256 amountToken,
- uint256 amountETH,
- uint256 liquidity
- );
- function removeLiquidity(
- address tokenA,
- address tokenB,
- uint256 liquidity,
- uint256 amountAMin,
- uint256 amountBMin,
- address to,
- uint256 deadline
- ) external returns (uint256 amountA, uint256 amountB);
- function removeLiquidityETH(
- address token,
- uint256 liquidity,
- uint256 amountTokenMin,
- uint256 amountETHMin,
- address to,
- uint256 deadline
- ) external returns (uint256 amountToken, uint256 amountETH);
- function removeLiquidityWithPermit(
- address tokenA,
- address tokenB,
- uint256 liquidity,
- uint256 amountAMin,
- uint256 amountBMin,
- address to,
- uint256 deadline,
- bool approveMax,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) external returns (uint256 amountA, uint256 amountB);
- function removeLiquidityETHWithPermit(
- address token,
- uint256 liquidity,
- uint256 amountTokenMin,
- uint256 amountETHMin,
- address to,
- uint256 deadline,
- bool approveMax,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) external returns (uint256 amountToken, uint256 amountETH);
- function swapExactTokensForTokens(
- uint256 amountIn,
- uint256 amountOutMin,
- address[] calldata path,
- address to,
- uint256 deadline
- ) external returns (uint256[] memory amounts);
- function swapTokensForExactTokens(
- uint256 amountOut,
- uint256 amountInMax,
- address[] calldata path,
- address to,
- uint256 deadline
- ) external returns (uint256[] memory amounts);
- function swapExactETHForTokens(
- uint256 amountOutMin,
- address[] calldata path,
- address to,
- uint256 deadline
- ) external payable returns (uint256[] memory amounts);
- function swapTokensForExactETH(
- uint256 amountOut,
- uint256 amountInMax,
- address[] calldata path,
- address to,
- uint256 deadline
- ) external returns (uint256[] memory amounts);
- function swapExactTokensForETH(
- Tib74, [4/22/2022 6:56 PM]
- uint256 amountIn,
- uint256 amountOutMin,
- address[] calldata path,
- address to,
- uint256 deadline
- ) external returns (uint256[] memory amounts);
- function swapETHForExactTokens(
- uint256 amountOut,
- address[] calldata path,
- address to,
- uint256 deadline
- ) external payable returns (uint256[] memory amounts);
- function quote(
- uint256 amountA,
- uint256 reserveA,
- uint256 reserveB
- ) external pure returns (uint256 amountB);
- function getAmountOut(
- uint256 amountIn,
- uint256 reserveIn,
- uint256 reserveOut
- ) external pure returns (uint256 amountOut);
- function getAmountIn(
- uint256 amountOut,
- uint256 reserveIn,
- uint256 reserveOut
- ) external pure returns (uint256 amountIn);
- function getAmountsOut(uint256 amountIn, address[] calldata path)
- external
- view
- returns (uint256[] memory amounts);
- function getAmountsIn(uint256 amountOut, address[] calldata path)
- external
- view
- returns (uint256[] memory amounts);
- }
- interface IUniswapV2Router02 is IUniswapV2Router01 {
- function removeLiquidityETHSupportingFeeOnTransferTokens(
- address token,
- uint256 liquidity,
- uint256 amountTokenMin,
- uint256 amountETHMin,
- address to,
- uint256 deadline
- ) external returns (uint256 amountETH);
- function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
- address token,
- uint256 liquidity,
- uint256 amountTokenMin,
- uint256 amountETHMin,
- address to,
- uint256 deadline,
- bool approveMax,
- uint8 v,
- bytes32 r,
- bytes32 s
- ) external returns (uint256 amountETH);
- function swapExactTokensForTokensSupportingFeeOnTransferTokens(
- uint256 amountIn,
- uint256 amountOutMin,
- address[] calldata path,
- address to,
- uint256 deadline
- ) external;
- function swapExactETHForTokensSupportingFeeOnTransferTokens(
- uint256 amountOutMin,
- address[] calldata path,
- address to,
- uint256 deadline
- ) external payable;
- function swapExactTokensForETHSupportingFeeOnTransferTokens(
- uint256 amountIn,
- uint256 amountOutMin,
- address[] calldata path,
- address to,
- uint256 deadline
- ) external;
- }
- // Dependency file: @openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol
- // pragma solidity ^0.8.0;
- /**
- * @dev Interface of the ERC20 standard as defined in the EIP.
- */
- interface IERC20Upgradeable {
- /**
- * @dev Returns the amount of tokens in existence.
- */
- function totalSupply() external view returns (uint256);
- /**
- * @dev Returns the amount of tokens owned by account.
- */
- function balanceOf(address account) external view returns (uint256);
- /**
- * @dev Moves amount tokens from the caller's account to recipient.
- *
- * Returns a boolean value indicating whether the operation succeeded.
- *
- * Emits a {Transfer} event.
- */
- 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}. This is
- * zero by default.
- *
- * This value changes when {approve} or {transferFrom} are called.
- */
- function allowance(address owner, address spender) external view returns (uint256);
- /**
- * @dev Sets amount as the allowance of spender over the caller's tokens.
- *
- * Returns a boolean value indicating whether the operation succeeded.
- *
- * IMPORTANT: Beware that changing an allowance with this method brings the risk
- * that someone may use both the old and the new allowance by unfortunate
- * transaction ordering. One possible solution to mitigate this race
- * condition is to first reduce the spender's allowance to 0 and set the
- Tib74, [4/22/2022 6:56 PM]
- * desired value afterwards:
- * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
- *
- * Emits an {Approval} event.
- */
- 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.
- *
- * Returns a boolean value indicating whether the operation succeeded.
- *
- * Emits a {Transfer} event.
- */
- function transferFrom(
- address sender,
- address recipient,
- uint256 amount
- ) external returns (bool);
- /**
- * @dev Emitted when value tokens are moved from one account (`from`) to
- * another (`to`).
- *
- * Note that value may be zero.
- */
- event Transfer(address indexed from, address indexed to, uint256 value);
- /**
- * @dev Emitted when the allowance of a spender for an owner is set by
- * a call to {approve}. value is the new allowance.
- */
- event Approval(address indexed owner, address indexed spender, uint256 value);
- }
- // Dependency file: @openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol
- // pragma solidity ^0.8.0;
- // import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
- /**
- * @dev Interface for the optional metadata functions from the ERC20 standard.
- *
- * _Available since v4.1._
- */
- interface IERC20MetadataUpgradeable is IERC20Upgradeable {
- /**
- * @dev Returns the name of the token.
- */
- function name() external view returns (string memory);
- /**
- * @dev Returns the symbol of the token.
- */
- function symbol() external view returns (string memory);
- /**
- * @dev Returns the decimals places of the token.
- */
- function decimals() external view returns (uint8);
- }
- // Dependency file: @openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
- // pragma solidity ^0.8.0;
- /**
- * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
- * behind a proxy. Since a proxied contract can't have a constructor, it's common to move constructor logic to an
- * external initializer function, usually called initialize. It then becomes necessary to protect this initializer
- * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
- *
- * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
- * possible by providing the encoded function call as the _data argument to {ERC1967Proxy-constructor}.
- *
- * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
- * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
- */
- abstract contract Initializable {
- /**
- * @dev Indicates that the contract has been initialized.
- */
- bool private _initialized;
- /**
- * @dev Indicates that the contract is in the process of being initialized.
- */
- bool private _initializing;
- /**
- * @dev Modifier to protect an initializer function from being invoked twice.
- */
- modifier initializer() {
- require(_initializing || !_initialized, "Initializable: contract is already initialized");
- bool isTopLevelCall = !_initializing;
- if (isTopLevelCall) {
- _initializing = true;
- _initialized = true;
- }
- _;
- if (isTopLevelCall) {
- _initializing = false;
- }
- }
- }
- // Dependency file: @openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol
- // pragma solidity ^0.8.0;
- // import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
- /**
- * @dev Provides information about the current execution context, including the
- * sender of the transaction and its data. While these are generally available
- * via msg.sender and msg.
- Tib74, [4/22/2022 6:56 PM]
- data, they should not be accessed in such a direct
- * manner, since when dealing with meta-transactions the account sending and
- * paying for execution may not be the actual sender (as far as an application
- * is concerned).
- *
- * This contract is only required for intermediate, library-like contracts.
- */
- abstract contract ContextUpgradeable is Initializable {
- function __Context_init() internal initializer {
- __Context_init_unchained();
- }
- function __Context_init_unchained() internal initializer {
- }
- function _msgSender() internal view virtual returns (address) {
- return msg.sender;
- }
- function _msgData() internal view virtual returns (bytes calldata) {
- return msg.data;
- }
- uint256[50] private __gap;
- }
- // Dependency file: @openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol
- // pragma solidity ^0.8.0;
- // import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol";
- // import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol";
- // import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
- // import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
- /**
- * @dev Implementation of the {IERC20} interface.
- *
- * This implementation is agnostic to the way tokens are created. This means
- * that a supply mechanism has to be added in a derived contract using {_mint}.
- * For a generic mechanism see {ERC20PresetMinterPauser}.
- *
- * TIP: For a detailed writeup see our guide
- * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
- * to implement supply mechanisms].
- *
- * We have followed general OpenZeppelin Contracts guidelines: functions revert
- * instead returning false on failure. This behavior is nonetheless
- * conventional and does not conflict with the expectations of ERC20
- * applications.
- *
- * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
- * This allows applications to reconstruct the allowance for all accounts just
- * by listening to said events. Other implementations of the EIP may not emit
- * these events, as it isn't required by the specification.
- *
- * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
- * functions have been added to mitigate the well-known issues around setting
- * allowances. See {IERC20-approve}.
- */
- contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable {
- mapping(address => uint256) private _balances;
- mapping(address => mapping(address => uint256)) private _allowances;
- uint256 private _totalSupply;
- string private _name;
- string private _symbol;
- /**
- * @dev Sets the values for {name} and {symbol}.
- *
- * The default value of {decimals} is 18. To select a different value for
- * {decimals} you should overload it.
- *
- * All two of these values are immutable: they can only be set once during
- * construction.
- */
- function __ERC20_init(string memory name_, string memory symbol_) internal initializer {
- __Context_init_unchained();
- __ERC20_init_unchained(name_, symbol_);
- }
- function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer {
- _name = name_;
- _symbol = symbol_;
- }
- /**
- * @dev Returns the name of the token.
- */
- function name() public view virtual override returns (string memory) {
- return _name;
- }
- /**
- * @dev Returns the symbol of the token, usually a shorter version of the
- * name.
- */
- function symbol() public view virtual override returns (string memory) {
- return _symbol;
- }
- /**
- * @dev Returns the number of decimals used to get its user representation.
- * For example, if decimals equals 2, a balance of 505 tokens should
- * be displayed to a user as 5.05 (`505 / 10 ** 2`).
- *
- * Tokens usually opt for a value of 18, imitating the relationship between
- * Ether and Wei.
- Tib74, [4/22/2022 6:56 PM]
- This is the value {ERC20} uses, unless this function is
- * overridden;
- *
- * NOTE: This information is only used for _display_ purposes: it in
- * no way affects any of the arithmetic of the contract, including
- * {IERC20-balanceOf} and {IERC20-transfer}.
- */
- function decimals() public view virtual override returns (uint8) {
- return 18;
- }
- /**
- * @dev See {IERC20-totalSupply}.
- */
- function totalSupply() public view virtual override returns (uint256) {
- return _totalSupply;
- }
- /**
- * @dev See {IERC20-balanceOf}.
- */
- function balanceOf(address account) public view virtual override returns (uint256) {
- return _balances[account];
- }
- /**
- * @dev See {IERC20-transfer}.
- *
- * Requirements:
- *
- * - recipient cannot be the zero address.
- * - the caller must have a balance of at least amount.
- */
- function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
- _transfer(_msgSender(), recipient, amount);
- return true;
- }
- /**
- * @dev See {IERC20-allowance}.
- */
- function allowance(address owner, address spender) public view virtual override returns (uint256) {
- return _allowances[owner][spender];
- }
- /**
- * @dev See {IERC20-approve}.
- *
- * Requirements:
- *
- * - spender cannot be the zero address.
- */
- function approve(address spender, uint256 amount) public virtual override returns (bool) {
- _approve(_msgSender(), spender, amount);
- return true;
- }
- /**
- * @dev See {IERC20-transferFrom}.
- *
- * Emits an {Approval} event indicating the updated allowance. This is not
- * required by the EIP. See the note at the beginning of {ERC20}.
- *
- * Requirements:
- *
- * - sender and recipient cannot be the zero address.
- * - sender must have a balance of at least amount.
- * - the caller must have allowance for ``sender``'s tokens of at least
- * amount.
- */
- function transferFrom(
- address sender,
- address recipient,
- uint256 amount
- ) public virtual override returns (bool) {
- _transfer(sender, recipient, amount);
- uint256 currentAllowance = _allowances[sender][_msgSender()];
- require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance");
- unchecked {
- _approve(sender, _msgSender(), currentAllowance - amount);
- }
- return true;
- }
- /**
- * @dev Atomically increases the allowance granted to spender by the caller.
- *
- * This is an alternative to {approve} that can be used as a mitigation for
- * problems described in {IERC20-approve}.
- *
- * Emits an {Approval} event indicating the updated allowance.
- *
- * Requirements:
- *
- * - spender cannot be the zero address.
- */
- function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
- _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue);
- return true;
- }
- /**
- * @dev Atomically decreases the allowance granted to spender by the caller.
- *
- * This is an alternative to {approve} that can be used as a mitigation for
- * problems described in {IERC20-approve}.
- *
- * Emits an {Approval} event indicating the updated allowance.
- *
- * Requirements:
- *
- * - spender cannot be the zero address.
- * - spender must have allowance for the caller of at least
- * subtractedValue.
- */
- function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
- uint256 currentAllowance = _allowances[_msgSender()][spender];
- require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
- unchecked {
- _approve(_msgSender(), spender, currentAllowance - subtractedValue);
- }
- return true;
- }
- /**
- Tib74, [4/22/2022 6:56 PM]
- * @dev Moves amount of tokens from sender to recipient.
- *
- * This internal function is equivalent to {transfer}, and can be used to
- * e.g. implement automatic token fees, slashing mechanisms, etc.
- *
- * Emits a {Transfer} event.
- *
- * Requirements:
- *
- * - sender cannot be the zero address.
- * - recipient cannot be the zero address.
- * - sender must have a balance of at least amount.
- */
- function _transfer(
- address sender,
- address recipient,
- uint256 amount
- ) internal virtual {
- require(sender != address(0), "ERC20: transfer from the zero address");
- require(recipient != address(0), "ERC20: transfer to the zero address");
- _beforeTokenTransfer(sender, recipient, amount);
- uint256 senderBalance = _balances[sender];
- require(senderBalance >= amount, "ERC20: transfer amount exceeds balance");
- unchecked {
- _balances[sender] = senderBalance - amount;
- }
- _balances[recipient] += amount;
- emit Transfer(sender, recipient, amount);
- _afterTokenTransfer(sender, recipient, amount);
- }
- /** @dev Creates amount tokens and assigns them to account, increasing
- * the total supply.
- *
- * Emits a {Transfer} event with from set to the zero address.
- *
- * Requirements:
- *
- * - account cannot be the zero address.
- */
- function _mint(address account, uint256 amount) internal virtual {
- require(account != address(0), "ERC20: mint to the zero address");
- _beforeTokenTransfer(address(0), account, amount);
- _totalSupply += amount;
- _balances[account] += amount;
- emit Transfer(address(0), account, amount);
- _afterTokenTransfer(address(0), account, amount);
- }
- /**
- * @dev Destroys amount tokens from account, reducing the
- * total supply.
- *
- * Emits a {Transfer} event with to set to the zero address.
- *
- * Requirements:
- *
- * - account cannot be the zero address.
- * - account must have at least amount tokens.
- */
- function _burn(address account, uint256 amount) internal virtual {
- require(account != address(0), "ERC20: burn from the zero address");
- _beforeTokenTransfer(account, address(0), amount);
- uint256 accountBalance = _balances[account];
- require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
- unchecked {
- _balances[account] = accountBalance - amount;
- }
- _totalSupply -= amount;
- emit Transfer(account, address(0), amount);
- _afterTokenTransfer(account, address(0), amount);
- }
- /**
- * @dev Sets amount as the allowance of spender over the owner s tokens.
- *
- * This internal function is equivalent to approve, and can be used to
- * e.g. set automatic allowances for certain subsystems, etc.
- *
- * Emits an {Approval} event.
- *
- * Requirements:
- *
- * - owner cannot be the zero address.
- * - spender cannot be the zero address.
- */
- function _approve(
- address owner,
- address spender,
- uint256 amount
- ) internal virtual {
- 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);
- }
- /**
- * @dev Hook that is called before any transfer of tokens. This includes
- * minting and burning.
- *
- * Calling conditions:
- *
- * - when from and to are both non-zero, amount of ``from``'s tokens
- * will be transferred to to.
- * - when from is zero, amount tokens will be minted for to.
- * - when to is zero, amount of ``from``'s tokens will be burned.
- * - from and to are never both zero.
- *
- * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
- */
- function _beforeTokenTransfer(
- Tib74, [4/22/2022 6:56 PM]
- address from,
- address to,
- uint256 amount
- ) internal virtual {}
- /**
- * @dev Hook that is called after any transfer of tokens. This includes
- * minting and burning.
- *
- * Calling conditions:
- *
- * - when from and to are both non-zero, amount of ``from``'s tokens
- * has been transferred to to.
- * - when from is zero, amount tokens have been minted for to.
- * - when to is zero, amount of ``from``'s tokens have been burned.
- * - from and to are never both zero.
- *
- * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
- */
- function _afterTokenTransfer(
- address from,
- address to,
- uint256 amount
- ) internal virtual {}
- uint256[45] private __gap;
- }
- // Dependency file: @openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol
- // pragma solidity ^0.8.0;
- // import "@openzeppelin/contracts-upgradeable/utils/ContextUpgradeable.sol";
- // import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
- /**
- * @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 module is used through inheritance. It will make available the modifier
- * onlyOwner, which can be applied to your functions to restrict their use to
- * the owner.
- */
- abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
- address private _owner;
- event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
- /**
- * @dev Initializes the contract setting the deployer as the initial owner.
- */
- function __Ownable_init() internal initializer {
- __Context_init_unchained();
- __Ownable_init_unchained();
- }
- function __Ownable_init_unchained() internal initializer {
- _setOwner(_msgSender());
- }
- /**
- * @dev Returns the address of the current owner.
- */
- function owner() public view virtual returns (address) {
- return _owner;
- }
- /**
- * @dev Throws if called by any account other than the owner.
- */
- 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.
- */
- function renounceOwnership() public virtual onlyOwner {
- _setOwner(address(0));
- }
- /**
- * @dev Transfers ownership of the contract to a new account (`newOwner`).
- * Can only be called by the current owner.
- */
- function transferOwnership(address newOwner) public virtual onlyOwner {
- require(newOwner != address(0), "Ownable: new owner is the zero address");
- _setOwner(newOwner);
- }
- function _setOwner(address newOwner) private {
- address oldOwner = _owner;
- _owner = newOwner;
- emit OwnershipTransferred(oldOwner, newOwner);
- }
- uint256[49] private __gap;
- }
- // Dependency file: contracts/interfaces/IUniswapV2Pair.sol
- // pragma solidity >=0.5.0;
- interface IUniswapV2Pair {
- event Approval(address indexed owner, address indexed spender, uint value);
- event Transfer(address indexed from, address indexed to, uint value);
- function name() external pure returns (string memory);
- function symbol() external pure returns (string memory);
- function decimals() external pure returns (uint8);
- function totalSupply() external view returns (uint);
- function balanceOf(address owner) external view returns (uint);
- Tib74, [4/22/2022 6:56 PM]
- function allowance(address owner, address spender) external view returns (uint);
- function approve(address spender, uint value) external returns (bool);
- function transfer(address to, uint value) external returns (bool);
- function transferFrom(address from, address to, uint value) external returns (bool);
- function DOMAIN_SEPARATOR() external view returns (bytes32);
- function PERMIT_TYPEHASH() external pure returns (bytes32);
- function nonces(address owner) external view returns (uint);
- function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;
- event Mint(address indexed sender, uint amount0, uint amount1);
- event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
- event Swap(
- address indexed sender,
- uint amount0In,
- uint amount1In,
- uint amount0Out,
- uint amount1Out,
- address indexed to
- );
- event Sync(uint112 reserve0, uint112 reserve1);
- function MINIMUM_LIQUIDITY() external pure returns (uint);
- function factory() external view returns (address);
- function token0() external view returns (address);
- function token1() external view returns (address);
- function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
- function price0CumulativeLast() external view returns (uint);
- function price1CumulativeLast() external view returns (uint);
- function kLast() external view returns (uint);
- function mint(address to) external returns (uint liquidity);
- function burn(address to) external returns (uint amount0, uint amount1);
- function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
- function skim(address to) external;
- function sync() external;
- function initialize(address, address) external;
- }
- // Dependency file: contracts/libs/SafeMathInt.sol
- // pragma solidity =0.8.4;
- /**
- * @title SafeMathInt
- * @dev Math operations for int256 with overflow safety checks.
- */
- library SafeMathInt {
- int256 private constant MIN_INT256 = int256(1) << 255;
- int256 private constant MAX_INT256 = ~(int256(1) << 255);
- /**
- * @dev Multiplies two int256 variables and fails on overflow.
- */
- function mul(int256 a, int256 b) internal pure returns (int256) {
- int256 c = a * b;
- // Detect overflow when multiplying MIN_INT256 with -1
- require(c != MIN_INT256 || (a & MIN_INT256) != (b & MIN_INT256));
- require((b == 0) || (c / b == a));
- return c;
- }
- /**
- * @dev Division of two int256 variables and fails on overflow.
- */
- function div(int256 a, int256 b) internal pure returns (int256) {
- // Prevent overflow when dividing MIN_INT256 by -1
- require(b != -1 || a != MIN_INT256);
- // Solidity already throws when dividing by 0.
- return a / b;
- }
- /**
- * @dev Subtracts two int256 variables and fails on overflow.
- */
- function sub(int256 a, int256 b) internal pure returns (int256) {
- int256 c = a - b;
- require((b >= 0 && c <= a) || (b < 0 && c > a));
- return c;
- }
- /**
- * @dev Adds two int256 variables and fails on overflow.
- */
- function add(int256 a, int256 b) internal pure returns (int256) {
- int256 c = a + b;
- require((b >= 0 && c >= a) || (b < 0 && c < a));
- return c;
- }
- /**
- * @dev Converts to absolute value, and fails on overflow.
- */
- function abs(int256 a) internal pure returns (int256) {
- require(a != MIN_INT256);
- return a < 0 ? -a : a;
- }
- function toUint256Safe(int256 a) internal pure returns (uint256) {
- require(a >= 0);
- return uint256(a);
- }
- }
- // Dependency file: contracts/libs/SafeMathUint.sol
- // pragma solidity =0.8.4;
- /**
- * @title SafeMathUint
- * @dev Math operations with safety checks that revert on error
- */
- library SafeMathUint {
- function toInt256Safe(uint256 a) internal pure returns (int256) {
- Tib74, [4/22/2022 6:56 PM]
- int256 b = int256(a);
- require(b >= 0);
- return b;
- }
- }
- // Dependency file: contracts/baby/IterableMapping.sol
- // pragma solidity =0.8.4;
- library IterableMapping {
- // Iterable mapping from address to uint;
- struct Map {
- address[] keys;
- mapping(address => uint256) values;
- mapping(address => uint256) indexOf;
- mapping(address => bool) inserted;
- }
- function get(Map storage map, address key) public view returns (uint256) {
- return map.values[key];
- }
- function getIndexOfKey(Map storage map, address key)
- public
- view
- returns (int256)
- {
- if (!map.inserted[key]) {
- return -1;
- }
- return int256(map.indexOf[key]);
- }
- function getKeyAtIndex(Map storage map, uint256 index)
- public
- view
- returns (address)
- {
- return map.keys[index];
- }
- function size(Map storage map) public view returns (uint256) {
- return map.keys.length;
- }
- function set(
- Map storage map,
- address key,
- uint256 val
- ) public {
- if (map.inserted[key]) {
- map.values[key] = val;
- } else {
- map.inserted[key] = true;
- map.values[key] = val;
- map.indexOf[key] = map.keys.length;
- map.keys.push(key);
- }
- }
- function remove(Map storage map, address key) public {
- if (!map.inserted[key]) {
- return;
- }
- delete map.inserted[key];
- delete map.values[key];
- uint256 index = map.indexOf[key];
- uint256 lastIndex = map.keys.length - 1;
- address lastKey = map.keys[lastIndex];
- map.indexOf[lastKey] = index;
- delete map.indexOf[key];
- map.keys[index] = lastKey;
- map.keys.pop();
- }
- }
- // Dependency file: contracts/baby/BabyTokenDividendTracker.sol
- // pragma solidity =0.8.4;
- // import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
- // import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
- // import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
- // import "@openzeppelin/contracts/access/Ownable.sol";
- // import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
- // import "@openzeppelin/contracts/utils/math/SafeMath.sol";
- // import "contracts/interfaces/IUniswapV2Factory.sol";
- // import "contracts/interfaces/IUniswapV2Router02.sol";
- // import "contracts/interfaces/IUniswapV2Pair.sol";
- // import "contracts/libs/SafeMathInt.sol";
- // import "contracts/libs/SafeMathUint.sol";
- // import "contracts/baby/IterableMapping.sol";
- /// @title Dividend-Paying Token Interface
- /// @author Roger Wu (https://github.com/roger-wu)
- /// @dev An interface for a dividend-paying token contract.
- interface DividendPayingTokenInterface {
- /// @notice View the amount of dividend in wei that an address can withdraw.
- /// @param _owner The address of a token holder.
- /// @return The amount of dividend in wei that _owner can withdraw.
- function dividendOf(address _owner) external view returns (uint256);
- /// @notice Withdraws the ether distributed to the sender.
- /// @dev SHOULD transfer dividendOf(msg.sender) wei to msg.sender, and dividendOf(msg.sender) SHOULD be 0 after the transfer.
- /// MUST emit a DividendWithdrawn event if the amount of ether transferred is greater than 0.
- function withdrawDividend() external;
- /// @dev This event MUST emit when ether is distributed to token holders.
- /// @param from The address which sends ether to this contract.
- /// @param weiAmount The amount of distributed ether in wei.
- event DividendsDistributed(address indexed from, uint256 weiAmount);
- /// @dev This event MUST emit when an address withdraws their dividend.
- /// @param to The address which withdraws ether from this contract.
- /// @param weiAmount The amount of withdrawn ether in wei.
- event DividendWithdrawn(address indexed to, uint256 weiAmount);
- }
- /// @title Dividend-Paying Token Optional Interface
- Tib74, [4/22/2022 6:56 PM]
- /// @author Roger Wu (https://github.com/roger-wu)
- /// @dev OPTIONAL functions for a dividend-paying token contract.
- interface DividendPayingTokenOptionalInterface {
- /// @notice View the amount of dividend in wei that an address can withdraw.
- /// @param _owner The address of a token holder.
- /// @return The amount of dividend in wei that _owner can withdraw.
- function withdrawableDividendOf(address _owner)
- external
- view
- returns (uint256);
- /// @notice View the amount of dividend in wei that an address has withdrawn.
- /// @param _owner The address of a token holder.
- /// @return The amount of dividend in wei that _owner has withdrawn.
- function withdrawnDividendOf(address _owner)
- external
- view
- returns (uint256);
- /// @notice View the amount of dividend in wei that an address has earned in total.
- /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)
- /// @param _owner The address of a token holder.
- /// @return The amount of dividend in wei that _owner has earned in total.
- function accumulativeDividendOf(address _owner)
- external
- view
- returns (uint256);
- }
- /// @title Dividend-Paying Token
- /// @author Roger Wu (https://github.com/roger-wu)
- /// @dev A mintable ERC20 token that allows anyone to pay and distribute ether
- /// to token holders as dividends and allows token holders to withdraw their dividends.
- /// Reference: the source code of PoWH3D: https://etherscan.io/address/0xB3775fB83F7D12A36E0475aBdD1FCA35c091efBe#code
- contract DividendPayingToken is
- ERC20Upgradeable,
- OwnableUpgradeable,
- DividendPayingTokenInterface,
- DividendPayingTokenOptionalInterface
- {
- using SafeMath for uint256;
- using SafeMathUint for uint256;
- using SafeMathInt for int256;
- address public rewardToken;
- // With magnitude, we can properly distribute dividends even if the amount of received ether is small.
- // For more discussion about choosing the value of magnitude,
- // see https://github.com/ethereum/EIPs/issues/1726#issuecomment-472352728
- uint256 internal constant magnitude = 2**128;
- uint256 internal magnifiedDividendPerShare;
- // About dividendCorrection:
- // If the token balance of a _user is never changed, the dividend of _user can be computed with:
- // dividendOf(_user) = dividendPerShare * balanceOf(_user).
- // When balanceOf(_user) is changed (via minting/burning/transferring tokens),
- // dividendOf(_user) should not be changed,
- // but the computed value of dividendPerShare * balanceOf(_user) is changed.
- // To keep the dividendOf(_user) unchanged, we add a correction term:
- // dividendOf(_user) = dividendPerShare * balanceOf(_user) + dividendCorrectionOf(_user),
- // where dividendCorrectionOf(_user) is updated whenever balanceOf(_user) is changed:
- // dividendCorrectionOf(_user) = dividendPerShare * (old balanceOf(_user)) - (new balanceOf(_user)).
- // So now dividendOf(_user) returns the same value before and after balanceOf(_user) is changed.
- mapping(address => int256) internal magnifiedDividendCorrections;
- mapping(address => uint256) internal withdrawnDividends;
- uint256 public totalDividendsDistributed;
- function __DividendPayingToken_init(
- address _rewardToken,
- string memory _name,
- string memory _symbol
- ) internal initializer {
- __Ownable_init();
- __ERC20_init(_name, _symbol);
- rewardToken = _rewardToken;
- }
- function distributeCAKEDividends(uint256 amount) public onlyOwner {
- require(totalSupply() > 0);
- if (amount > 0) {
- magnifiedDividendPerShare = magnifiedDividendPerShare.add(
- (amount).mul(magnitude) / totalSupply()
- );
- emit DividendsDistributed(msg.sender, amount);
- totalDividendsDistributed = totalDividendsDistributed.add(amount);
- }
- }
- /// @notice Withdraws the ether distributed to the sender.
- Tib74, [4/22/2022 6:56 PM]
- /// @dev It emits a DividendWithdrawn event if the amount of withdrawn ether is greater than 0.
- function withdrawDividend() public virtual override {
- _withdrawDividendOfUser(payable(msg.sender));
- }
- /// @notice Withdraws the ether distributed to the sender.
- /// @dev It emits a DividendWithdrawn event if the amount of withdrawn ether is greater than 0.
- function _withdrawDividendOfUser(address payable user)
- internal
- returns (uint256)
- {
- uint256 _withdrawableDividend = withdrawableDividendOf(user);
- if (_withdrawableDividend > 0) {
- withdrawnDividends[user] = withdrawnDividends[user].add(
- _withdrawableDividend
- );
- emit DividendWithdrawn(user, _withdrawableDividend);
- bool success = IERC20(rewardToken).transfer(
- user,
- _withdrawableDividend
- );
- if (!success) {
- withdrawnDividends[user] = withdrawnDividends[user].sub(
- _withdrawableDividend
- );
- return 0;
- }
- return _withdrawableDividend;
- }
- return 0;
- }
- /// @notice View the amount of dividend in wei that an address can withdraw.
- /// @param _owner The address of a token holder.
- /// @return The amount of dividend in wei that _owner can withdraw.
- function dividendOf(address _owner) public view override returns (uint256) {
- return withdrawableDividendOf(_owner);
- }
- /// @notice View the amount of dividend in wei that an address can withdraw.
- /// @param _owner The address of a token holder.
- /// @return The amount of dividend in wei that _owner can withdraw.
- function withdrawableDividendOf(address _owner)
- public
- view
- override
- returns (uint256)
- {
- return accumulativeDividendOf(_owner).sub(withdrawnDividends[_owner]);
- }
- /// @notice View the amount of dividend in wei that an address has withdrawn.
- /// @param _owner The address of a token holder.
- /// @return The amount of dividend in wei that _owner has withdrawn.
- function withdrawnDividendOf(address _owner)
- public
- view
- override
- returns (uint256)
- {
- return withdrawnDividends[_owner];
- }
- /// @notice View the amount of dividend in wei that an address has earned in total.
- /// @dev accumulativeDividendOf(_owner) = withdrawableDividendOf(_owner) + withdrawnDividendOf(_owner)
- /// = (magnifiedDividendPerShare * balanceOf(_owner) + magnifiedDividendCorrections[_owner]) / magnitude
- /// @param _owner The address of a token holder.
- /// @return The amount of dividend in wei that _owner has earned in total.
- function accumulativeDividendOf(address _owner)
- public
- view
- override
- returns (uint256)
- {
- return
- magnifiedDividendPerShare
- .mul(balanceOf(_owner))
- .toInt256Safe()
- .add(magnifiedDividendCorrections[_owner])
- .toUint256Safe() / magnitude;
- }
- /// @dev Internal function that transfer tokens from one address to another.
- /// Update magnifiedDividendCorrections to keep dividends unchanged.
- /// @param from The address to transfer from.
- /// @param to The address to transfer to.
- /// @param value The amount to be transferred.
- function _transfer(
- address from,
- address to,
- uint256 value
- ) internal virtual override {
- require(false);
- int256 _magCorrection = magnifiedDividendPerShare
- .mul(value)
- .toInt256Safe();
- magnifiedDividendCorrections[from] = magnifiedDividendCorrections[from]
- .add(_magCorrection);
- magnifiedDividendCorrections[to] = magnifiedDividendCorrections[to].sub(
- _magCorrection
- );
- }
- /// @dev Internal function that mints tokens to an account.
- /// Update magnifiedDividendCorrections to keep dividends unchanged.
- Tib74, [4/22/2022 6:56 PM]
- /// @param account The account that will receive the created tokens.
- /// @param value The amount that will be created.
- function _mint(address account, uint256 value) internal override {
- super._mint(account, value);
- magnifiedDividendCorrections[account] = magnifiedDividendCorrections[
- account
- ].sub((magnifiedDividendPerShare.mul(value)).toInt256Safe());
- }
- /// @dev Internal function that burns an amount of the token of a given account.
- /// Update magnifiedDividendCorrections to keep dividends unchanged.
- /// @param account The account whose tokens will be burnt.
- /// @param value The amount that will be burnt.
- function _burn(address account, uint256 value) internal override {
- super._burn(account, value);
- magnifiedDividendCorrections[account] = magnifiedDividendCorrections[
- account
- ].add((magnifiedDividendPerShare.mul(value)).toInt256Safe());
- }
- function _setBalance(address account, uint256 newBalance) internal {
- uint256 currentBalance = balanceOf(account);
- if (newBalance > currentBalance) {
- uint256 mintAmount = newBalance.sub(currentBalance);
- _mint(account, mintAmount);
- } else if (newBalance < currentBalance) {
- uint256 burnAmount = currentBalance.sub(newBalance);
- _burn(account, burnAmount);
- }
- }
- }
- contract BABYTOKENDividendTracker is OwnableUpgradeable, DividendPayingToken {
- using SafeMath for uint256;
- using SafeMathInt for int256;
- using IterableMapping for IterableMapping.Map;
- IterableMapping.Map private tokenHoldersMap;
- uint256 public lastProcessedIndex;
- mapping(address => bool) public excludedFromDividends;
- mapping(address => uint256) public lastClaimTimes;
- uint256 public claimWait;
- uint256 public minimumTokenBalanceForDividends;
- event ExcludeFromDividends(address indexed account);
- event ClaimWaitUpdated(uint256 indexed newValue, uint256 indexed oldValue);
- event Claim(
- address indexed account,
- uint256 amount,
- bool indexed automatic
- );
- function initialize(
- address rewardToken_,
- uint256 minimumTokenBalanceForDividends_
- ) external initializer {
- DividendPayingToken.__DividendPayingToken_init(
- rewardToken_,
- "DIVIDEND_TRACKER",
- "DIVIDEND_TRACKER"
- );
- claimWait = 3600;
- minimumTokenBalanceForDividends = minimumTokenBalanceForDividends_;
- }
- function _transfer(
- address,
- address,
- uint256
- ) internal pure override {
- require(false, "Dividend_Tracker: No transfers allowed");
- }
- function withdrawDividend() public pure override {
- require(
- false,
- "Dividend_Tracker: withdrawDividend disabled. Use the 'claim' function on the main BABYTOKEN contract."
- );
- }
- function excludeFromDividends(address account) external onlyOwner {
- require(!excludedFromDividends[account]);
- excludedFromDividends[account] = true;
- _setBalance(account, 0);
- tokenHoldersMap.remove(account);
- emit ExcludeFromDividends(account);
- }
- function isExcludedFromDividends(address account)
- public
- view
- returns (bool)
- {
- return excludedFromDividends[account];
- }
- function updateClaimWait(uint256 newClaimWait) external onlyOwner {
- require(
- newClaimWait >= 3600 && newClaimWait <= 86400,
- "Dividend_Tracker: claimWait must be updated to between 1 and 24 hours"
- );
- require(
- newClaimWait != claimWait,
- "Dividend_Tracker: Cannot update claimWait to same value"
- );
- emit ClaimWaitUpdated(newClaimWait, claimWait);
- claimWait = newClaimWait;
- }
- function updateMinimumTokenBalanceForDividends(uint256 amount)
- external
- onlyOwner
- {
- minimumTokenBalanceForDividends = amount;
- }
- Tib74, [4/22/2022 6:56 PM]
- function getLastProcessedIndex() external view returns (uint256) {
- return lastProcessedIndex;
- }
- function getNumberOfTokenHolders() external view returns (uint256) {
- return tokenHoldersMap.keys.length;
- }
- function getAccount(address _account)
- public
- view
- returns (
- address account,
- int256 index,
- int256 iterationsUntilProcessed,
- uint256 withdrawableDividends,
- uint256 totalDividends,
- uint256 lastClaimTime,
- uint256 nextClaimTime,
- uint256 secondsUntilAutoClaimAvailable
- )
- {
- account = _account;
- index = tokenHoldersMap.getIndexOfKey(account);
- iterationsUntilProcessed = -1;
- if (index >= 0) {
- if (uint256(index) > lastProcessedIndex) {
- iterationsUntilProcessed = index.sub(
- int256(lastProcessedIndex)
- );
- } else {
- uint256 processesUntilEndOfArray = tokenHoldersMap.keys.length >
- lastProcessedIndex
- ? tokenHoldersMap.keys.length.sub(lastProcessedIndex)
- : 0;
- iterationsUntilProcessed = index.add(
- int256(processesUntilEndOfArray)
- );
- }
- }
- withdrawableDividends = withdrawableDividendOf(account);
- totalDividends = accumulativeDividendOf(account);
- lastClaimTime = lastClaimTimes[account];
- nextClaimTime = lastClaimTime > 0 ? lastClaimTime.add(claimWait) : 0;
- secondsUntilAutoClaimAvailable = nextClaimTime > block.timestamp
- ? nextClaimTime.sub(block.timestamp)
- : 0;
- }
- function getAccountAtIndex(uint256 index)
- public
- view
- returns (
- address,
- int256,
- int256,
- uint256,
- uint256,
- uint256,
- uint256,
- uint256
- )
- {
- if (index >= tokenHoldersMap.size()) {
- return (address(0), -1, -1, 0, 0, 0, 0, 0);
- }
- address account = tokenHoldersMap.getKeyAtIndex(index);
- return getAccount(account);
- }
- function canAutoClaim(uint256 lastClaimTime) private view returns (bool) {
- if (lastClaimTime > block.timestamp) {
- return false;
- }
- return block.timestamp.sub(lastClaimTime) >= claimWait;
- }
- function setBalance(address payable account, uint256 newBalance)
- external
- onlyOwner
- {
- if (excludedFromDividends[account]) {
- return;
- }
- if (newBalance >= minimumTokenBalanceForDividends) {
- _setBalance(account, newBalance);
- tokenHoldersMap.set(account, newBalance);
- } else {
- _setBalance(account, 0);
- tokenHoldersMap.remove(account);
- }
- processAccount(account, true);
- }
- function process(uint256 gas)
- public
- returns (
- uint256,
- uint256,
- uint256
- )
- {
- uint256 numberOfTokenHolders = tokenHoldersMap.keys.length;
- if (numberOfTokenHolders == 0) {
- return (0, 0, lastProcessedIndex);
- }
- uint256 _lastProcessedIndex = lastProcessedIndex;
- uint256 gasUsed = 0;
- uint256 gasLeft = gasleft();
- uint256 iterations = 0;
- uint256 claims = 0;
- while (gasUsed < gas && iterations < numberOfTokenHolders) {
- _lastProcessedIndex++;
- if (_lastProcessedIndex >= tokenHoldersMap.keys.length) {
- _lastProcessedIndex = 0;
- }
- address account = tokenHoldersMap.keys[_lastProcessedIndex];
- if (canAutoClaim(lastClaimTimes[account])) {
- if (processAccount(payable(account), true)) {
- claims++;
- }
- }
- iterations++;
- uint256 newGasLeft = gasleft();
- if (gasLeft > newGasLeft) {
- gasUsed = gasUsed.add(gasLeft.sub(newGasLeft));
- }
- gasLeft = newGasLeft;
- }
- lastProcessedIndex = _lastProcessedIndex;
- return (iterations, claims, lastProcessedIndex);
- }
- function processAccount(address payable account, bool automatic)
- public
- onlyOwner
- returns (bool)
- {
- uint256 amount = _withdrawDividendOfUser(account);
- if (amount > 0) {
- lastClaimTimes[account] = block.timestamp;
- emit Claim(account, amount, automatic);
- return true;
- }
- return false;
- }
- }
- // Dependency file: contracts/BaseToken.sol
- // pragma solidity =0.8.4;
- enum TokenType {
- standard,
- antiBotStandard,
- liquidityGenerator,
- antiBotLiquidityGenerator,
- baby,
- antiBotBaby,
- buybackBaby,
- antiBotBuybackBaby
- }
- abstract contract BaseToken {
- event TokenCreated(
- address indexed owner,
- address indexed token,
- TokenType tokenType,
- uint256 version
- );
- }
- // Root file: contracts/baby/BabyToken.sol
- pragma solidity =0.8.4;
- // import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
- // import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
- // import "@openzeppelin/contracts/access/Ownable.sol";
- // import "@openzeppelin/contracts/utils/math/SafeMath.sol";
- // import "@openzeppelin/contracts/proxy/Clones.sol";
- // import "contracts/interfaces/IUniswapV2Factory.sol";
- // import "contracts/interfaces/IUniswapV2Router02.sol";
- // import "contracts/baby/BabyTokenDividendTracker.sol";
- // import "contracts/BaseToken.sol";
- contract BABYTOKEN is ERC20, Ownable, BaseToken {
- using SafeMath for uint256;
- uint256 public constant VERSION = 1;
- IUniswapV2Router02 public uniswapV2Router;
- address public uniswapV2Pair;
- bool private swapping;
- BABYTOKENDividendTracker public dividendTracker;
- address public rewardToken;
- uint256 public swapTokensAtAmount;
- uint256 public tokenRewardsFee;
- uint256 public liquidityFee;
- uint256 public marketingFee;
- uint256 public totalFees;
- address public _marketingWalletAddress;
- uint256 public gasForProcessing;
- // exlcude from fees and max transaction amount
- mapping(address => bool) private _isExcludedFromFees;
- // store addresses that a automatic market maker pairs. Any transfer *to* these addresses
- // could be subject to a maximum transfer amount
- mapping(address => bool) public automatedMarketMakerPairs;
- event UpdateDividendTracker(
- address indexed newAddress,
- address indexed oldAddress
- );
- event UpdateUniswapV2Router(
- address indexed newAddress,
- address indexed oldAddress
- );
- event ExcludeFromFees(address indexed account, bool isExcluded);
- event ExcludeMultipleAccountsFromFees(address[] accounts, bool isExcluded);
- event SetAutomatedMarketMakerPair(address indexed pair, bool indexed value);
- event LiquidityWalletUpdated(
- address indexed newLiquidityWallet,
- address indexed oldLiquidityWallet
- );
- event GasForProcessingUpdated(
- uint256 indexed newValue,
- uint256 indexed oldValue
- );
- event SwapAndLiquify(
- uint256 tokensSwapped,
- uint256 ethReceived,
- uint256 tokensIntoLiqudity
- );
- event SendDividends(uint256 tokensSwapped, uint256 amount);
- event ProcessedDividendTracker(
- uint256 iterations,
- uint256 claims,
- uint256 lastProcessedIndex,
- bool indexed automatic,
- uint256 gas,
- address indexed processor
- );
- constructor(
- string memory name_,
- string memory symbol_,
- uint256 totalSupply_,
- address[4] memory addrs, // reward, router, marketing wallet, dividendTracker
- uint256[3] memory feeSettings, // rewards, liquidity, marketing
- uint256 minimumTokenBalanceForDividends_,
- address serviceFeeReceiver_,
- uint256 serviceFee_
- ) payable ERC20(name_, symbol_) {
- rewardToken = addrs[0];
- Tib74, [4/22/2022 7:01 PM]
- _marketingWalletAddress = addrs[2];
- require(
- msg.sender != _marketingWalletAddress,
- "Owner and marketing wallet cannot be the same"
- );
- tokenRewardsFee = feeSettings[0];
- liquidityFee = feeSettings[1];
- marketingFee = feeSettings[2];
- totalFees = tokenRewardsFee.add(liquidityFee).add(marketingFee);
- require(totalFees <= 25, "Total fee is over 25%");
- swapTokensAtAmount = totalSupply_.mul(2).div(10**6); // 0.002%
- // use by default 300,000 gas to process auto-claiming dividends
- gasForProcessing = 300000;
- dividendTracker = BABYTOKENDividendTracker(
- payable(Clones.clone(addrs[3]))
- );
- dividendTracker.initialize(
- rewardToken,
- minimumTokenBalanceForDividends_
- );
- IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(addrs[1]);
- // Create a uniswap pair for this new token
- address _uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory())
- .createPair(address(this), _uniswapV2Router.WETH());
- uniswapV2Router = _uniswapV2Router;
- uniswapV2Pair = _uniswapV2Pair;
- _setAutomatedMarketMakerPair(_uniswapV2Pair, true);
- // exclude from receiving dividends
- dividendTracker.excludeFromDividends(address(dividendTracker));
- dividendTracker.excludeFromDividends(address(this));
- dividendTracker.excludeFromDividends(owner());
- dividendTracker.excludeFromDividends(address(0xdead));
- dividendTracker.excludeFromDividends(address(_uniswapV2Router));
- // exclude from paying fees or having max transaction amount
- excludeFromFees(owner(), true);
- excludeFromFees(_marketingWalletAddress, true);
- excludeFromFees(address(this), true);
- /*
- _mint is an internal function in ERC20.sol that is only called here,
- and CANNOT be called ever again
- */
- _mint(owner(), totalSupply_);
- emit TokenCreated(owner(), address(this), TokenType.baby, VERSION);
- payable(serviceFeeReceiver_).transfer(serviceFee_);
- }
- receive() external payable {}
- function setSwapTokensAtAmount(uint256 amount) external onlyOwner {
- swapTokensAtAmount = amount;
- }
- function updateDividendTracker(address newAddress) public onlyOwner {
- require(
- newAddress != address(dividendTracker),
- "BABYTOKEN: The dividend tracker already has that address"
- );
- BABYTOKENDividendTracker newDividendTracker = BABYTOKENDividendTracker(
- payable(newAddress)
- );
- require(
- newDividendTracker.owner() == address(this),
- "BABYTOKEN: The new dividend tracker must be owned by the BABYTOKEN token contract"
- );
- newDividendTracker.excludeFromDividends(address(newDividendTracker));
- newDividendTracker.excludeFromDividends(address(this));
- newDividendTracker.excludeFromDividends(owner());
- newDividendTracker.excludeFromDividends(address(uniswapV2Router));
- emit UpdateDividendTracker(newAddress, address(dividendTracker));
- dividendTracker = newDividendTracker;
- }
- function updateUniswapV2Router(address newAddress) public onlyOwner {
- require(
- newAddress != address(uniswapV2Router),
- "BABYTOKEN: The router already has that address"
- );
- emit UpdateUniswapV2Router(newAddress, address(uniswapV2Router));
- uniswapV2Router = IUniswapV2Router02(newAddress);
- address _uniswapV2Pair = IUniswapV2Factory(uniswapV2Router.factory())
- .createPair(address(this), uniswapV2Router.WETH());
- uniswapV2Pair = _uniswapV2Pair;
- }
- function excludeFromFees(address account, bool excluded) public onlyOwner {
- require(
- _isExcludedFromFees[account] != excluded,
- "BABYTOKEN: Account is already the value of 'excluded'"
- );
- _isExcludedFromFees[account] = excluded;
- Tib74, [4/22/2022 7:01 PM]
- emit ExcludeFromFees(account, excluded);
- }
- function excludeMultipleAccountsFromFees(
- address[] calldata accounts,
- bool excluded
- ) public onlyOwner {
- for (uint256 i = 0; i < accounts.length; i++) {
- _isExcludedFromFees[accounts[i]] = excluded;
- }
- emit ExcludeMultipleAccountsFromFees(accounts, excluded);
- }
- function setMarketingWallet(address payable wallet) external onlyOwner {
- _marketingWalletAddress = wallet;
- }
- function setTokenRewardsFee(uint256 value) external onlyOwner {
- tokenRewardsFee = value;
- totalFees = tokenRewardsFee.add(liquidityFee).add(marketingFee);
- require(totalFees <= 25, "Total fee is over 25%");
- }
- function setLiquiditFee(uint256 value) external onlyOwner {
- liquidityFee = value;
- totalFees = tokenRewardsFee.add(liquidityFee).add(marketingFee);
- require(totalFees <= 25, "Total fee is over 25%");
- }
- function setMarketingFee(uint256 value) external onlyOwner {
- marketingFee = value;
- totalFees = tokenRewardsFee.add(liquidityFee).add(marketingFee);
- require(totalFees <= 25, "Total fee is over 25%");
- }
- function setAutomatedMarketMakerPair(address pair, bool value)
- public
- onlyOwner
- {
- require(
- pair != uniswapV2Pair,
- "BABYTOKEN: The PancakeSwap pair cannot be removed from automatedMarketMakerPairs"
- );
- _setAutomatedMarketMakerPair(pair, value);
- }
- function _setAutomatedMarketMakerPair(address pair, bool value) private {
- require(
- automatedMarketMakerPairs[pair] != value,
- "BABYTOKEN: Automated market maker pair is already set to that value"
- );
- automatedMarketMakerPairs[pair] = value;
- if (value) {
- dividendTracker.excludeFromDividends(pair);
- }
- emit SetAutomatedMarketMakerPair(pair, value);
- }
- function updateGasForProcessing(uint256 newValue) public onlyOwner {
- require(
- newValue >= 200000 && newValue <= 500000,
- "BABYTOKEN: gasForProcessing must be between 200,000 and 500,000"
- );
- require(
- newValue != gasForProcessing,
- "BABYTOKEN: Cannot update gasForProcessing to same value"
- );
- emit GasForProcessingUpdated(newValue, gasForProcessing);
- gasForProcessing = newValue;
- }
- function updateClaimWait(uint256 claimWait) external onlyOwner {
- dividendTracker.updateClaimWait(claimWait);
- }
- function getClaimWait() external view returns (uint256) {
- return dividendTracker.claimWait();
- }
- function updateMinimumTokenBalanceForDividends(uint256 amount)
- external
- onlyOwner
- {
- dividendTracker.updateMinimumTokenBalanceForDividends(amount);
- }
- function getMinimumTokenBalanceForDividends()
- external
- view
- returns (uint256)
- {
- return dividendTracker.minimumTokenBalanceForDividends();
- }
- function getTotalDividendsDistributed() external view returns (uint256) {
- return dividendTracker.totalDividendsDistributed();
- }
- function isExcludedFromFees(address account) public view returns (bool) {
- return _isExcludedFromFees[account];
- }
- function withdrawableDividendOf(address account)
- public
- view
- returns (uint256)
- {
- return dividendTracker.withdrawableDividendOf(account);
- }
- function dividendTokenBalanceOf(address account)
- public
- view
- returns (uint256)
- {
- return dividendTracker.balanceOf(account);
- }
- function excludeFromDividends(address account) external onlyOwner {
- dividendTracker.excludeFromDividends(account);
- }
- function isExcludedFromDividends(address account)
- public
- view
- returns (bool)
- {
- return dividendTracker.isExcludedFromDividends(account);
- }
- function getAccountDividendsInfo(address account)
- external
- Tib74, [4/22/2022 7:01 PM]
- view
- returns (
- address,
- int256,
- int256,
- uint256,
- uint256,
- uint256,
- uint256,
- uint256
- )
- {
- return dividendTracker.getAccount(account);
- }
- function getAccountDividendsInfoAtIndex(uint256 index)
- external
- view
- returns (
- address,
- int256,
- int256,
- uint256,
- uint256,
- uint256,
- uint256,
- uint256
- )
- {
- return dividendTracker.getAccountAtIndex(index);
- }
- function processDividendTracker(uint256 gas) external {
- (
- uint256 iterations,
- uint256 claims,
- uint256 lastProcessedIndex
- ) = dividendTracker.process(gas);
- emit ProcessedDividendTracker(
- iterations,
- claims,
- lastProcessedIndex,
- false,
- gas,
- tx.origin
- );
- }
- function claim() external {
- dividendTracker.processAccount(payable(msg.sender), false);
- }
- function getLastProcessedIndex() external view returns (uint256) {
- return dividendTracker.getLastProcessedIndex();
- }
- function getNumberOfDividendTokenHolders() external view returns (uint256) {
- return dividendTracker.getNumberOfTokenHolders();
- }
- function _transfer(
- address from,
- address to,
- uint256 amount
- ) internal override {
- require(from != address(0), "ERC20: transfer from the zero address");
- require(to != address(0), "ERC20: transfer to the zero address");
- if (amount == 0) {
- super._transfer(from, to, 0);
- return;
- }
- uint256 contractTokenBalance = balanceOf(address(this));
- bool canSwap = contractTokenBalance >= swapTokensAtAmount;
- if (
- canSwap &&
- !swapping &&
- !automatedMarketMakerPairs[from] &&
- from != owner() &&
- to != owner()
- ) {
- swapping = true;
- uint256 marketingTokens = contractTokenBalance
- .mul(marketingFee)
- .div(totalFees);
- swapAndSendToFee(marketingTokens);
- uint256 swapTokens = contractTokenBalance.mul(liquidityFee).div(
- totalFees
- );
- swapAndLiquify(swapTokens);
- uint256 sellTokens = balanceOf(address(this));
- swapAndSendDividends(sellTokens);
- swapping = false;
- }
- bool takeFee = !swapping;
- // if any account belongs to _isExcludedFromFee account then remove the fee
- if (_isExcludedFromFees[from] || _isExcludedFromFees[to]) {
- takeFee = false;
- }
- if (takeFee) {
- uint256 fees = amount.mul(totalFees).div(100);
- if (automatedMarketMakerPairs[to]) {
- fees += amount.mul(1).div(100);
- }
- amount = amount.sub(fees);
- super._transfer(from, address(this), fees);
- }
- super._transfer(from, to, amount);
- try
- dividendTracker.setBalance(payable(from), balanceOf(from))
- {} catch {}
- try dividendTracker.setBalance(payable(to), balanceOf(to)) {} catch {}
- if (!swapping) {
- uint256 gas = gasForProcessing;
- try dividendTracker.process(gas) returns (
- uint256 iterations,
- uint256 claims,
- uint256 lastProcessedIndex
- ) {
- emit ProcessedDividendTracker(
- iterations,
- claims,
- lastProcessedIndex,
- true,
- gas,
- tx.origin
- );
- } catch {}
- }
- }
- function swapAndSendToFee(uint256 tokens) private {
- uint256 initialCAKEBalance = IERC20(rewardToken).balanceOf(
- address(this)
- );
- swapTokensForCake(tokens);
- Tib74, [4/22/2022 7:01 PM]
- uint256 newBalance = (IERC20(rewardToken).balanceOf(address(this))).sub(
- initialCAKEBalance
- );
- IERC20(rewardToken).transfer(_marketingWalletAddress, newBalance);
- }
- function swapAndLiquify(uint256 tokens) private {
- // split the contract balance into halves
- uint256 half = tokens.div(2);
- uint256 otherHalf = tokens.sub(half);
- // capture the contract's current ETH balance.
- // this is so that we can capture exactly the amount of ETH that the
- // swap creates, and not make the liquidity event include any ETH that
- // has been manually sent to the contract
- uint256 initialBalance = address(this).balance;
- // swap tokens for ETH
- swapTokensForEth(half); // <- this breaks the ETH -> HATE swap when swap+liquify is triggered
- // how much ETH did we just swap into?
- uint256 newBalance = address(this).balance.sub(initialBalance);
- // add liquidity to uniswap
- addLiquidity(otherHalf, newBalance);
- emit SwapAndLiquify(half, newBalance, otherHalf);
- }
- function swapTokensForEth(uint256 tokenAmount) private {
- // generate the uniswap pair path of token -> weth
- address[] memory path = new address[](2);
- path[0] = address(this);
- path[1] = uniswapV2Router.WETH();
- _approve(address(this), address(uniswapV2Router), tokenAmount);
- // make the swap
- uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
- tokenAmount,
- 0, // accept any amount of ETH
- path,
- address(this),
- block.timestamp
- );
- }
- function swapTokensForCake(uint256 tokenAmount) private {
- address[] memory path = new address[](3);
- path[0] = address(this);
- path[1] = uniswapV2Router.WETH();
- path[2] = rewardToken;
- _approve(address(this), address(uniswapV2Router), tokenAmount);
- // make the swap
- uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
- tokenAmount,
- 0,
- path,
- address(this),
- block.timestamp
- );
- }
- function addLiquidity(uint256 tokenAmount, uint256 ethAmount) private {
- // approve token transfer to cover all possible scenarios
- _approve(address(this), address(uniswapV2Router), tokenAmount);
- // add the liquidity
- uniswapV2Router.addLiquidityETH{value: ethAmount}(
- address(this),
- tokenAmount,
- 0, // slippage is unavoidable
- 0, // slippage is unavoidable
- address(0),
- block.timestamp
- );
- }
- function swapAndSendDividends(uint256 tokens) private {
- swapTokensForCake(tokens);
- uint256 dividends = IERC20(rewardToken).balanceOf(address(this));
- bool success = IERC20(rewardToken).transfer(
- address(dividendTracker),
- dividends
- );
- if (success) {
- dividendTracker.distributeCAKEDividends(dividends);
- emit SendDividends(tokens, dividends);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement