编译器
0.8.20+commit.a1b79de6
文件 1 的 9:ECDSA.sol
pragma solidity ^0.8.4;
library ECDSA {
error InvalidSignature();
bytes32 private constant _MALLEABILITY_THRESHOLD_PLUS_ONE =
0x7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a1;
function recover(bytes32 hash, bytes memory signature) internal view returns (address result) {
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, byte(0, mload(add(signature, 0x60))))
mstore(0x40, mload(add(signature, 0x20)))
mstore(0x60, mload(add(signature, 0x40)))
pop(
staticcall(
gas(),
and(
eq(mload(signature), 65),
lt(mload(0x60), _MALLEABILITY_THRESHOLD_PLUS_ONE)
),
0x00,
0x80,
0x00,
0x20
)
)
result := mload(0x00)
if iszero(returndatasize()) {
mstore(0x00, 0x8baa579f)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function recoverCalldata(bytes32 hash, bytes calldata signature)
internal
view
returns (address result)
{
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40))))
calldatacopy(0x40, signature.offset, 0x40)
pop(
staticcall(
gas(),
and(
eq(signature.length, 65),
lt(mload(0x60), _MALLEABILITY_THRESHOLD_PLUS_ONE)
),
0x00,
0x80,
0x00,
0x20
)
)
result := mload(0x00)
if iszero(returndatasize()) {
mstore(0x00, 0x8baa579f)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function recover(bytes32 hash, bytes32 r, bytes32 vs) internal view returns (address result) {
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, add(shr(255, vs), 27))
mstore(0x40, r)
mstore(0x60, shr(1, shl(1, vs)))
pop(
staticcall(
gas(),
lt(mload(0x60), _MALLEABILITY_THRESHOLD_PLUS_ONE),
0x00,
0x80,
0x00,
0x20
)
)
result := mload(0x00)
if iszero(returndatasize()) {
mstore(0x00, 0x8baa579f)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
internal
view
returns (address result)
{
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, and(v, 0xff))
mstore(0x40, r)
mstore(0x60, s)
pop(
staticcall(
gas(),
lt(s, _MALLEABILITY_THRESHOLD_PLUS_ONE),
0x00,
0x80,
0x00,
0x20
)
)
result := mload(0x00)
if iszero(returndatasize()) {
mstore(0x00, 0x8baa579f)
revert(0x1c, 0x04)
}
mstore(0x60, 0)
mstore(0x40, m)
}
}
function tryRecover(bytes32 hash, bytes memory signature)
internal
view
returns (address result)
{
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, byte(0, mload(add(signature, 0x60))))
mstore(0x40, mload(add(signature, 0x20)))
mstore(0x60, mload(add(signature, 0x40)))
pop(
staticcall(
gas(),
and(
eq(mload(signature), 65),
lt(mload(0x60), _MALLEABILITY_THRESHOLD_PLUS_ONE)
),
0x00,
0x80,
0x40,
0x20
)
)
mstore(0x60, 0)
result := mload(xor(0x60, returndatasize()))
mstore(0x40, m)
}
}
function tryRecoverCalldata(bytes32 hash, bytes calldata signature)
internal
view
returns (address result)
{
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, byte(0, calldataload(add(signature.offset, 0x40))))
calldatacopy(0x40, signature.offset, 0x40)
pop(
staticcall(
gas(),
and(
eq(signature.length, 65),
lt(mload(0x60), _MALLEABILITY_THRESHOLD_PLUS_ONE)
),
0x00,
0x80,
0x40,
0x20
)
)
mstore(0x60, 0)
result := mload(xor(0x60, returndatasize()))
mstore(0x40, m)
}
}
function tryRecover(bytes32 hash, bytes32 r, bytes32 vs)
internal
view
returns (address result)
{
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, add(shr(255, vs), 27))
mstore(0x40, r)
mstore(0x60, shr(1, shl(1, vs)))
pop(
staticcall(
gas(),
lt(mload(0x60), _MALLEABILITY_THRESHOLD_PLUS_ONE),
0x00,
0x80,
0x40,
0x20
)
)
mstore(0x60, 0)
result := mload(xor(0x60, returndatasize()))
mstore(0x40, m)
}
}
function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s)
internal
view
returns (address result)
{
assembly {
let m := mload(0x40)
mstore(0x00, hash)
mstore(0x20, and(v, 0xff))
mstore(0x40, r)
mstore(0x60, s)
pop(
staticcall(
gas(),
lt(s, _MALLEABILITY_THRESHOLD_PLUS_ONE),
0x00,
0x80,
0x40,
0x20
)
)
mstore(0x60, 0)
result := mload(xor(0x60, returndatasize()))
mstore(0x40, m)
}
}
function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32 result) {
assembly {
mstore(0x20, hash)
mstore(0x00, "\x00\x00\x00\x00\x19Ethereum Signed Message:\n32")
result := keccak256(0x04, 0x3c)
}
}
function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32 result) {
assembly {
let sLength := mload(s)
let o := 0x20
mstore(o, "\x19Ethereum Signed Message:\n")
mstore(0x00, 0x00)
for { let temp := sLength } 1 {} {
o := sub(o, 1)
mstore8(o, add(48, mod(temp, 10)))
temp := div(temp, 10)
if iszero(temp) { break }
}
let n := sub(0x3a, o)
returndatacopy(returndatasize(), returndatasize(), gt(n, 0x20))
mstore(s, or(mload(0x00), mload(n)))
result := keccak256(add(s, sub(0x20, n)), add(n, sLength))
mstore(s, sLength)
}
}
function emptySignature() internal pure returns (bytes calldata signature) {
assembly {
signature.length := 0
}
}
}
文件 2 的 9:EMBR.sol
pragma solidity ^0.8.20;
import "solmate/tokens/ERC20.sol";
import "solmate/auth/Owned.sol";
import "./IUniswapV2Router01.sol";
import "./PersonalEmbrVester.sol";
import "./PresaleManager.sol";
import "./SafeMath.sol";
contract EMBRToken is ERC20, Owned {
using SafeMath for uint256;
uint public buy_tax = 5;
uint public sell_tax = 5;
uint public preventSwapBefore = 10;
uint public buyCount = 0;
uint public swapThreshold = 100_000 * 10**18;
uint public inSwap = 1;
mapping(address => bool) public lps;
mapping(address => bool) public routers;
mapping(address => bool) public excludedFromFee;
address public weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address public uniRouter = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
uint public maxTx = 1_000_000 * 10**18;
uint public maxHolding = 1_000_000 * 10**18;
uint public isTradingEnabled = 1;
mapping(address => bool) public excludedAntiWhales;
constructor() ERC20("Ember", "EMBR", 18) Owned(msg.sender) {
excludedAntiWhales[address(this)] = true;
excludedAntiWhales[msg.sender] = true;
routers[0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D] = true;
allowance[address(this)][0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D] = type(uint256).max;
excludedAntiWhales[0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D] = true;
super._mint(msg.sender, 9_000_000 * 10**18);
}
modifier lockTheSwap() {
inSwap = 2;
_;
inSwap = 1;
}
function setMaxTx(uint amount) onlyOwner external {
maxTx = amount;
}
function setMaxHolding(uint amount) onlyOwner external {
maxHolding = amount;
}
function excludeWhale(address addy) onlyOwner external {
excludedAntiWhales[addy] = true;
}
function setUniRouter(address newRouter) onlyOwner external {
uniRouter = newRouter;
}
function setAmm(address lp) onlyOwner external {
lps[lp] = true;
excludedAntiWhales[lp] = true;
}
function setRouter(address router) onlyOwner external {
routers[router] = true;
allowance[address(this)][router] = type(uint256).max;
excludedAntiWhales[router] = true;
}
function excludeFromFee(address addy) onlyOwner external {
excludedFromFee[addy] = true;
}
function setPreventSwapBefore(uint counter) onlyOwner external {
preventSwapBefore = counter;
}
function setSwapThreshold(uint newThreshold) onlyOwner external {
swapThreshold = newThreshold;
}
function setSellTax(uint newTax) onlyOwner external {
sell_tax = newTax;
}
function setBuyTax(uint newTax) onlyOwner external {
buy_tax = newTax;
}
function transfer(address to, uint256 amount) public override returns (bool) {
_transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public override returns (bool) {
uint256 allowed = allowance[from][msg.sender];
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
_transfer(from, to, amount);
return true;
}
function _transfer(address from, address to, uint256 amount) private {
require(isTradingEnabled == 2 || tx.origin == owner, "trading isnt live");
require(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
require(amount > 0, "Transfer amount must be greater than zero");
require(maxTx >= amount || excludedAntiWhales[from], "max tx limit");
uint256 taxAmount = 0;
if (from != owner && to != owner && tx.origin != owner) {
bool isSelling;
if (lps[from] &&
!routers[to] &&
!excludedFromFee[to]) {
buyCount++;
taxAmount = amount
.mul(buy_tax)
.div(100);
}
if (lps[to] && from != address(this)) {
isSelling = true;
taxAmount = amount
.mul(sell_tax)
.div(100);
}
uint256 contractTokenBalance = balanceOf[address(this)];
if (
inSwap == 1 &&
isSelling &&
contractTokenBalance > swapThreshold &&
buyCount > preventSwapBefore
) {
swapTokensForEth(contractTokenBalance);
uint256 contractETHBalance = address(this).balance;
if (contractETHBalance > 0.1 ether) {
payable(owner).transfer(contractETHBalance);
}
}
}
if (taxAmount > 0) {
balanceOf[address(this)] = balanceOf[address(this)].add(taxAmount);
emit Transfer(from, address(this), taxAmount);
}
balanceOf[from] = balanceOf[from].sub(amount);
balanceOf[to] = balanceOf[to].add(amount.sub(taxAmount));
require(balanceOf[to] <= maxHolding || excludedAntiWhales[to] || tx.origin == owner, "max holding limit");
emit Transfer(from, to, amount.sub(taxAmount));
}
function enableTrading() onlyOwner external {
isTradingEnabled = 2;
}
function claimTaxes() onlyOwner external {
uint256 contractTokenBalance = balanceOf[address(this)];
balanceOf[address(this)] -= contractTokenBalance;
balanceOf[owner] += contractTokenBalance;
emit Transfer(address(this), owner, contractTokenBalance);
}
function swapTokensForEth(uint amount) private lockTheSwap {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = weth;
IUniswapV2Router01(uniRouter).swapExactTokensForETHSupportingFeeOnTransferTokens(amount, 0, path, address(this), 99999999999999999999);
}
function mint(uint amount) onlyOwner external {
super._mint(owner, amount);
}
receive() external payable { }
function withdraw() onlyOwner external {
(bool sent,) = owner.call{value: address(this).balance}("");
require(sent, "Failed to send Ether");
}
}
文件 3 的 9:ERC20.sol
pragma solidity >=0.8.0;
abstract contract ERC20 {
event Transfer(address indexed from, address indexed to, uint256 amount);
event Approval(address indexed owner, address indexed spender, uint256 amount);
string public name;
string public symbol;
uint8 public immutable decimals;
uint256 public totalSupply;
mapping(address => uint256) public balanceOf;
mapping(address => mapping(address => uint256)) public allowance;
uint256 internal immutable INITIAL_CHAIN_ID;
bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;
mapping(address => uint256) public nonces;
constructor(
string memory _name,
string memory _symbol,
uint8 _decimals
) {
name = _name;
symbol = _symbol;
decimals = _decimals;
INITIAL_CHAIN_ID = block.chainid;
INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
}
function approve(address spender, uint256 amount) public virtual returns (bool) {
allowance[msg.sender][spender] = amount;
emit Approval(msg.sender, spender, amount);
return true;
}
function transfer(address to, uint256 amount) public virtual returns (bool) {
balanceOf[msg.sender] -= amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(msg.sender, to, amount);
return true;
}
function transferFrom(
address from,
address to,
uint256 amount
) public virtual returns (bool) {
uint256 allowed = allowance[from][msg.sender];
if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;
balanceOf[from] -= amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(from, to, amount);
return true;
}
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) public virtual {
require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");
unchecked {
address recoveredAddress = ecrecover(
keccak256(
abi.encodePacked(
"\x19\x01",
DOMAIN_SEPARATOR(),
keccak256(
abi.encode(
keccak256(
"Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
),
owner,
spender,
value,
nonces[owner]++,
deadline
)
)
)
),
v,
r,
s
);
require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");
allowance[recoveredAddress][spender] = value;
}
emit Approval(owner, spender, value);
}
function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
}
function computeDomainSeparator() internal view virtual returns (bytes32) {
return
keccak256(
abi.encode(
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
keccak256(bytes(name)),
keccak256("1"),
block.chainid,
address(this)
)
);
}
function _mint(address to, uint256 amount) internal virtual {
totalSupply += amount;
unchecked {
balanceOf[to] += amount;
}
emit Transfer(address(0), to, amount);
}
function _burn(address from, uint256 amount) internal virtual {
balanceOf[from] -= amount;
unchecked {
totalSupply -= amount;
}
emit Transfer(from, address(0), amount);
}
}
文件 4 的 9:IEMBR.sol
pragma solidity ^0.8.20;
interface IEMBRToken {
function mint_allowance(address addy) external returns (uint);
function mintWithAllowance(uint amount, address receiver) external;
}
文件 5 的 9:IUniswapV2Router01.sol
pragma solidity >=0.6.2;
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 swapExactTokensForETHSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
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);
}
文件 6 的 9:Owned.sol
pragma solidity >=0.8.0;
abstract contract Owned {
event OwnershipTransferred(address indexed user, address indexed newOwner);
address public owner;
modifier onlyOwner() virtual {
require(msg.sender == owner, "UNAUTHORIZED");
_;
}
constructor(address _owner) {
owner = _owner;
emit OwnershipTransferred(address(0), _owner);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
owner = newOwner;
emit OwnershipTransferred(msg.sender, newOwner);
}
}
文件 7 的 9:PersonalEmbrVester.sol
pragma solidity ^0.8.20;
import "./EMBR.sol";
import "solmate/tokens/ERC20.sol";
contract PersonalVester {
address public claimer;
EMBRToken public embr;
uint public vestingTime;
uint public cliff;
uint public totalTokens;
uint public startingTime;
uint public totalClaimed;
uint256 public precision = 10e9;
constructor(uint _totalTokens, uint _vestingTime, uint _cliff, address _claimer){
totalTokens = _totalTokens;
vestingTime = _vestingTime;
cliff = _cliff;
claimer = _claimer;
}
function startVest() external {
require(msg.sender == address(embr), "caller must be embr contract");
startingTime = block.timestamp;
}
function claim() public returns (uint256) {
require(msg.sender == claimer, "invalid caller");
require(startingTime != 0, "vesting is not started");
require(block.timestamp > startingTime + cliff, "cliff not reached!");
uint passedTime = block.timestamp - startingTime;
if (passedTime > vestingTime) passedTime = vestingTime;
uint totalClaimableTokens = totalTokens * precision * passedTime / vestingTime / precision;
uint toClaim = totalClaimableTokens - totalClaimed;
totalClaimed += toClaim;
embr.transfer(msg.sender, toClaim);
return toClaim;
}
function claimable() external view returns (uint256) {
if (startingTime == 0) return 0;
if (block.timestamp < startingTime + cliff) return 0;
uint passedTime = block.timestamp - startingTime;
if (passedTime > vestingTime) passedTime = vestingTime;
uint totalClaimableTokens = totalTokens * precision * passedTime / vestingTime / precision;
uint toClaim = totalClaimableTokens - totalClaimed;
return toClaim;
}
}
文件 8 的 9:PresaleManager.sol
pragma solidity ^0.8.20;
import "solmate/auth/Owned.sol";
import "./IEMBR.sol";
import "solady/src/utils/ECDSA.sol";
using ECDSA for bytes32;
contract EMBRPresale is Owned {
IEMBRToken public ember_token;
uint public total_commited_eth;
uint public hard_cap = 500.01 ether;
uint public precision = 10**21;
uint public commit_start;
uint public commit_length;
mapping(address => uint) public commited_amount;
mapping(address => uint) public claimed;
uint public vesting_start;
uint public cliff_period = 14 days;
uint public vesting_period = 90 days;
uint public PRICE_PER_TOKEN = 0.00016667 ether;
address public claimSigner;
event Commit(address indexed from, uint commit_amount, uint total_commitment);
constructor(address _claimSigner, uint _commitStart, uint _commitLength) Owned(msg.sender) {
claimSigner = _claimSigner;
commit_start = _commitStart;
commit_length = _commitLength;
}
function commit(bytes memory signature, uint min_allocation, uint max_allocation) payable public {
require(block.timestamp >= commit_start, "Sale is not live yet");
require(block.timestamp < (commit_start + commit_length), "Sale already ended");
require(msg.value > 0, "Commitment amount too low");
bytes32 hashed = keccak256(abi.encodePacked(msg.sender, min_allocation, max_allocation));
bytes32 message = ECDSA.toEthSignedMessageHash(hashed);
address recovered_address = ECDSA.recover(message, signature);
require(recovered_address == claimSigner, "Invalid signer");
uint user_commited_amount = commited_amount[msg.sender];
require(user_commited_amount >= min_allocation || msg.value >= min_allocation, "Minimum presale commitment not met");
uint allocation_available = max_allocation - user_commited_amount;
uint leftFromHardCap = hard_cap - total_commited_eth;
if (leftFromHardCap < allocation_available) allocation_available = leftFromHardCap;
require(allocation_available > 0, "No more allocation left");
uint commit_amount = msg.value;
if (msg.value > allocation_available) {
uint leftover = msg.value - allocation_available;
(bool sent,) = msg.sender.call{value: leftover}("");
require(sent, "Failed to send Ether");
commit_amount -= leftover;
}
commited_amount[msg.sender] += commit_amount;
total_commited_eth += commit_amount;
emit Commit(msg.sender, commit_amount, commited_amount[msg.sender]);
}
function claim() external returns (uint) {
require(vesting_start != 0, "vesting hasnt started yet bro");
require(block.timestamp >= vesting_start + cliff_period, "You can only start claiming after cliff period");
uint passedTime = block.timestamp - vesting_start;
if (passedTime > vesting_period) passedTime = vesting_period;
uint totalUserTokens = commited_amount[msg.sender] * 10**18 / PRICE_PER_TOKEN;
uint totalClaimableTokens = totalUserTokens * precision * passedTime / vesting_period / precision;
uint toClaim = totalClaimableTokens - claimed[msg.sender];
claimed[msg.sender] += toClaim;
ember_token.mintWithAllowance(toClaim, msg.sender);
return toClaim;
}
function claimable() external view returns (uint) {
if (vesting_start == 0) return 0;
if (block.timestamp < vesting_start + cliff_period) return 0;
uint passedTime = block.timestamp - vesting_start;
if (passedTime > vesting_period) passedTime = vesting_period;
uint totalUserTokens = commited_amount[msg.sender] * 10**18 / PRICE_PER_TOKEN;
uint totalClaimableTokens = totalUserTokens * precision * passedTime / vesting_period / precision;
uint toClaim = totalClaimableTokens - claimed[msg.sender];
return toClaim;
}
function withdraw() onlyOwner external {
(bool sent,) = owner.call{value: address(this).balance}("");
require(sent, "Failed to send Ether");
}
function startVesting() onlyOwner external {
vesting_start = block.timestamp;
}
function setEmbr(address embr) onlyOwner external {
ember_token = IEMBRToken(embr);
}
function setCommitInfo(uint startTs, uint length) onlyOwner external {
commit_start = startTs;
commit_length = length;
}
function setHardCap(uint new_hardcap) onlyOwner external {
hard_cap = new_hardcap;
}
}
文件 9 的 9:SafeMath.sol
pragma solidity ^0.8.20;
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
if (a == 0) {
return 0;
}
c = a * b;
assert(c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
assert(c >= a);
return c;
}
}
{
"compilationTarget": {
"src/EMBR.sol": "EMBRToken"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": [
":ds-test/=lib/forge-std/lib/ds-test/src/",
":forge-std/=lib/forge-std/src/",
":solady/=lib/solady/",
":solmate/=lib/solmate/src/"
]
}
[{"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":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buy_tax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimTaxes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addy","type":"address"}],"name":"excludeFromFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addy","type":"address"}],"name":"excludeWhale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"excludedAntiWhales","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"excludedFromFee","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inSwap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isTradingEnabled","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lps","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxHolding","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","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":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"preventSwapBefore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"routers","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sell_tax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"lp","type":"address"}],"name":"setAmm","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTax","type":"uint256"}],"name":"setBuyTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxHolding","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"setMaxTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"counter","type":"uint256"}],"name":"setPreventSwapBefore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"router","type":"address"}],"name":"setRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newTax","type":"uint256"}],"name":"setSellTax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newThreshold","type":"uint256"}],"name":"setSwapThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newRouter","type":"address"}],"name":"setUniRouter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapThreshold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"amount","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":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uniRouter","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"weth","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]