// SPDX-License-Identifier: MITpragmasolidity ^0.8.6;/*
* @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).
*
* This contract is only required for intermediate, library-like contracts.
*/abstractcontractContext{
function_msgSender() internalviewvirtualreturns (address) {
returnmsg.sender;
}
function_msgData() internalviewvirtualreturns (bytescalldata) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691returnmsg.data;
}
}
Contract Source Code
File 2 of 11: DividendPayingToken.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.6;import"./ERC20.sol";
import"./SafeMath.sol";
import"./DividendPayingTokenInterface.sol";
import"./DividendPayingTokenOptionalInterface.sol";
/// @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#codecontractDividendPayingTokenisERC20, DividendPayingTokenInterface, DividendPayingTokenOptionalInterface{
usingSafeMathforuint256;
usingSafeMathUintforuint256;
usingSafeMathIntforint256;
// 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-472352728uint256constantinternal magnitude =2**128;
uint256internal 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;
uint256public totalDividendsDistributed;
uint256public totalDividendsWithdrawn;
constructor(stringmemory _name, stringmemory _symbol) ERC20(_name, _symbol) {
}
/// @dev Distributes dividends whenever ether is paid to this contract.receive() externalpayable{
distributeDividends();
}
/// @notice Distributes ether to token holders as dividends./// @dev It reverts if the total supply of tokens is 0./// It emits the `DividendsDistributed` event if the amount of received ether is greater than 0./// About undistributed ether:/// In each distribution, there is a small amount of ether not distributed,/// the magnified amount of which is/// `(msg.value * magnitude) % totalSupply()`./// With a well-chosen `magnitude`, the amount of undistributed ether/// (de-magnified) in a distribution can be less than 1 wei./// We can actually keep track of the undistributed ether in a distribution/// and try to distribute it in the next distribution,/// but keeping track of such data on-chain costs much more than/// the saved ether, so we don't do that.functiondistributeDividends() publicoverridepayable{
require(totalSupply() >0);
if (msg.value>0) {
magnifiedDividendPerShare = magnifiedDividendPerShare.add(
(msg.value).mul(magnitude) / totalSupply()
);
emit DividendsDistributed(msg.sender, msg.value);
totalDividendsDistributed = totalDividendsDistributed.add(msg.value);
}
}
/// @notice Withdraws the ether distributed to the sender./// @dev It emits a `DividendWithdrawn` event if the amount of withdrawn ether is greater than 0.functionwithdrawDividend() publicvirtualoverride{
_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(addresspayable user) internalreturns (uint256) {
uint256 _withdrawableDividend = withdrawableDividendOf(user);
if (_withdrawableDividend >0) {
withdrawnDividends[user] = withdrawnDividends[user].add(_withdrawableDividend);
totalDividendsWithdrawn += _withdrawableDividend;
emit DividendWithdrawn(user, _withdrawableDividend);
(bool success,) = user.call{value: _withdrawableDividend, gas: 3000}("");
if(!success) {
withdrawnDividends[user] = withdrawnDividends[user].sub(_withdrawableDividend);
totalDividendsWithdrawn -= _withdrawableDividend;
return0;
}
return _withdrawableDividend;
}
return0;
}
/// @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.functiondividendOf(address _owner) publicviewoverridereturns(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.functionwithdrawableDividendOf(address _owner) publicviewoverridereturns(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.functionwithdrawnDividendOf(address _owner) publicviewoverridereturns(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.functionaccumulativeDividendOf(address _owner) publicviewoverridereturns(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(addressfrom, address to, uint256 value) internalvirtualoverride{
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./// @param account The account that will receive the created tokens./// @param value The amount that will be created.function_mint(address account, uint256 value) internaloverride{
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) internaloverride{
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);
} elseif(newBalance < currentBalance) {
uint256 burnAmount = currentBalance.sub(newBalance);
_burn(account, burnAmount);
}
}
}
Contract Source Code
File 3 of 11: DividendPayingTokenInterface.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.6;/// @title Dividend-Paying Token Interface/// @author Roger Wu (https://github.com/roger-wu)/// @dev An interface for a dividend-paying token contract.interfaceDividendPayingTokenInterface{
/// @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.functiondividendOf(address _owner) externalviewreturns(uint256);
/// @notice Distributes ether to token holders as dividends./// @dev SHOULD distribute the paid ether to token holders as dividends./// SHOULD NOT directly transfer ether to token holders in this function./// MUST emit a `DividendsDistributed` event when the amount of distributed ether is greater than 0.functiondistributeDividends() externalpayable;
/// @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.functionwithdrawDividend() 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.eventDividendsDistributed(addressindexedfrom,
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.eventDividendWithdrawn(addressindexed to,
uint256 weiAmount
);
}
Contract Source Code
File 4 of 11: DividendPayingTokenOptionalInterface.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.6;/// @title Dividend-Paying Token Optional Interface/// @author Roger Wu (https://github.com/roger-wu)/// @dev OPTIONAL functions for a dividend-paying token contract.interfaceDividendPayingTokenOptionalInterface{
/// @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.functionwithdrawableDividendOf(address _owner) externalviewreturns(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.functionwithdrawnDividendOf(address _owner) externalviewreturns(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.functionaccumulativeDividendOf(address _owner) externalviewreturns(uint256);
}
Contract Source Code
File 5 of 11: ERC20.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.6;import"./IERC20.sol";
import"./Context.sol";
import"./SafeMath.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 guidelines: functions revert instead
* of 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}.
*/contractERC20isContext, IERC20, IERC20Metadata{
usingSafeMathforuint256;
mapping(address=>uint256) private _balances;
mapping(address=>mapping(address=>uint256)) private _allowances;
uint256private _totalSupply;
stringprivate _name;
stringprivate _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(stringmemory name_, stringmemory symbol_) {
_name = name_;
_symbol = symbol_;
}
/**
* @dev Returns the name of the token.
*/functionname() publicviewvirtualoverridereturns (stringmemory) {
return _name;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/functionsymbol() publicviewvirtualoverridereturns (stringmemory) {
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}.
*/functiondecimals() publicviewvirtualoverridereturns (uint8) {
return9;
}
/**
* @dev See {IERC20-totalSupply}.
*/functiontotalSupply() publicviewvirtualoverridereturns (uint256) {
return _totalSupply;
}
/**
* @dev See {IERC20-balanceOf}.
*/functionbalanceOf(address account) publicviewvirtualoverridereturns (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`.
*/functiontransfer(address recipient, uint256 amount) publicvirtualoverridereturns (bool) {
_transfer(_msgSender(), recipient, amount);
returntrue;
}
/**
* @dev See {IERC20-allowance}.
*/functionallowance(address owner, address spender) publicviewvirtualoverridereturns (uint256) {
return _allowances[owner][spender];
}
/**
* @dev See {IERC20-approve}.
*
* Requirements:
*
* - `spender` cannot be the zero address.
*/functionapprove(address spender, uint256 amount) publicvirtualoverridereturns (bool) {
_approve(_msgSender(), spender, amount);
returntrue;
}
/**
* @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`.
*/functiontransferFrom(address sender,
address recipient,
uint256 amount
) publicvirtualoverridereturns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
returntrue;
}
/**
* @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.
*/functionincreaseAllowance(address spender, uint256 addedValue) publicvirtualreturns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
returntrue;
}
/**
* @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`.
*/functiondecreaseAllowance(address spender, uint256 subtractedValue) publicvirtualreturns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
returntrue;
}
/**
* @dev Moves tokens `amount` from `sender` to `recipient`.
*
* This is 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
) internalvirtual{
require(sender !=address(0), "ERC20: transfer from the zero address");
require(recipient !=address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(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) internalvirtual{
require(account !=address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(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) internalvirtual{
require(account !=address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(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
) internalvirtual{
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 to 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(addressfrom,
address to,
uint256 amount
) internalvirtual{}
}
// SPDX-License-Identifier: MITpragmasolidity ^0.8.6;/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/interfaceIERC20{
/**
* @dev Returns the amount of tokens in existence.
*/functiontotalSupply() externalviewreturns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/functionbalanceOf(address account) externalviewreturns (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.
*/functiontransfer(address recipient, uint256 amount) externalreturns (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.
*/functionallowance(address owner, address spender) externalviewreturns (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.
*/functionapprove(address spender, uint256 amount) externalreturns (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.
*/functiontransferFrom(address sender,
address recipient,
uint256 amount
) externalreturns (bool);
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/eventTransfer(addressindexedfrom, addressindexed 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.
*/eventApproval(addressindexed owner, addressindexed spender, uint256 value);
}
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/interfaceIERC20MetadataisIERC20{
/**
* @dev Returns the name of the token.
*/functionname() externalviewreturns (stringmemory);
/**
* @dev Returns the symbol of the token.
*/functionsymbol() externalviewreturns (stringmemory);
/**
* @dev Returns the decimals places of the token.
*/functiondecimals() externalviewreturns (uint8);
}
pragmasolidity ^0.8.6;// SPDX-License-Identifier: MIT Licenseimport"./Context.sol";
contractOwnableisContext{
addressprivate _owner;
eventOwnershipTransferred(addressindexed previousOwner, addressindexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/constructor () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
/**
* @dev Returns the address of the current owner.
*/functionowner() publicviewreturns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/modifieronlyOwner() {
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.
*/functionrenounceOwnership() publicvirtualonlyOwner{
emit OwnershipTransferred(_owner, address(0));
_owner =address(0);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/functiontransferOwnership(address newOwner) publicvirtualonlyOwner{
require(newOwner !=address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
Contract Source Code
File 10 of 11: SafeMath.sol
// SPDX-License-Identifier: MITpragmasolidity ^0.8.6;librarySafeMath{
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/functionadd(uint256 a, uint256 b) internalpurereturns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
/**
* @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.
*/functionsub(uint256 a, uint256 b) internalpurereturns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/functionsub(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/functionmul(uint256 a, uint256 b) internalpurereturns (uint256) {
// 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/522if (a ==0) {
return0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts 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.
*/functiondiv(uint256 a, uint256 b) internalpurereturns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
/**
* @dev Returns the integer division of two unsigned integers. Reverts 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.
*/functiondiv(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b >0, errorMessage);
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't holdreturn c;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts 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.
*/functionmod(uint256 a, uint256 b) internalpurereturns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* Reverts with custom message 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.
*/functionmod(uint256 a, uint256 b, stringmemory errorMessage) internalpurereturns (uint256) {
require(b !=0, errorMessage);
return a % b;
}
}
/**
* @title SafeMathInt
* @dev Math operations for int256 with overflow safety checks.
*/librarySafeMathInt{
int256privateconstant MIN_INT256 =int256(1) <<255;
int256privateconstant MAX_INT256 =~(int256(1) <<255);
/**
* @dev Multiplies two int256 variables and fails on overflow.
*/functionmul(int256 a, int256 b) internalpurereturns (int256) {
int256 c = a * b;
// Detect overflow when multiplying MIN_INT256 with -1require(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.
*/functiondiv(int256 a, int256 b) internalpurereturns (int256) {
// Prevent overflow when dividing MIN_INT256 by -1require(b !=-1|| a != MIN_INT256);
// Solidity already throws when dividing by 0.return a / b;
}
/**
* @dev Subtracts two int256 variables and fails on overflow.
*/functionsub(int256 a, int256 b) internalpurereturns (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.
*/functionadd(int256 a, int256 b) internalpurereturns (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.
*/functionabs(int256 a) internalpurereturns (int256) {
require(a != MIN_INT256);
return a <0 ? -a : a;
}
functiontoUint256Safe(int256 a) internalpurereturns (uint256) {
require(a >=0);
returnuint256(a);
}
}
/**
* @title SafeMathUint
* @dev Math operations with safety checks that revert on error
*/librarySafeMathUint{
functiontoInt256Safe(uint256 a) internalpurereturns (int256) {
int256 b =int256(a);
require(b >=0);
return b;
}
}
Contract Source Code
File 11 of 11: TWITTERINU.sol
// SPDX-License-Identifier: Unlicensed/*
WELCOME TO TWITTER INU
MEET THE ONLY DEFLATIONARY INU TOKEN THAT GIVES YOU AN INSANE AMOUNT OF ETHEREUM REWARDS
DEFI, MEME, DEFI 3.0 , FAAS, DAAS , NFT, FARMING, PASSIVE INCOME... EVERYTHING YOU ARE LOOKING FOR IS HERE.
Its very simple, TWITTERINU need to go viral in the crypto space!!! Buy a bag, claim anytime, enjoy the ETH rewards, use every social network you know (Twitter especially) and share the hashtag #TWITTERINU everywhere, anywhere.
Always like, comment and retweet our tweets.
Dont waste time on Telegram asking when 100x, when binance, when moon. You ask when calls, when marketing? This is the answer: Twitter is free and is the biggest tool for marketing in the Crypto world.
BUY, SHILL, CLAIM, REPEAT.
LETS GO VIRAL
LIQUIDITY LOCKED 1 YEAR, DYNAMIC FEES BASED ON THE MARKET SENTIMENT, NO FEES ON TRANSFER.
https://t.me/TwitterInu (At launch the only way to communicate with us in on twitter, every comment, every post you make need to have the hashtag #TWITTERINU
https://twitter.com/TwInuProject
*/pragmasolidity ^0.8.6;import"./DividendPayingToken.sol";
import"./IterableMapping.sol";
import"./Ownable.sol";
import"./IDex.sol";
import"./SafeMath.sol";
libraryAddress{
functionsendValue(addresspayable recipient, uint256 amount) internal{
require(address(this).balance>= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
}
contractTWITTERINUisERC20, Ownable{
usingAddressforaddresspayable;
IRouter public router;
addresspublic pair;
boolprivate swapping;
boolpublic swapEnabled =true;
mapping (address=>bool) public isBot;
TWITTERINUDividendTracker public dividendTracker;
uint256public swapTokensAtAmount =500_000_000* (10**9);
uint256public maxTxAmount =10000000000*10**9;
uint256public maxWalletBalance =50000000000*10**9;
uint256public ETHRewardsFee =0;
uint256public treasuryFee =20;
uint256public liquidityFee =0;
uint256public totalFees = ETHRewardsFee + treasuryFee + liquidityFee;
uint256public sellETHRewardsFee =20;
uint256public sellTreasuryFee =0;
uint256public sellLiquidityFee =20;
uint256public sellTotalFees = sellETHRewardsFee + sellLiquidityFee + sellTreasuryFee;
addresspublic treasuryWallet =0x775D05a72504cD751Ac25Fa298443E688dAA0d5a;
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 amountmapping (address=>bool) public automatedMarketMakerPairs;
eventUpdateDividendTracker(addressindexed newAddress, addressindexed oldAddress);
eventUpdaterouter(addressindexed newAddress, addressindexed oldAddress);
eventExcludeFromFees(addressindexed account, bool isExcluded);
eventExcludeMultipleAccountsFromFees(address[] accounts, bool isExcluded);
eventSetAutomatedMarketMakerPair(addressindexed pair, boolindexed value);
eventGasForProcessingUpdated(uint256indexed newValue, uint256indexed oldValue);
eventSwapAndLiquify(uint256 tokensSwapped,
uint256 ethReceived,
uint256 tokensIntoLiqudity
);
eventSendDividends(uint256 tokensSwapped,
uint256 amount
);
modifierlockTheSwap{
swapping =true;
_;
swapping =false;
}
constructor() ERC20("TWITTER INU", "TWITTERINU") {
dividendTracker =new TWITTERINUDividendTracker();
IRouter _router = IRouter(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
// Create a uniswap pair for this new tokenaddress _pair = IFactory(_router.factory())
.createPair(address(this), _router.WETH());
router = _router;
pair = _pair;
_setAutomatedMarketMakerPair(_pair, true);
// exclude from receiving dividends
dividendTracker.excludeFromDividends(address(dividendTracker));
dividendTracker.excludeFromDividends(address(this));
dividendTracker.excludeFromDividends(owner());
dividendTracker.excludeFromDividends(0x000000000000000000000000000000000000dEaD);
dividendTracker.excludeFromDividends(address(_router));
// exclude from paying fees or having max transaction amount
excludeFromFees(owner(), true);
excludeFromFees(address(this), true);
excludeFromFees(treasuryWallet, true);
/*
_mint is an internal function in ERC20.sol that is only called here,
and CANNOT be called ever again
*/
_mint(owner(), 1e12* (10**9));
}
receive() externalpayable{
}
functionupdateDividendTracker(address newAddress) publiconlyOwner{
require(newAddress !=address(dividendTracker), "TWITTERINU: The dividend tracker already has that address");
TWITTERINUDividendTracker newDividendTracker = TWITTERINUDividendTracker(payable(newAddress));
require(newDividendTracker.owner() ==address(this), "TWITTERINU: The new dividend tracker must be owned by the TWITTERINU token contract");
newDividendTracker.excludeFromDividends(address(newDividendTracker));
newDividendTracker.excludeFromDividends(address(this));
newDividendTracker.excludeFromDividends(owner());
newDividendTracker.excludeFromDividends(address(router));
emit UpdateDividendTracker(newAddress, address(dividendTracker));
dividendTracker = newDividendTracker;
}
functionupdateRouter(address newAddress) publiconlyOwner{
require(newAddress !=address(router), "TWITTERINU: The router already has that address");
emit Updaterouter(newAddress, address(router));
router = IRouter(newAddress);
}
functionexcludeFromFees(address account, bool excluded) publiconlyOwner{
require(_isExcludedFromFees[account] != excluded, "TWITTERINU: Account is already the value of 'excluded'");
_isExcludedFromFees[account] = excluded;
emit ExcludeFromFees(account, excluded);
}
functionexcludeMultipleAccountsFromFees(address[] calldata accounts, bool excluded) publiconlyOwner{
for(uint256 i =0; i < accounts.length; i++) {
_isExcludedFromFees[accounts[i]] = excluded;
}
emit ExcludeMultipleAccountsFromFees(accounts, excluded);
}
functionsetSwapTokensAtAmount(uint256 amount) externalonlyOwner{
swapTokensAtAmount = amount *10**9;
}
functionsetAutomatedMarketMakerPair(address newPair, bool value) publiconlyOwner{
require(newPair != pair, "TWITTERINU: The PancakeSwap pair cannot be removed from automatedMarketMakerPairs");
_setAutomatedMarketMakerPair(newPair, value);
}
functionexcludeFromDividends(address account) externalonlyOwner{
dividendTracker.excludeFromDividends(account);
}
function_setAutomatedMarketMakerPair(address newPair, bool value) private{
require(automatedMarketMakerPairs[newPair] != value, "TWITTERINU: Automated market maker pair is already set to that value");
automatedMarketMakerPairs[newPair] = value;
if(value) {
dividendTracker.excludeFromDividends(newPair);
}
emit SetAutomatedMarketMakerPair(newPair, value);
}
functionsetMaxtxAmount(uint256 amount) externalonlyOwner{
maxTxAmount = amount *10**9;
}
functionsetMaxWalletBalance(uint256 amount) externalonlyOwner{
maxWalletBalance = amount *10**9;
}
/// @notice Withdraw tokens sent by mistake./// @param tokenAddress The address of the token to withdrawfunctionrescueBEP20Tokens(address tokenAddress) externalonlyOwner{
IERC20(tokenAddress).transfer(msg.sender, IERC20(tokenAddress).balanceOf(address(this)));
}
functionforceSend() external{
uint256 ETHbalance =address(this).balance;
payable(owner()).sendValue(ETHbalance);
}
functiongetTotalDividendsDistributed() externalviewreturns (uint256) {
return dividendTracker.totalDividendsDistributed();
}
functionisExcludedFromFees(address account) publicviewreturns(bool) {
return _isExcludedFromFees[account];
}
functionwithdrawableDividendOf(address account) publicviewreturns(uint256) {
return dividendTracker.withdrawableDividendOf(account);
}
functiondividendTokenBalanceOf(address account) publicviewreturns (uint256) {
return dividendTracker.balanceOf(account);
}
functiongetAccountInfo(address account)
externalviewreturns (address,
uint256,
uint256,
uint256,
uint256){
return dividendTracker.getAccount(account);
}
functionclaim() external{
dividendTracker.processAccount(payable(msg.sender), false);
}
functionsetBuyFees(uint256 _rewards, uint256 _liquidity, uint256 _treasury) externalonlyOwner{
require(_rewards + _liquidity + _treasury <=40, "max fee is 40%");
ETHRewardsFee = _rewards;
liquidityFee = _liquidity;
treasuryFee = _treasury;
totalFees = ETHRewardsFee + liquidityFee + treasuryFee;
}
functionsetSellFees(uint256 _rewards, uint256 _liquidity, uint256 _treasury) externalonlyOwner{
require(_rewards + _liquidity + _treasury <=40, "max fee is 40%");
sellETHRewardsFee = _rewards;
sellLiquidityFee = _liquidity;
sellTreasuryFee = _treasury;
sellTotalFees = sellETHRewardsFee + sellLiquidityFee + sellTreasuryFee;
}
functionsetTreasuryWallet(address newWallet) externalonlyOwner{
treasuryWallet = newWallet;
}
functionsetSwapEnabled(bool value) externalonlyOwner{
swapEnabled = value;
}
functionsetBot(address account, bool state) externalonlyOwner{
isBot[account] = state;
}
function_transfer(addressfrom,
address to,
uint256 amount
) internaloverride{
require(from!=address(0), "ERC20: transfer from the zero address");
require(to !=address(0), "ERC20: transfer to the zero address");
require(!isBot[from] &&!isBot[to], "You are a bot");
if(!_isExcludedFromFees[from] &&!_isExcludedFromFees[to]){
require(amount <= maxTxAmount ,"You are exceeding maxTxAmount");
if(!automatedMarketMakerPairs[to]){
require(balanceOf(to) + amount <= maxWalletBalance ,"You are exceeding maxWalletBalance");
}
}
if(amount ==0) {
super._transfer(from, to, 0);
return;
}
uint256 contractTokenBalance = balanceOf(address(this));
bool canSwap = contractTokenBalance >= swapTokensAtAmount;
if(canSwap && swapEnabled &&!swapping &&from!= pair &&!_isExcludedFromFees[from] &&!_isExcludedFromFees[to]) {
if(totalFees >0){
swapAndLiquify(swapTokensAtAmount);
}
}
bool takeFee =!swapping;
// if any account belongs to _isExcludedFromFee account then remove the feeif(_isExcludedFromFees[from] || _isExcludedFromFees[to] && (!automatedMarketMakerPairs[from] &&!automatedMarketMakerPairs[to])) {
takeFee =false;
}
if(takeFee) {
uint256 fees;
if(automatedMarketMakerPairs[from]) fees = amount * (totalFees) / (100);
elseif(automatedMarketMakerPairs[to]) fees = amount * sellTotalFees /100;
amount = amount - fees;
super._transfer(from, address(this), fees);
}
super._transfer(from, to, amount);
dividendTracker.setBalance(payable(from), balanceOf(from));
dividendTracker.setBalance(payable(to), balanceOf(to));
}
functionswapAndLiquify(uint256 tokens) privatelockTheSwap{
// Split the contract balance into halvesuint256 denominator= (sellTotalFees) *2;
uint256 tokensToAddLiquidityWith = tokens * sellLiquidityFee / denominator;
uint256 toSwap = tokens - tokensToAddLiquidityWith;
uint256 initialBalance =address(this).balance;
swapTokensForETH(toSwap);
uint256 deltaBalance =address(this).balance- initialBalance;
uint256 unitBalance= deltaBalance / (denominator - sellLiquidityFee);
uint256 ethToAddLiquidityWith = unitBalance * sellLiquidityFee;
if(ethToAddLiquidityWith >0){
// Add liquidity to pancake
addLiquidity(tokensToAddLiquidityWith, ethToAddLiquidityWith);
}
// Send ETH to treasuryuint256 treasuryAmt = (unitBalance *2* sellTreasuryFee);
if(treasuryAmt >0){
payable(treasuryWallet).sendValue(treasuryAmt);
}
// Send ETH to rewardsuint256 dividends = unitBalance *2* ETHRewardsFee;
if(dividends >0){
(bool success,) =address(dividendTracker).call{value: dividends}("");
if(success)emit SendDividends(tokens, dividends);
}
}
functionaddLiquidity(uint256 tokenAmount, uint256 ethAmount) private{
// approve token transfer to cover all possible scenarios
_approve(address(this), address(router), tokenAmount);
// add the liquidity
router.addLiquidityETH{value: ethAmount}(
address(this),
tokenAmount,
0, // slippage is unavoidable0, // slippage is unavoidableaddress(0),
block.timestamp
);
}
functionswapTokensForETH(uint256 tokenAmount) private{
// generate the uniswap pair path of token -> wethaddress[] memory path =newaddress[](2);
path[0] =address(this);
path[1] = router.WETH();
_approve(address(this), address(router), tokenAmount);
// make the swap
router.swapExactTokensForETHSupportingFeeOnTransferTokens(
tokenAmount,
0, // accept any amount of ETH
path,
address(this),
block.timestamp
);
}
}
contractTWITTERINUDividendTrackerisDividendPayingToken, Ownable{
structAccountInfo {
address account;
uint256 withdrawableDividends;
uint256 totalDividends;
uint256 lastClaimTime;
}
mapping(address=>uint256) public lastClaimTimes;
mapping (address=>bool) public excludedFromDividends;
eventExcludeFromDividends(addressindexed account);
eventClaim(addressindexed account, uint256 amount, boolindexed automatic);
constructor() DividendPayingToken("TWITTERINU_Dividend_Tracker", "TWITTERINU_Dividend_Tracker") { }
function_transfer(address, address, uint256) internalpureoverride{
require(false, "TWITTERINU_Dividend_Tracker: No transfers allowed");
}
functionwithdrawDividend() publicpureoverride{
require(false, "TWITTERINU_Dividend_Tracker: withdrawDividend disabled. Use the 'claim' function on the main TWITTERINU contract.");
}
functionexcludeFromDividends(address account) externalonlyOwner{
require(!excludedFromDividends[account]);
excludedFromDividends[account] =true;
_setBalance(account, 0);
emit ExcludeFromDividends(account);
}
functiongetAccount(address account) publicviewreturns (address, uint256, uint256, uint256, uint256) {
AccountInfo memory info;
info.account = account;
info.withdrawableDividends = withdrawableDividendOf(account);
info.totalDividends = accumulativeDividendOf(account);
info.lastClaimTime = lastClaimTimes[account];
return (
info.account,
info.withdrawableDividends,
info.totalDividends,
info.lastClaimTime,
totalDividendsWithdrawn
);
}
functionsetBalance(addresspayable account, uint256 newBalance) externalonlyOwner{
if(excludedFromDividends[account]) {
return;
}
_setBalance(account, newBalance);
}
functionprocessAccount(addresspayable account, bool automatic) publiconlyOwnerreturns (bool) {
uint256 amount = _withdrawDividendOfUser(account);
if(amount >0) {
lastClaimTimes[account] =block.timestamp;
emit Claim(account, amount, automatic);
returntrue;
}
returnfalse;
}
}