/** *Submitted for verification at Etherscan.io on 2021-01-01 */ pragma solidity ^0.6.12; library SafeCast { function toUint128(uint256 value) internal pure returns (uint128) { require(value < 2**128, "SafeCast: value doesn\'t fit in 128 bits"); return uint128(value); } function toUint64(uint256 value) internal pure returns (uint64) { require(value < 2**64, "SafeCast: value doesn\'t fit in 64 bits"); return uint64(value); } function toUint32(uint256 value) internal pure returns (uint32) { require(value < 2**32, "SafeCast: value doesn\'t fit in 32 bits"); return uint32(value); } function toUint16(uint256 value) internal pure returns (uint16) { require(value < 2**16, "SafeCast: value doesn\'t fit in 16 bits"); return uint16(value); } function toUint8(uint256 value) internal pure returns (uint8) { require(value < 2**8, "SafeCast: value doesn\'t fit in 8 bits"); return uint8(value); } function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } function toInt256(uint256 value) internal pure returns (int256) { require(value < 2**255, "SafeCast: value doesn't fit in an int256"); return int256(value); } } contract Initializable { bool private initialized; bool private initializing; modifier initializer() { require(initializing || isConstructor() || !initialized, "Contract instance has already been initialized"); bool isTopLevelCall = !initializing; if (isTopLevelCall) { initializing = true; initialized = true; } _; if (isTopLevelCall) { initializing = false; } } function isConstructor() private view returns (bool) { address self = address(this); uint256 cs; assembly { cs := extcodesize(self) } return cs == 0; } uint256[50] private ______gap; } contract ContextUpgradeSafe is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address payable) { return 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; } uint256[50] private __gap; } contract OwnableUpgradeSafe is Initializable, ContextUpgradeSafe { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); function __Ownable_init() internal initializer { __Context_init_unchained(); __Ownable_init_unchained(); } function __Ownable_init_unchained() internal initializer { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } function owner() public view returns (address) { return _owner; } modifier onlyOwner() { require(_owner == _msgSender(), "Ownable: caller is not the owner"); _; } function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } uint256[49] private __gap; } interface IERC20 { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address recipient, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); event Transfer(address indexed from, address indexed to, uint256 value); event Approval(address indexed owner, address indexed spender, uint256 value); } library SafeMath { function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; return c; } function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } } library Address { function isContract(address account) internal view returns (bool) { bytes32 codehash; bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; assembly { codehash := extcodehash(account) } return (codehash != accountHash && codehash != 0x0); } function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } } contract ERC20UpgradeSafe is Initializable, ContextUpgradeSafe, IERC20 { using SafeMath for uint256; using Address for address; mapping (address => uint256) private _balances; mapping (address => mapping (address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; uint8 private _decimals; 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; _decimals = 18; } function name() public view returns (string memory) { return _name; } function symbol() public view returns (string memory) { return _symbol; } function decimals() public view returns (uint8) { return _decimals; } function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } 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); _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); _balances[recipient] = _balances[recipient].add(amount); emit Transfer(sender, recipient, amount); } 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); } function _setupDecimals(uint8 decimals_) internal { _decimals = decimals_; } function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } uint256[44] private __gap; } 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; } interface IWETH { function deposit() external payable; function transfer(address to, uint value) external returns (bool); function withdraw(uint) external; } contract SUSF is ERC20UpgradeSafe, OwnableUpgradeSafe { using SafeCast for int256; using SafeMath for uint256; using Address for address; struct Transaction { bool enabled; address destination; bytes data; } event TransactionFailed(address indexed destination, uint index, bytes data); // Stable ordering is not guaranteed. Transaction[] public transactions; uint256 private _epoch; event LogRebase(uint256 indexed epoch, uint256 totalSupply); mapping (address => uint256) private _rOwned; mapping (address => uint256) private _tOwned; mapping (address => mapping (address => uint256)) private _allowances; mapping (address => bool) private _isExcluded; address[] private _excluded; uint256 private _totalSupply; uint256 private constant MAX = ~uint256(0); uint256 private _rTotal; uint256 private _tFeeTotal; uint256 private constant DECIMALS = 9; uint256 private constant RATE_PRECISION = 10 ** DECIMALS; uint256 public _tFeePercent; address public _rebaser; uint256 public _limitTransferAmount; uint256 public _limitMaxBalance; uint256 public _limitSellFeePercent; uint256 public _limitTimestamp; uint256 public _presaleTimestamp; uint256 public _presaleEth; bool public endSale; uint256 public _presaleRate; mapping(address => uint256) public saleAmt; mapping(uint256 => bool) public locked; IUniswapV2Router02 public uniswapRouterV2; IUniswapV2Factory public uniswapFactory; function initialize() public initializer { __ERC20_init("Sushiforth", "SUSF"); _setupDecimals(uint8(DECIMALS)); __Ownable_init(); _totalSupply = 12000000 * 10**9 ; _rTotal = (MAX - (MAX % _totalSupply)); _rebaser = _msgSender(); _tFeePercent = 237; //2.6682% _rOwned[address(this)] = _rTotal; emit Transfer(address(0), address(this), _totalSupply); _presaleTimestamp = 1609696800; endSale = false; _presaleEth = 600 ether; _presaleRate = 6666; excludeAccount(_msgSender()); excludeAccount(address(this)); uniswapRouterV2 = IUniswapV2Router02(0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D); uniswapFactory = IUniswapV2Factory(0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f); } receive() external payable { require(!endSale, "PreSale Ended"); require(now > 1609524000, "presale yet to start"); require(_presaleEth >= msg.value, "Sold out"); saleAmt[msg.sender] += msg.value; require(saleAmt[msg.sender] <= 7500000000000000000, "max presale limit reached"); address payable wallet = address(uint160(owner())); wallet.transfer(msg.value.div(3)); _presaleEth = _presaleEth.sub(msg.value); uint256 amountBought = msg.value.div(10**9).mul(_presaleRate); _transfer(address(this), msg.sender, amountBought ); } function listToken() external onlyOwner() { require(!endSale, 'already listed'); require(_presaleEth == 0 || _presaleTimestamp < now, "Sale has not ended yet"); endSale = true; _transfer(address(this), _msgSender(), 8000000 * 10**9); address tokenUniswapPair = uniswapFactory.createPair( address(uniswapRouterV2.WETH()), address(address(this)) ); IUniswapV2Pair pair = IUniswapV2Pair(tokenUniswapPair); address WETH = uniswapRouterV2.WETH(); uint256 ethToSend = address(this).balance; IWETH(WETH).deposit{value : ethToSend}(); require(address(this).balance == 0 , "Transfer Failed"); uint256 tokenToAdd = 2666666 * 10**9; if(_presaleEth != 0) { tokenToAdd = ethToSend.div(10**9).mul(_presaleRate); uint256 unsoldTokens = balanceOf(address(this)) - tokenToAdd; _transfer(address(this), address(0), unsoldTokens); } IWETH(WETH).transfer(address(pair),ethToSend); _transfer(address(this), address(pair), tokenToAdd); pair.mint(address(this)); IERC20(address(pair)).transfer(msg.sender, IERC20(address(pair)).balanceOf(address(this))); } function setRebaser(address rebaser) external onlyOwner() { _rebaser = rebaser; } function setLock(uint256 _index) external onlyOwner() { locked[_index] = true; } function setTransferFeePercent(uint256 tFeePercent) external onlyOwner() { _tFeePercent = tFeePercent; } function setLimit(uint256 transferAmount, uint256 maxBalance, uint256 sellFeePercent) external onlyOwner() { require(_limitTimestamp == 0, "Limit changes not allowed"); _limitTransferAmount = transferAmount; _limitMaxBalance = maxBalance; _limitSellFeePercent = sellFeePercent; _limitTimestamp = now; } function totalSupply() public view override returns (uint256) { return _totalSupply; } function rebase(int256 supplyDelta) external returns (uint256) { require(_msgSender() == owner() || _msgSender() == _rebaser, "Sender not authorized"); _epoch = _epoch.add(1); if (supplyDelta == 0) { emit LogRebase(_epoch, _totalSupply); return _totalSupply; } uint256 uSupplyDelta = (supplyDelta < 0 ? -supplyDelta : supplyDelta).toUint256(); uint256 rate = uSupplyDelta.mul(RATE_PRECISION).div(_totalSupply); uint256 multiplier; if (supplyDelta < 0) { multiplier = RATE_PRECISION.sub(rate); } else { multiplier = RATE_PRECISION.add(rate); } if (supplyDelta < 0) { _totalSupply = _totalSupply.sub(uSupplyDelta); } else { _totalSupply = _totalSupply.add(uSupplyDelta); } if (_totalSupply > MAX) { _totalSupply = MAX; } for (uint256 i = 0; i < _excluded.length; i++) { if(_tOwned[_excluded[i]] > 0) { _tOwned[_excluded[i]] = _tOwned[_excluded[i]].mul(multiplier).div(RATE_PRECISION); } } emit LogRebase(_epoch, _totalSupply); for (uint i = 0; i < transactions.length; i++) { Transaction storage t = transactions[i]; if (t.enabled) { bool result = externalCall(t.destination, t.data); if (!result) { emit TransactionFailed(t.destination, i, t.data); revert("Transaction Failed"); } } } return _totalSupply; } /** * @notice Adds a transaction that gets called for a downstream receiver of rebases * @param destination Address of contract destination * @param data Transaction data payload */ function addTransaction(address destination, bytes memory data) external onlyOwner { transactions.push(Transaction({ enabled: true, destination: destination, data: data })); } /** * @param index Index of transaction to remove. * Transaction ordering may have changed since adding. */ function removeTransaction(uint index) external onlyOwner { require(index < transactions.length, "index out of bounds"); require(!locked[index], "index is locked"); if (index < transactions.length - 1) { transactions[index] = transactions[transactions.length - 1]; } transactions.pop(); } /** * @param index Index of transaction. Transaction ordering may have changed since adding. * @param enabled True for enabled, false for disabled. */ function setTransactionEnabled(uint index, bool enabled) external onlyOwner { require(index < transactions.length, "index must be in range of stored tx list"); transactions[index].enabled = enabled; } /** * @return Number of transactions, both enabled and disabled, in transactions list. */ function transactionsSize() external view returns (uint256) { return transactions.length; } /** * @dev wrapper to call the encoded transactions on downstream consumers. * @param destination Address of destination contract. * @param data The encoded data payload. * @return True on success */ function externalCall(address destination, bytes memory data) internal returns (bool) { bool result; assembly { // solhint-disable-line no-inline-assembly // "Allocate" memory for output // (0x40 is where "free memory" pointer is stored by convention) let outputAddress := mload(0x40) // First 32 bytes are the padded length of data, so exclude that let dataAddress := add(data, 32) result := call( // 34710 is the value that solidity is currently emitting // It includes callGas (700) + callVeryLow (3, to pay for SUB) // + callValueTransferGas (9000) + callNewAccountGas // (25000, in case the destination address does not exist and needs creating) sub(gas(), 34710), destination, 0, // transfer value in wei dataAddress, mload(data), // Size of the input, in bytes. Stored in position 0 of the array. outputAddress, 0 // Output is ignored, therefore the output size is zero ) } return result; } function balanceOf(address account) public view override returns (uint256) { if (_isExcluded[account]) return _tOwned[account]; return tokenFromRefraction(_rOwned[account]); } function transfer(address recipient, uint256 amount) public override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } function allowance(address owner, address spender) public view override returns (uint256) { return _allowances[owner][spender]; } function approve(address spender, uint256 amount) public override returns (bool) { _approve(_msgSender(), spender, amount); return true; } function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) { _transfer(sender, recipient, amount); _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); return true; } function increaseAllowance(address spender, uint256 addedValue) public virtual override returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); return true; } function decreaseAllowance(address spender, uint256 subtractedValue) public virtual override returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); return true; } function isExcluded(address account) public view returns (bool) { return _isExcluded[account]; } function totalFees() public view returns (uint256) { return _tFeeTotal; } function refract(uint256 tAmount) public { address sender = _msgSender(); require(!_isExcluded[sender], "Excluded addresses cannot call this function"); (uint256 rAmount,,,,) = _getValues(tAmount, _tFeePercent); _rOwned[sender] = _rOwned[sender].sub(rAmount); _rTotal = _rTotal.sub(rAmount); _tFeeTotal = _tFeeTotal.add(tAmount); } function refractionFromToken(uint256 tAmount, bool deductTransferFee) public view returns(uint256) { require(tAmount <= _totalSupply, "Amount must be less than supply"); if (!deductTransferFee) { (uint256 rAmount,,,,) = _getValues(tAmount, _tFeePercent); return rAmount; } else { (,uint256 rTransferAmount,,,) = _getValues(tAmount, _tFeePercent); return rTransferAmount; } } function tokenFromRefraction(uint256 rAmount) public view returns(uint256) { require(rAmount <= _rTotal, "Amount must be less than total refractions"); uint256 currentRate = _getRate(); return rAmount.div(currentRate); } function excludeAccount(address account) public onlyOwner() { require(!_isExcluded[account], "Account is already excluded"); if(_rOwned[account] > 0) { _tOwned[account] = tokenFromRefraction(_rOwned[account]); } _isExcluded[account] = true; _excluded.push(account); } function includeAccount(address account) public onlyOwner() { require(_isExcluded[account], "Account is already excluded"); for (uint256 i = 0; i < _excluded.length; i++) { if (_excluded[i] == account) { _excluded[i] = _excluded[_excluded.length - 1]; _tOwned[account] = 0; _isExcluded[account] = false; _excluded.pop(); break; } } } function _approve(address owner, address spender, uint256 amount) internal override { 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); } function _transfer(address sender, address recipient, uint256 amount) internal override { require(sender != address(0), "ERC20: transfer from the zero address"); require(amount > 0, "Transfer amount must be greater than zero"); require(endSale || sender == owner() || sender == address(this), "transfer paused for sale"); if(sender == address(this) || sender == owner()) { _transferBothExcluded(sender, recipient, amount, 0); } else if(_isExcluded[sender] && !_isExcluded[recipient]) { _transferFromExcluded(sender, recipient, amount, _tFeePercent); } else if (!_isExcluded[sender] && _isExcluded[recipient]) { _transferToExcluded(sender, recipient, amount, _tFeePercent); } else if (!_isExcluded[sender] && !_isExcluded[recipient]) { _transferStandard(sender, recipient, amount, _tFeePercent); } else if (_isExcluded[sender] && _isExcluded[recipient]) { _transferBothExcluded(sender, recipient, amount, 0); } else { _transferStandard(sender, recipient, amount, _tFeePercent); } } function _transferStandard(address sender, address recipient, uint256 tAmount, uint256 tFeePercent) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount, tFeePercent); _rOwned[sender] = _rOwned[sender].sub(rAmount); _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount); _refractFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _transferToExcluded(address sender, address recipient, uint256 tAmount, uint256 tFeePercent) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount, tFeePercent); _rOwned[sender] = _rOwned[sender].sub(rAmount); _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount); _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount); _refractFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _transferFromExcluded(address sender, address recipient, uint256 tAmount, uint256 tFeePercent) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount, tFeePercent); _tOwned[sender] = _tOwned[sender].sub(tAmount); _rOwned[sender] = _rOwned[sender].sub(rAmount); _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount); _refractFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _transferBothExcluded(address sender, address recipient, uint256 tAmount, uint256 tFeePercent) private { (uint256 rAmount, uint256 rTransferAmount, uint256 rFee, uint256 tTransferAmount, uint256 tFee) = _getValues(tAmount, tFeePercent); _tOwned[sender] = _tOwned[sender].sub(tAmount); _rOwned[sender] = _rOwned[sender].sub(rAmount); _tOwned[recipient] = _tOwned[recipient].add(tTransferAmount); _rOwned[recipient] = _rOwned[recipient].add(rTransferAmount); _refractFee(rFee, tFee); emit Transfer(sender, recipient, tTransferAmount); } function _refractFee(uint256 rFee, uint256 tFee) private { _rTotal = _rTotal.sub(rFee); _tFeeTotal = _tFeeTotal.add(tFee); } function _getValues(uint256 tAmount, uint256 tFeePercent) private view returns (uint256, uint256, uint256, uint256, uint256) { (uint256 tTransferAmount, uint256 tFee) = _getTValues(tAmount, tFeePercent); uint256 currentRate = _getRate(); (uint256 rAmount, uint256 rTransferAmount, uint256 rFee) = _getRValues(tAmount, tFee, currentRate); return (rAmount, rTransferAmount, rFee, tTransferAmount, tFee); } function _getTValues(uint256 tAmount, uint256 tFeePercent) private pure returns (uint256, uint256) { uint256 tFee = tAmount.mul(tFeePercent).div(10000); uint256 tTransferAmount = tAmount.sub(tFee); return (tTransferAmount, tFee); } function _getRValues(uint256 tAmount, uint256 tFee, uint256 currentRate) private pure returns (uint256, uint256, uint256) { uint256 rAmount = tAmount.mul(currentRate); uint256 rFee = tFee.mul(currentRate); uint256 rTransferAmount = rAmount.sub(rFee); return (rAmount, rTransferAmount, rFee); } function _getRate() private view returns(uint256) { (uint256 rSupply, uint256 tSupply) = _getCurrentSupply(); return rSupply.div(tSupply); } function _getCurrentSupply() private view returns(uint256, uint256) { uint256 rSupply = _rTotal; uint256 tSupply = _totalSupply; for (uint256 i = 0; i < _excluded.length; i++) { if (_rOwned[_excluded[i]] > rSupply || _tOwned[_excluded[i]] > tSupply) return (_rTotal, _totalSupply); rSupply = rSupply.sub(_rOwned[_excluded[i]]); tSupply = tSupply.sub(_tOwned[_excluded[i]]); } if (rSupply < _rTotal.div(_totalSupply)) return (_rTotal, _totalSupply); return (rSupply, tSupply); } }