Skip to content

Instantly share code, notes, and snippets.

@thexeromin
Last active February 21, 2023 11:18
Show Gist options
  • Save thexeromin/2cbf09c8fcf264e890de0a8aa322fb09 to your computer and use it in GitHub Desktop.
Save thexeromin/2cbf09c8fcf264e890de0a8aa322fb09 to your computer and use it in GitHub Desktop.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
interface IDEXRouter {
function factory() external pure returns (address);
function WBRISE() external pure returns (address);
function addLiquidity(
address tokenA,
address tokenB,
uint256 amountADesired,
uint256 amountBDesired,
uint256 amountAMin,
uint256 amountBMin,
address to,
uint256 deadline
) external returns (uint256 amountA, uint256 amountB, uint256 liquidity);
function addLiquidityBRISE(
address token,
uint256 amountTokenDesired,
uint256 amountTokenMin,
uint256 amountBRISEMin,
address to,
uint256 deadline
)
external
payable
returns (uint256 amountToken, uint256 amountBRISE, uint256 liquidity);
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function swapExactBRISEForTokensSupportingFeeOnTransferTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable;
function swapExactTokensForBRISESupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
}
interface IDEXFactory {
function createPair(
address tokenA,
address tokenB
) external returns (address pair);
}
contract Token is Context, IERC20, IERC20Metadata, Ownable {
using SafeMath for uint256;
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
mapping(address => bool) public blacklist;
mapping(address => bool) _minters;
mapping(address => bool) _isFeeExempt;
mapping(address => bool) public automatedMarketMakerPairs;
address[] public _markerPairs;
uint256 private _totalSupply;
uint256 private _initialSupply = 1 * 10 ** 9 * 10 ** 18;
string private _name = "Testing";
string private _symbol = "TEST";
bool public feesOnNormalTransfers = false;
bool public feesOnBRISE = false;
address public liquidityReceiver =
0x341d7eb69809B5035FC3F0fDd11b55372549D449;
address public treasuryReceiver =
0xd341fD31249Da902cC80A19d2643CCD5D57F7B4E;
uint256 public liquidityFee = 1;
uint256 public treasuryFee = 1;
uint256 public feeDenominator = 100;
IDEXRouter public router;
constructor() {
router = IDEXRouter(0x21086f765FcaFE6F78a76b43B207ADC7e9b529C4);
_mint(msg.sender, _initialSupply);
_isFeeExempt[address(this)] = true;
_isFeeExempt[msg.sender] = true;
_minters[msg.sender] = true;
}
modifier onlyMinters() {
require(_minters[msg.sender], "Not an owner");
_;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function decimals() public view virtual override returns (uint8) {
return 18;
}
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 to,
uint256 amount
) public virtual override returns (bool) {
address owner = _msgSender();
_transfer(owner, to, 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) {
address owner = _msgSender();
_approve(owner, spender, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual override returns (bool) {
address spender = _msgSender();
_spendAllowance(from, spender, amount);
_transfer(from, to, amount);
return true;
}
function increaseAllowance(
address spender,
uint256 addedValue
) public virtual returns (bool) {
address owner = _msgSender();
_approve(owner, spender, allowance(owner, spender) + addedValue);
return true;
}
function decreaseAllowance(
address spender,
uint256 subtractedValue
) public virtual returns (bool) {
address owner = _msgSender();
uint256 currentAllowance = allowance(owner, spender);
require(
currentAllowance >= subtractedValue,
"ERC20: decreased allowance below zero"
);
unchecked {
_approve(owner, spender, currentAllowance - subtractedValue);
}
return true;
}
function _transfer(
address from,
address to,
uint256 amount
) internal virtual {
require(!blacklist[from] && !blacklist[to], "in_blacklist");
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
uint256 gonAmountReceived = shouldTakeFee(from, to)
? takeFee(from, amount)
: amount;
uint256 fromBalance = _balances[from];
require(
fromBalance >= amount,
"ERC20: transfer amount exceeds balance"
);
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += gonAmountReceived;
emit Transfer(from, to, gonAmountReceived);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
uint256 accountBalance = _balances[account];
require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
unchecked {
_balances[account] = accountBalance - amount;
}
_totalSupply -= amount;
emit Transfer(account, address(0), amount);
}
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 _spendAllowance(
address owner,
address spender,
uint256 amount
) internal virtual {
uint256 currentAllowance = allowance(owner, spender);
if (currentAllowance != type(uint256).max) {
require(
currentAllowance >= amount,
"ERC20: insufficient allowance"
);
unchecked {
_approve(owner, spender, currentAllowance - amount);
}
}
}
function updateBlacklist(
address _user,
bool _flag
) public virtual onlyOwner {
blacklist[_user] = _flag;
}
function setMinters(address _user, bool _flag) public virtual onlyOwner {
_minters[_user] = _flag;
}
function setFeesOnBRISE(bool _flag) public virtual onlyOwner {
feesOnBRISE = _flag;
}
function setFeeExempt(address _addr, bool _value) public virtual onlyOwner {
require(_isFeeExempt[_addr] != _value, "Not changed");
_isFeeExempt[_addr] = _value;
}
function setFeesOnNormalTransfers(bool _enabled) public virtual onlyOwner {
require(feesOnNormalTransfers != _enabled, "Not changed");
feesOnNormalTransfers = _enabled;
}
function setFeeReceivers(
address _liquidityReceiver,
address _treasuryReceiver
) public virtual onlyOwner {
liquidityReceiver = _liquidityReceiver;
treasuryReceiver = _treasuryReceiver;
}
function shouldTakeFee(
address from,
address to
) internal view returns (bool) {
if (_isFeeExempt[from] || _isFeeExempt[to]) {
return false;
} else if (feesOnNormalTransfers) {
return true;
} else {
return (automatedMarketMakerPairs[from] ||
automatedMarketMakerPairs[to]);
}
}
function takeFee(
address sender,
uint256 amount
) internal virtual returns (uint256) {
uint256 treasuryFeeAmount = amount.mul(treasuryFee).div(feeDenominator);
uint256 liquidityFeeAmount = amount.mul(liquidityFee).div(
feeDenominator
);
uint256 totalFeeAmount = treasuryFeeAmount.add(liquidityFeeAmount);
if (feesOnBRISE) {
_swapTokensForBrise(treasuryFeeAmount, treasuryReceiver);
_swapTokensForBrise(liquidityFeeAmount, liquidityReceiver);
} else {
_balances[treasuryReceiver] += treasuryFeeAmount;
_balances[liquidityReceiver] += liquidityFeeAmount;
}
emit Transfer(sender, address(this), totalFeeAmount);
return amount.sub(totalFeeAmount);
}
function mint(address account, uint256 amount) public onlyMinters {
_mint(account, amount);
}
function _swapTokensForBrise(
uint256 tokenAmount,
address receiver
) private {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = router.WBRISE();
router.swapExactTokensForBRISESupportingFeeOnTransferTokens(
tokenAmount,
0,
path,
receiver,
block.timestamp
);
}
receive() external payable {}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment