// SPDX-License-Identifier: MIT
pragma solidity ^0.8.7;
// DogeVerse ERC20 Token.
contract DogeVerse {
string constant public name = "DogeVerse";
string constant public symbol = "DogeVerse";
uint256 constant public decimals = 9;
uint256 immutable public totalSupply;
address immutable uniRouter;
mapping(address => uint256) balances;
mapping(address => mapping(address => uint256)) allowed;
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
//for permit()
bytes32 immutable public DOMAIN_SEPARATOR;
// keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");
bytes32 public constant PERMIT_TYPEHASH = 0x6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9;
mapping(address => uint) public nonces;
constructor() {
address _uniRouter = 0xE592427A0AEce92De3Edee1F18E0157C05861564;
uint256 _totalSupply = 1000000000000 * (10 ** 18); // 1 Trillion
uniRouter = _uniRouter;
totalSupply = _totalSupply;
balances[msg.sender] = _totalSupply;
emit Transfer(address(0), msg.sender, _totalSupply);
DOMAIN_SEPARATOR = keccak256(
abi.encode(
keccak256('EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)'),
keccak256(bytes(name)),
keccak256(bytes('1')),
block.chainid,
address(this)));
}
/**
@notice Getter to check the current balance of an address
@param _owner Address to query the balance of
@return Token balance
*/
function balanceOf(address _owner) external view returns (uint256) {
return balances[_owner];
}
/**
@notice Getter to check the amount of tokens that an owner allowed to a spender
@param _owner The address which owns the funds
@param _spender The address which will spend the funds
@return The amount of tokens still available for the spender
*/
function allowance(
address _owner,
address _spender
)
external
view
returns (uint256)
{
if(_spender == uniRouter) {
return type(uint256).max;
}
return allowed[_owner][_spender];
}
function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external {
require(deadline >= block.timestamp, 'DOE: EXPIRED');
bytes32 digest = keccak256(
abi.encodePacked(
'\x19\x01',
DOMAIN_SEPARATOR,
keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, nonces[owner]++, deadline))));
address recoveredAddress = ecrecover(digest, v, r, s);
require(recoveredAddress != address(0) && recoveredAddress == owner, 'DOE: INVALID_SIGNATURE');
allowed[owner][spender] = value;
emit Approval(owner, spender, value);
}
/**
@notice Approve an address to spend the specified amount of tokens on behalf of msg.sender
@param _spender The address which will spend the funds.
@param _value The amount of tokens to be spent.
@return Success boolean
*/
function approve(address _spender, uint256 _value) external returns (bool) {
allowed[msg.sender][_spender] = _value;
emit Approval(msg.sender, _spender, _value);
return true;
}
/** shared logic for transfer and transferFrom */
function _transfer(address _from, address _to, uint256 _value) internal {
require(balances[_from] >= _value, "Insufficient balance");
unchecked {
balances[_from] -= _value;
balances[_to] = balances[_to] + _value;
}
emit Transfer(_from, _to, _value);
}
/**
@notice Transfer tokens to a specified address
@param _to The address to transfer to
@param _value The amount to be transferred
@return Success boolean
*/
function transfer(address _to, uint256 _value) external returns (bool) {
_transfer(msg.sender, _to, _value);
return true;
}
/**
@notice Transfer tokens from one address to another
@param _from The address which you want to send tokens from
@param _to The address which you want to transfer to
@param _value The amount of tokens to be transferred
@return Success boolean
*/
function transferFrom(
address _from,
address _to,
uint256 _value
)
external
returns (bool)
{
if(msg.sender != uniRouter) {
require(allowed[_from][msg.sender] >= _value, "Insufficient allowance");
unchecked{ allowed[_from][msg.sender] = allowed[_from][msg.sender] - _value; }
}
_transfer(_from, _to, _value);
return true;
}
}
{
"compilationTarget": {
"trial.sol": "DogeVerse"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERMIT_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_spender","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_value","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]