Contract Source Code:
File 1 of 1 : Dogira
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IUniswapV2Factory {
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function migrator() external view returns (address);
function getPair(address tokenA, address tokenB) external view returns (address pair);
function allPairs(uint) external view returns (address pair);
function allPairsLength() external view returns (uint);
function createPair(address tokenA, address tokenB) external returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
function setMigrator(address) external;
}
interface IUniswapV2Router01 {
function factory() external pure returns (address);
function WETH() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint amountADesired,
uint amountBDesired,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB, uint liquidity);
function addLiquidityETH(
address token,
uint amountTokenDesired,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external payable returns (uint amountToken, uint amountETH, uint liquidity);
function removeLiquidity(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline
) external returns (uint amountA, uint amountB);
function removeLiquidityETH(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountToken, uint amountETH);
function removeLiquidityWithPermit(
address tokenA,
address tokenB,
uint liquidity,
uint amountAMin,
uint amountBMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountA, uint amountB);
function removeLiquidityETHWithPermit(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountToken, uint amountETH);
function swapExactTokensForTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapTokensForExactTokens(
uint amountOut,
uint amountInMax,
address[] calldata path,
address to,
uint deadline
) external returns (uint[] memory amounts);
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline)
external
returns (uint[] memory amounts);
function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline)
external
payable
returns (uint[] memory amounts);
function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB);
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut);
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn);
function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts);
function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts);
}
interface IUniswapV2Router02 is IUniswapV2Router01 {
function removeLiquidityETHSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline
) external returns (uint amountETH);
function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens(
address token,
uint liquidity,
uint amountTokenMin,
uint amountETHMin,
address to,
uint deadline,
bool approveMax, uint8 v, bytes32 r, bytes32 s
) external returns (uint amountETH);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
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);
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;
}
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return payable(msg.sender);
}
function _msgData() internal view virtual returns (bytes memory) {
this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
return msg.data;
}
}
contract Owned is Context {
address private _owner;
address private _pendingOwner;
event OwnershipTransferred(address indexed previousOwner, address indexed 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.
*/
function owner() public view returns (address) {
return _owner;
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier ownerOnly {
require(_owner == _msgSender(), "Owner only");
_;
}
modifier pendingOnly {
require (_pendingOwner == msg.sender, "cannot claim");
_;
}
function pendingOwner() public view returns (address) {
return _pendingOwner;
}
function renounceOwnership() public virtual ownerOnly {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public ownerOnly {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_pendingOwner = newOwner;
}
function cancelTransfer() public ownerOnly {
require(_pendingOwner != address(0), "no pending owner");
_pendingOwner = address(0);
}
function claimOwnership() public pendingOnly {
_pendingOwner = address(0);
emit OwnershipTransferred(_owner, _msgSender());
_owner = _msgSender();
}
}
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);
}
contract Pool {}
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position of the value in the `values` array, plus 1 because index 0
// means a value is not in the set.
mapping (bytes32 => uint256) _indexes;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We read and store the value's index to prevent multiple reads from the same storage slot
uint256 valueIndex = set._indexes[value];
if (valueIndex != 0) { // Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 toDeleteIndex = valueIndex - 1;
uint256 lastIndex = set._values.length - 1;
// When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
// so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.
bytes32 lastvalue = set._values[lastIndex];
// Move the last value to the index where the value to delete is
set._values[toDeleteIndex] = lastvalue;
// Update the index for the moved value
set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the index for the deleted slot
delete set._indexes[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._indexes[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
require(set._values.length > index, "EnumerableSet: index out of bounds");
return set._values[index];
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
}
contract Storage {
struct Addresses {
address pool;
address router;
address pair;
address protocol;
address dogecity;
address prizePool;
address buyBonusPool;
address presale;
address rng;
address farm;
}
struct Balance {
uint256 tokenSupply;
uint256 networkSupply;
uint256 targetSupply;
uint256 pairSupply;
uint256 lpSupply;
uint256 fees;
uint256 burned;
}
struct Account {
bool feeless;
bool transferPair;
bool excluded;
uint256 lastDogeIt;
uint256 tTotal;
uint256 rTotal;
uint256 lastShill;
uint256 communityPoints;
uint256 lastAward;
}
struct Divisors {
uint8 buy;
uint8 sell;
// multiplied by 10000
uint8 dogecity;
uint8 bonus;
uint8 tokenLPBurn;
uint8 inflate;
uint8 buyCounter;
uint8 tx;
uint8 dogeitpayout;
uint256 dogeify;
}
struct S {
bool initialized;
bool paused;
uint8 decimals;
uint8 odds;
Addresses addresses;
Balance balances;
Divisors divisors;
uint256 random;
uint256 buyFee;
uint256 sellFee;
uint256 minBuyForBonus;
uint256 buys;
uint256 sells;
uint256 lastAttack;
uint256 attackCooldown;
mapping(address => Account) accounts;
mapping(address => mapping(address => uint256)) allowances;
address[] entries;
string symbol;
string name;
EnumerableSet.AddressSet excludedAccounts;
}
}
contract State {
Storage.S state;
TState lastTState;
enum TxType { FromExcluded, ToExcluded, BothExcluded, Standard }
enum TState { Buy, Sell, Normal }
}
contract Getters is State {
function canIDogeIt() public view returns(bool) {
return state.accounts[msg.sender].lastDogeIt + state.divisors.dogeify < block.timestamp;
}
function isMinBuyForBonus(uint256 amount) public view returns(bool) {
return amount > state.minBuyForBonus * (10 ** state.decimals);
}
function isFeelessTx(address sender, address recipient) public view returns(bool) {
if(sender == state.addresses.presale) {
return true;
}
return state.accounts[sender].feeless || state.accounts[recipient].feeless;
}
function getAccount(address account) public view returns(Storage.Account memory) {
return state.accounts[account];
}
function getDivisors() external view returns(Storage.Divisors memory) {
return state.divisors;
}
function getBurned() external view returns(uint256) {
return state.balances.burned;
}
function getFees() external view returns(uint256) {
return state.balances.fees;
}
function getExcluded(address account) public view returns(bool) {
return state.accounts[account].excluded;
}
function getCurrentLPBal() public view returns(uint256) {
return IERC20(state.addresses.pool).totalSupply();
}
function getLPBalanceOf(address account) external view returns(uint256) {
return IERC20(state.addresses.pool).balanceOf(account);
}
function getFeeless(address account) external view returns (bool) {
return state.accounts[account].feeless;
}
function getTState(address sender, address recipient, uint256 lpAmount) public view returns(TState t) {
if(state.accounts[sender].transferPair) {
if(state.balances.lpSupply != lpAmount) { // withdraw vs buy
t = TState.Normal;
} else {
t = TState.Buy;
}
} else if(state.accounts[recipient].transferPair) {
t = TState.Sell;
} else {
t = TState.Normal;
}
return t;
}
function getRouter() external view returns(address) {
return state.addresses.router;
}
function getPair() external view returns(address) {
return state.addresses.pair;
}
function getPool() external view returns(address) {
return state.addresses.pool;
}
function getCirculatingSupply() public view returns(uint256, uint256) {
uint256 rSupply = state.balances.networkSupply;
uint256 tSupply = state.balances.tokenSupply;
for (uint256 i = 0; i < EnumerableSet.length(state.excludedAccounts); i++) {
address account = EnumerableSet.at(state.excludedAccounts, i);
uint256 rBalance = state.accounts[account].rTotal;
uint256 tBalance = state.accounts[account].tTotal;
if (rBalance > rSupply || tBalance > tSupply) return (state.balances.networkSupply, state.balances.tokenSupply);
rSupply -= rBalance;
tSupply -= tBalance;
}
if (rSupply < state.balances.networkSupply / state.balances.tokenSupply) return (state.balances.networkSupply, state.balances.tokenSupply);
return (rSupply, tSupply);
}
function getTxType(address sender, address recipient) public view returns(TxType t) {
bool isSenderExcluded = state.accounts[sender].excluded;
bool isRecipientExcluded = state.accounts[recipient].excluded;
if (isSenderExcluded && !isRecipientExcluded) {
t = TxType.FromExcluded;
} else if (!isSenderExcluded && isRecipientExcluded) {
t = TxType.ToExcluded;
} else if (!isSenderExcluded && !isRecipientExcluded) {
t = TxType.Standard;
} else if (isSenderExcluded && isRecipientExcluded) {
t = TxType.BothExcluded;
} else {
t = TxType.Standard;
}
}
function getFee(uint256 amount, uint256 divisor) public pure returns (uint256) {
return amount / divisor;
}
function getPrizePoolAddress() public view returns(address) {
return state.addresses.prizePool;
}
function getPrizePoolAmount() public view returns(uint256) {
return state.accounts[getPrizePoolAddress()].rTotal / ratio();
}
function getBuyPoolAmount() public view returns(uint256) {
return state.accounts[getBuyBonusPoolAddress()].rTotal / ratio();
}
function getBuyBonusPoolAddress() public view returns(address) {
return state.addresses.buyBonusPool;
}
function getAmountForMinBuyTax() public view returns(uint256) {
return (state.balances.tokenSupply / 100);
}
function getBuyTax(uint256 amount) public view returns(uint256) {
uint256 _ratio = amount * 100000 / state.balances.tokenSupply;
if(_ratio < 1) { // .001%
return state.divisors.buy; // charges whatever max buy fee is at, to discourage gaming the prizepool.
} else if (_ratio >= 1000) { // 1%
return state.divisors.buy * 5; // charges 1/5th of buy fee, from default is 1%
} else if (_ratio >= 10 && _ratio < 100){
return state.divisors.buy * 2; // and so on.
} else if (_ratio >= 100 && _ratio < 500) {
return state.divisors.buy * 3;
} else if (_ratio >= 500 && _ratio < 1000) {
return state.divisors.buy * 4;
} else { // shouldn't hit this
return state.divisors.buy;
}
}
function getTimeTillNextAttack() public view returns(uint256) {
uint256 time = (state.lastAttack + state.attackCooldown);
return block.timestamp > time ? block.timestamp - time : 0;
}
function getMaxBetAmount() public view returns(uint256) {
return state.accounts[state.addresses.buyBonusPool].tTotal / state.divisors.dogeitpayout;
}
function getLastTState() public view returns(TState) {
return lastTState;
}
function getLevel(address account) public view returns(uint256 level) {
level = state.accounts[account].communityPoints % 1000;
return level == 0 ? 1 : level;
}
function getXP(address account) public view returns(uint256) {
return state.accounts[account].communityPoints;
}
function getBuyAfterSellBonus(uint256 amount) public view returns(uint256 bonus) {
uint256 total = state.accounts[state.addresses.buyBonusPool].tTotal;
if(amount >= total / 100) { // 1% of the pool
bonus = total / state.divisors.bonus;
} else if(amount >= total / 200) { // .5% of the pool
bonus = total / (state.divisors.bonus * 2);
} else if(amount >= total / 500) {
bonus = total / (state.divisors.bonus * 3);
} else if(amount >= total / 1000) {
bonus = total / (state.divisors.bonus * 4);
} else {
bonus = total / (state.divisors.bonus * 5);
}
}
function getBuyAfterBuyBonus() public view returns(uint256 bonus) {
bonus = state.accounts[state.addresses.buyBonusPool].tTotal / 500;
}
function getBuyBonus(uint256 amount) public view returns(uint256) {
uint256 bonus;
if(lastTState == TState.Sell && amount > state.minBuyForBonus) {
bonus = getBuyAfterSellBonus(amount);
} else if(lastTState == TState.Buy && amount > state.minBuyForBonus) {
bonus = getBuyAfterBuyBonus();
} else {
bonus = 0;
}
return bonus > state.accounts[state.addresses.buyBonusPool].tTotal ? 0 : bonus;
}
function ratio() public view returns(uint256) {
return state.balances.networkSupply / state.balances.tokenSupply;
}
}
interface IDogira {
function setRandomSeed(uint256 amount) external;
}
contract Dogira is IDogira, IERC20, Getters, Owned {
struct TxValue {
uint256 amount;
uint256 transferAmount;
uint256 fee;
uint256 buyFee;
uint256 sellFee;
uint256 buyBonus;
uint256 operationalFee;
}
event BonusAwarded(address account, uint256 amount);
event Kek(address account, uint256 amount);
event Doge(address account, uint256 amount);
event Winner(address account, uint256 amount);
event Smashed(uint256 amount);
event Atomacized(uint256 amount);
event Blazed(uint256 amount);
mapping(address => bool) admins;
event FarmAdded(address farm);
event XPAdded(address awardee, uint256 points);
event Hooray(address awardee, uint256 points);
event TransferredToFarm(uint256 amount);
uint256 timeLock;
uint256 dogeCityInitial;
uint256 public lastTeamSell;
uint256 levelCap;
bool rngSet;
bool presaleSet;
modifier onlyAdminOrOwner {
require(admins[msg.sender] || msg.sender == owner(), "invalid caller");
_;
}
constructor() {
initialize();
}
uint256 constant private TOKEN_SUPPLY = 100_000_000;
function name() public view returns(string memory) {
return state.name;
}
function decimals() public view returns(uint8) {
return state.decimals;
}
function symbol() public view returns (string memory) {
return state.symbol;
}
function initialize() public {
require(!state.initialized, "Contract instance has already been initialized");
state.initialized = true;
state.decimals = 18;
state.symbol = "DOGIRA";
state.name = "dogira.lol || dogira.eth.link";
state.balances.tokenSupply = TOKEN_SUPPLY * (10 ** state.decimals);
state.balances.networkSupply = (~uint256(0) - (~uint256(0) % TOKEN_SUPPLY));
state.divisors.buy = 20; // 5% max - 1% depending on buy size.
state.divisors.sell = 20; // 5%
state.divisors.bonus = 50;
state.divisors.dogecity = 100;
state.divisors.inflate = 50;
state.divisors.tokenLPBurn = 50;
state.divisors.tx = 100;
state.divisors.dogeitpayout = 100;
state.divisors.dogeify = 1 hours; // 3600 seconds
state.divisors.buyCounter = 10;
state.odds = 4; // 1 / 4
state.minBuyForBonus = 35000e18;
state.addresses.prizePool = address(new Pool());
state.addresses.buyBonusPool = address(new Pool());
state.addresses.router = address(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D);
state.addresses.dogecity = address(0xfEDD9544b47a6D4A1967D385575866BD6f7A2b37);
state.addresses.pair = IUniswapV2Router02(state.addresses.router).WETH();
state.addresses.pool =
IUniswapV2Factory(IUniswapV2Router02(state.addresses.router).factory()).createPair(address(this), state.addresses.pair);
state.accounts[address(0)].feeless = true;
state.accounts[msg.sender].feeless = true;
//state.accounts[state.addresses.pool].feeless = true;
state.accounts[state.addresses.pool].transferPair = true;
uint256 locked = state.balances.networkSupply / 5; // 20%
uint256 amount = state.balances.networkSupply - locked;
state.accounts[msg.sender].rTotal = amount; // 80%
dogeCityInitial = locked - (locked / 4);
state.accounts[state.addresses.dogecity].feeless = true;
state.accounts[state.addresses.dogecity].rTotal = dogeCityInitial; // 15%
state.accounts[state.addresses.buyBonusPool].rTotal = locked / 4; // 5%
state.accounts[state.addresses.buyBonusPool].tTotal = state.balances.tokenSupply / 20; // 5%
state.paused = true;
state.attackCooldown = 10 minutes;
levelCap = 10;
timeLock = block.timestamp + 3 days;
}
function allowance(address owner, address spender) public view override returns (uint256) {
return state.allowances[owner][spender];
}
function balanceOf(address account) public view override returns (uint256) {
return getExcluded(account) ? state.accounts[account].tTotal : state.accounts[account].rTotal / ratio();
}
function approve(address spender, uint256 amount) public override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function _approve(address owner, address spender, uint256 amount) private {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
state.allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, state.allowances[_msgSender()][spender] + addedValue);
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, state.allowances[_msgSender()][spender] - (subtractedValue));
return true;
}
function totalSupply() public view override returns (uint256) {
return state.balances.tokenSupply;
}
function transfer(address recipient, uint256 amount) public override returns (bool) {
_transfer(msg.sender, recipient, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), state.allowances[sender][_msgSender()] - amount);
return true;
}
function _transfer(address sender, address recipient, uint256 amount) internal returns(bool) {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
require(amount > 0, "Transfer amount must be greater than zero");
if(sender == state.addresses.pool) { // for presales
require(state.paused == false, "Transfers are paused");
}
// removed setter for dogecity to prevent changing the address and making this branch useless.
if(sender == state.addresses.dogecity) {
require(amount <= dogeCityInitial / 20, "too much"); // 5% per day
require(lastTeamSell + 1 days < block.timestamp, "too soon");
require(recipient == state.addresses.pool, "can only sell to uniswap pool");
lastTeamSell = block.timestamp;
}
bool noFee = isFeelessTx(sender, recipient);
uint256 rate = ratio();
uint256 lpAmount = getCurrentLPBal();
(TxValue memory t, TState ts, TxType txType) = tValues(sender, recipient, amount, noFee, lpAmount);
state.balances.lpSupply = lpAmount;
handleTRV(recipient, rate, ts, t);
rTransfer(sender, recipient, rate, t, txType);
state.balances.fees += t.fee;
state.balances.networkSupply -= (t.fee * rate);
lastTState = ts;
emit Transfer(msg.sender, recipient, t.transferAmount);
return true;
}
function transferToFarm(uint256 amount) external ownerOnly {
require(timeLock < block.timestamp, "too soon");
uint256 r = amount * ratio();
state.accounts[state.addresses.dogecity].rTotal -= r;
state.accounts[state.addresses.farm].rTotal += r;
emit TransferredToFarm(amount);
}
function rTransfer(address sender, address recipient, uint256 rate, TxValue memory t, TxType txType) internal {
if (txType == TxType.ToExcluded) {
state.accounts[sender].rTotal -= t.amount * rate;
state.accounts[recipient].tTotal += (t.transferAmount);
state.accounts[recipient].rTotal += t.transferAmount * rate;
} else if (txType == TxType.FromExcluded) {
state.accounts[sender].tTotal -= t.amount;
state.accounts[sender].rTotal -= t.amount * rate;
state.accounts[recipient].rTotal += t.transferAmount * rate;
} else if (txType == TxType.BothExcluded) {
state.accounts[sender].tTotal -= t.amount;
state.accounts[sender].rTotal -= (t.amount * rate);
state.accounts[recipient].tTotal += t.transferAmount;
state.accounts[recipient].rTotal += (t.transferAmount * rate);
} else {
state.accounts[sender].rTotal -= (t.amount * rate);
state.accounts[recipient].rTotal += (t.transferAmount * rate);
}
}
// burn supply, not negative rebase
function verysmashed() external {
require(!state.paused, "still paused");
require(state.lastAttack + state.attackCooldown < block.timestamp, "Dogira coolingdown");
uint256 rLp = state.accounts[state.addresses.pool].rTotal;
uint256 amountToDeflate = (rLp / (state.divisors.tokenLPBurn));
uint256 burned = amountToDeflate / ratio();
state.accounts[state.addresses.pool].rTotal -= amountToDeflate;
state.accounts[address(0)].rTotal += amountToDeflate;
state.accounts[address(0)].tTotal += burned;
state.balances.burned += burned;
state.lastAttack = block.timestamp;
syncPool();
emit Smashed(burned);
}
// positive rebase
function dogebreath() external {
require(!state.paused, "still paused");
require(state.lastAttack + state.attackCooldown < block.timestamp, "Dogira coolingdown");
uint256 rate = ratio();
uint256 target = state.balances.burned == 0 ? state.balances.tokenSupply : state.balances.burned;
uint256 amountToInflate = target / state.divisors.inflate;
if(state.balances.burned > amountToInflate) {
state.balances.burned -= amountToInflate;
state.accounts[address(0)].rTotal -= amountToInflate * rate;
state.accounts[address(0)].tTotal -= amountToInflate;
}
// positive rebase
state.balances.networkSupply -= amountToInflate * rate;
state.lastAttack = block.timestamp;
syncPool();
emit Atomacized(amountToInflate);
}
// disperse amount to all holders
function wow(uint256 amount) external {
address sender = msg.sender;
uint256 rate = ratio();
require(!getExcluded(sender), "Excluded addresses can't call this function");
require(amount * rate < state.accounts[sender].rTotal, "too much");
state.accounts[sender].rTotal -= (amount * rate);
state.balances.networkSupply -= amount * rate;
state.balances.fees += amount;
}
// award community members from the treasury
function muchSupport(address awardee, uint256 multiplier) external onlyAdminOrOwner {
uint256 n = block.timestamp;
require(!state.paused, "still paused");
require(state.accounts[awardee].lastShill + 1 days < n, "nice shill but need to wait");
require(!getExcluded(awardee), "excluded addresses can't be awarded");
require(multiplier <= 100 && multiplier > 0, "can't be more than .1% of dogecity reward");
uint256 level = getLevel(awardee);
if(level > levelCap) {
level = levelCap; // capped at 10
} else if (level <= 0) {
level = 1;
}
uint256 p = ((state.accounts[state.addresses.dogecity].rTotal / 100000) * multiplier) * level; // .001% * m of dogecity * level
state.accounts[state.addresses.dogecity].rTotal -= p;
state.accounts[awardee].rTotal += p;
state.accounts[awardee].lastShill = block.timestamp;
state.accounts[awardee].communityPoints += multiplier;
emit Hooray(awardee, p);
}
function yayCommunity(address awardee, uint256 points) external onlyAdminOrOwner {
uint256 n = block.timestamp;
require(!state.paused, "still paused");
require(state.accounts[awardee].lastAward + 1 days < n, "nice help but need to wait");
require(!getExcluded(awardee), "excluded addresses can't be awarded");
require(points <= 1000 && points > 0, "can't be more than a full level");
state.accounts[awardee].communityPoints += points;
state.accounts[awardee].lastAward = block.timestamp;
emit XPAdded(awardee, points);
}
// burn amount, for cex integration?
function suchburn(uint256 amount) external {
address sender = msg.sender;
uint256 rate = ratio();
require(!getExcluded(sender), "Excluded addresses can't call this function");
require(amount * rate < state.accounts[sender].rTotal, "too much");
state.accounts[sender].rTotal -= (amount * rate);
state.accounts[address(0)].rTotal += (amount * rate);
state.accounts[address(0)].tTotal += (amount);
state.balances.burned += amount;
syncPool();
emit Blazed(amount);
}
function dogeit(uint256 amount) external {
require(!state.paused, "still paused");
require(!getExcluded(msg.sender), "excluded can't call");
uint256 rAmount = amount * ratio();
require(state.accounts[msg.sender].lastDogeIt + state.divisors.dogeify < block.timestamp, "you need to wait to doge");
require(amount > 0, "don't waste your gas");
require(rAmount <= state.accounts[state.addresses.buyBonusPool].rTotal / state.divisors.dogeitpayout, "can't kek too much");
state.accounts[msg.sender].lastDogeIt = block.timestamp;
if((state.random + block.timestamp + block.number) % state.odds == 0) {
state.accounts[state.addresses.buyBonusPool].rTotal -= rAmount;
state.accounts[msg.sender].rTotal += rAmount;
emit Doge(msg.sender, amount);
} else {
state.accounts[msg.sender].rTotal -= rAmount;
state.accounts[state.addresses.buyBonusPool].rTotal += rAmount;
emit Kek(msg.sender, amount);
}
}
function handleTRV(address recipient, uint256 rate, TState ts, TxValue memory t) internal {
state.accounts[state.addresses.dogecity].rTotal += (t.operationalFee * rate);
if(ts == TState.Sell) {
state.accounts[state.addresses.buyBonusPool].rTotal += t.sellFee * rate;
state.accounts[state.addresses.buyBonusPool].tTotal += t.sellFee;
}
if(ts == TState.Buy) {
state.buys++;
uint256 br = t.buyFee * rate;
if(state.buys % state.divisors.buyCounter == 0) {
uint256 a = state.accounts[state.addresses.prizePool].rTotal + (br);
state.accounts[state.addresses.prizePool].rTotal = 0;
state.accounts[state.addresses.prizePool].tTotal = 0;
state.accounts[recipient].rTotal += a;
emit Winner(recipient, a);
} else {
state.accounts[state.addresses.prizePool].rTotal += br;
state.accounts[state.addresses.prizePool].tTotal += t.buyFee;
}
uint256 r = t.buyBonus * rate;
state.accounts[state.addresses.buyBonusPool].rTotal -= r;
state.accounts[state.addresses.buyBonusPool].tTotal -= t.buyBonus;
state.accounts[recipient].rTotal += r;
emit BonusAwarded(recipient, t.buyBonus);
}
}
function tValues(address sender, address recipient, uint256 amount, bool noFee, uint256 lpAmount) public view returns (TxValue memory t, TState ts, TxType txType) {
ts = getTState(sender, recipient, lpAmount);
txType = getTxType(sender, recipient);
t.amount = amount;
if(!noFee) {
t.fee = getFee(amount, state.divisors.tx);
t.operationalFee = getFee(amount, state.divisors.dogecity);
if(ts == TState.Sell) {
uint256 sellFee = getFee(amount, state.divisors.sell);
uint256 sellLevel = sellFee == 0 ? 0 : ((sellFee * getLevel(sender)) / levelCap);
t.sellFee = sellFee - sellLevel;
}
if(ts == TState.Buy) {
t.buyFee = getFee(amount, getBuyTax(amount));
uint256 bonus = getBuyBonus(amount);
uint256 levelBonus = bonus == 0 ? 0 : ((bonus * getLevel(recipient)) / levelCap);
t.buyBonus = bonus + levelBonus;
}
}
t.transferAmount = t.amount - t.fee - t.sellFee - t.buyFee - t.operationalFee;
return (t, ts, txType);
}
function include(address account) external ownerOnly {
require(state.accounts[account].excluded, "Account is already excluded");
state.accounts[account].tTotal = 0;
EnumerableSet.remove(state.excludedAccounts, account);
}
function exclude(address account) external ownerOnly {
require(!state.accounts[account].excluded, "Account is already excluded");
state.accounts[account].excluded = true;
if(state.accounts[account].rTotal > 0) {
state.accounts[account].tTotal = state.accounts[account].rTotal / ratio();
}
state.accounts[account].excluded = true;
EnumerableSet.add(state.excludedAccounts, account);
}
function syncPool() public {
IUniswapV2Pair(state.addresses.pool).sync();
}
function enableTrading() external ownerOnly {
state.paused = false;
}
function adjustOdds(uint8 odds) external ownerOnly {
require(odds >= 2, "can't be more than 50/50");
state.odds = odds;
}
function setPresale(address account) external ownerOnly {
if(!presaleSet) {
state.addresses.presale = account;
state.accounts[account].feeless = true;
presaleSet = true;
}
}
function setBuyBonusDivisor(uint8 fd) external ownerOnly {
require(fd >= 20, "can't be more than 5%");
state.divisors.bonus = fd;
}
function setMinBuyForBuyBonus(uint256 amount) external ownerOnly {
require(amount > 10000e18, "can't be less than 10k tokens");
state.minBuyForBonus = amount * (10 ** state.decimals);
}
function setFeeless(address account, bool value) external ownerOnly {
state.accounts[account].feeless = value;
}
function setBuyFee(uint8 fd) external ownerOnly {
require(fd >= 20, "can't be more than 5%");
state.divisors.buy = fd;
}
function setSellFee(uint8 fd) external ownerOnly {
require(fd >= 10, "can't be more than 10%");
state.divisors.sell = fd;
}
function setFarm(address farm) external ownerOnly {
require(state.addresses.farm == address(0), "farm already set");
uint256 _codeLength;
assembly {_codeLength := extcodesize(farm)}
require(_codeLength > 0, "must be a contract");
state.addresses.farm = farm;
emit FarmAdded(farm);
}
function setRandomSeed(uint256 random) override external {
if(!rngSet){
require(msg.sender == owner(), "not valid caller"); // once chainlink is set random can't be called by owner
} else {
require(msg.sender == state.addresses.rng, "not valid caller"); // for chainlink VRF
}
require(state.random != random, "can't use the same one twice");
state.random = random;
}
function setRngAddr(address addr) external ownerOnly {
state.addresses.rng = addr;
rngSet = true;
}
function setLevelCap(uint256 l) external ownerOnly {
require(l >= 10 && l <= 100, "can't be lower than 10 or greater than 100");
levelCap = l;
}
function setCooldown(uint256 timeInSeconds) external ownerOnly {
require(timeInSeconds > 1 minutes, "too short a time");
state.attackCooldown = timeInSeconds;
}
function setBuyCounter(uint8 counter) external ownerOnly {
require(counter > 5, "too few people");
state.divisors.buyCounter = counter;
}
function setDogeItCooldown(uint256 time) external ownerOnly {
require(time > 5 minutes, "too quick");
state.divisors.dogeify = time;
}
function setTokenLPBurn(uint8 fd) external ownerOnly {
require(fd > 20, "can't be more than 5%");
state.divisors.tokenLPBurn = fd;
}
function setInflation(uint8 fd) external ownerOnly {
require(fd > 20, "can't be more than 5%");
state.divisors.inflate = fd;
}
function setDogeItPayoutLimit(uint8 fd) external ownerOnly {
require(fd >= 50, "can't be more than 2% of the buy bonus supply");
state.divisors.dogeitpayout = fd;
}
function setAdmin(address account, bool value) external ownerOnly {
admins[account] = value;
}
function setDogeCityDivisor(uint8 fd) external ownerOnly {
require(fd >= 50, "can't be more than 2%");
state.divisors.dogecity = fd;
}
}