编译器
0.8.16+commit.07a7930e
文件 1 的 29:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 29:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 3 的 29:Counters.sol
pragma solidity ^0.8.0;
library Counters {
struct Counter {
uint256 _value;
}
function current(Counter storage counter) internal view returns (uint256) {
return counter._value;
}
function increment(Counter storage counter) internal {
unchecked {
counter._value += 1;
}
}
function decrement(Counter storage counter) internal {
uint256 value = counter._value;
require(value > 0, "Counter: decrement overflow");
unchecked {
counter._value = value - 1;
}
}
function reset(Counter storage counter) internal {
counter._value = 0;
}
}
文件 4 的 29:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 5 的 29:ERC20.sol
pragma solidity ^0.8.0;
import "./IERC20.sol";
import "./extensions/IERC20Metadata.sol";
import "../../utils/Context.sol";
contract ERC20 is Context, IERC20, IERC20Metadata {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
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(from != address(0), "ERC20: transfer from the zero address");
require(to != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(from, to, amount);
uint256 fromBalance = _balances[from];
require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
unchecked {
_balances[from] = fromBalance - amount;
}
_balances[to] += amount;
emit Transfer(from, to, amount);
_afterTokenTransfer(from, to, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply += amount;
_balances[account] += amount;
emit Transfer(address(0), account, amount);
_afterTokenTransfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
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);
_afterTokenTransfer(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 _beforeTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 amount
) internal virtual {}
}
文件 6 的 29:ERC721.sol
pragma solidity ^0.8.0;
import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
using Address for address;
using Strings for uint256;
string private _name;
string private _symbol;
mapping(uint256 => address) private _owners;
mapping(address => uint256) private _balances;
mapping(uint256 => address) private _tokenApprovals;
mapping(address => mapping(address => bool)) private _operatorApprovals;
constructor(string memory name_, string memory symbol_) {
_name = name_;
_symbol = symbol_;
}
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return
interfaceId == type(IERC721).interfaceId ||
interfaceId == type(IERC721Metadata).interfaceId ||
super.supportsInterface(interfaceId);
}
function balanceOf(address owner) public view virtual override returns (uint256) {
require(owner != address(0), "ERC721: address zero is not a valid owner");
return _balances[owner];
}
function ownerOf(uint256 tokenId) public view virtual override returns (address) {
address owner = _owners[tokenId];
require(owner != address(0), "ERC721: invalid token ID");
return owner;
}
function name() public view virtual override returns (string memory) {
return _name;
}
function symbol() public view virtual override returns (string memory) {
return _symbol;
}
function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
_requireMinted(tokenId);
string memory baseURI = _baseURI();
return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
}
function _baseURI() internal view virtual returns (string memory) {
return "";
}
function approve(address to, uint256 tokenId) public virtual override {
address owner = ERC721.ownerOf(tokenId);
require(to != owner, "ERC721: approval to current owner");
require(
_msgSender() == owner || isApprovedForAll(owner, _msgSender()),
"ERC721: approve caller is not token owner nor approved for all"
);
_approve(to, tokenId);
}
function getApproved(uint256 tokenId) public view virtual override returns (address) {
_requireMinted(tokenId);
return _tokenApprovals[tokenId];
}
function setApprovalForAll(address operator, bool approved) public virtual override {
_setApprovalForAll(_msgSender(), operator, approved);
}
function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
return _operatorApprovals[owner][operator];
}
function transferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
_transfer(from, to, tokenId);
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) public virtual override {
safeTransferFrom(from, to, tokenId, "");
}
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes memory data
) public virtual override {
require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
_safeTransfer(from, to, tokenId, data);
}
function _safeTransfer(
address from,
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_transfer(from, to, tokenId);
require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
}
function _exists(uint256 tokenId) internal view virtual returns (bool) {
return _owners[tokenId] != address(0);
}
function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
address owner = ERC721.ownerOf(tokenId);
return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
}
function _safeMint(address to, uint256 tokenId) internal virtual {
_safeMint(to, tokenId, "");
}
function _safeMint(
address to,
uint256 tokenId,
bytes memory data
) internal virtual {
_mint(to, tokenId);
require(
_checkOnERC721Received(address(0), to, tokenId, data),
"ERC721: transfer to non ERC721Receiver implementer"
);
}
function _mint(address to, uint256 tokenId) internal virtual {
require(to != address(0), "ERC721: mint to the zero address");
require(!_exists(tokenId), "ERC721: token already minted");
_beforeTokenTransfer(address(0), to, tokenId);
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(address(0), to, tokenId);
_afterTokenTransfer(address(0), to, tokenId);
}
function _burn(uint256 tokenId) internal virtual {
address owner = ERC721.ownerOf(tokenId);
_beforeTokenTransfer(owner, address(0), tokenId);
_approve(address(0), tokenId);
_balances[owner] -= 1;
delete _owners[tokenId];
emit Transfer(owner, address(0), tokenId);
_afterTokenTransfer(owner, address(0), tokenId);
}
function _transfer(
address from,
address to,
uint256 tokenId
) internal virtual {
require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
require(to != address(0), "ERC721: transfer to the zero address");
_beforeTokenTransfer(from, to, tokenId);
_approve(address(0), tokenId);
_balances[from] -= 1;
_balances[to] += 1;
_owners[tokenId] = to;
emit Transfer(from, to, tokenId);
_afterTokenTransfer(from, to, tokenId);
}
function _approve(address to, uint256 tokenId) internal virtual {
_tokenApprovals[tokenId] = to;
emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
}
function _setApprovalForAll(
address owner,
address operator,
bool approved
) internal virtual {
require(owner != operator, "ERC721: approve to caller");
_operatorApprovals[owner][operator] = approved;
emit ApprovalForAll(owner, operator, approved);
}
function _requireMinted(uint256 tokenId) internal view virtual {
require(_exists(tokenId), "ERC721: invalid token ID");
}
function _checkOnERC721Received(
address from,
address to,
uint256 tokenId,
bytes memory data
) private returns (bool) {
if (to.isContract()) {
try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
return retval == IERC721Receiver.onERC721Received.selector;
} catch (bytes memory reason) {
if (reason.length == 0) {
revert("ERC721: transfer to non ERC721Receiver implementer");
} else {
assembly {
revert(add(32, reason), mload(reason))
}
}
}
} else {
return true;
}
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
function _afterTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual {}
}
文件 7 的 29:ERC721Enumerable.sol
pragma solidity ^0.8.0;
import "../ERC721.sol";
import "./IERC721Enumerable.sol";
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
mapping(address => mapping(uint256 => uint256)) private _ownedTokens;
mapping(uint256 => uint256) private _ownedTokensIndex;
uint256[] private _allTokens;
mapping(uint256 => uint256) private _allTokensIndex;
function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
}
function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
return _ownedTokens[owner][index];
}
function totalSupply() public view virtual override returns (uint256) {
return _allTokens.length;
}
function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
return _allTokens[index];
}
function _beforeTokenTransfer(
address from,
address to,
uint256 tokenId
) internal virtual override {
super._beforeTokenTransfer(from, to, tokenId);
if (from == address(0)) {
_addTokenToAllTokensEnumeration(tokenId);
} else if (from != to) {
_removeTokenFromOwnerEnumeration(from, tokenId);
}
if (to == address(0)) {
_removeTokenFromAllTokensEnumeration(tokenId);
} else if (to != from) {
_addTokenToOwnerEnumeration(to, tokenId);
}
}
function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
uint256 length = ERC721.balanceOf(to);
_ownedTokens[to][length] = tokenId;
_ownedTokensIndex[tokenId] = length;
}
function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
_allTokensIndex[tokenId] = _allTokens.length;
_allTokens.push(tokenId);
}
function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
uint256 tokenIndex = _ownedTokensIndex[tokenId];
if (tokenIndex != lastTokenIndex) {
uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];
_ownedTokens[from][tokenIndex] = lastTokenId;
_ownedTokensIndex[lastTokenId] = tokenIndex;
}
delete _ownedTokensIndex[tokenId];
delete _ownedTokens[from][lastTokenIndex];
}
function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
uint256 lastTokenIndex = _allTokens.length - 1;
uint256 tokenIndex = _allTokensIndex[tokenId];
uint256 lastTokenId = _allTokens[lastTokenIndex];
_allTokens[tokenIndex] = lastTokenId;
_allTokensIndex[lastTokenId] = tokenIndex;
delete _allTokensIndex[tokenId];
_allTokens.pop();
}
}
文件 8 的 29:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 9 的 29:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, 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 from,
address to,
uint256 amount
) external returns (bool);
}
文件 10 的 29:IERC20Metadata.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
interface IERC20Metadata is IERC20 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function decimals() external view returns (uint8);
}
文件 11 的 29:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function setApprovalForAll(address operator, bool _approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 12 的 29:IERC721Enumerable.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Enumerable is IERC721 {
function totalSupply() external view returns (uint256);
function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);
function tokenByIndex(uint256 index) external view returns (uint256);
}
文件 13 的 29:IERC721Metadata.sol
pragma solidity ^0.8.0;
import "../IERC721.sol";
interface IERC721Metadata is IERC721 {
function name() external view returns (string memory);
function symbol() external view returns (string memory);
function tokenURI(uint256 tokenId) external view returns (string memory);
}
文件 14 的 29:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 15 的 29:IStakeRewards.sol
pragma solidity ^0.8.9;
interface IStakeRewards {
function claimReward(bool compound) external;
function depositRewards() external payable;
function getShares(address wallet) external view returns (uint256);
function setShare(
address shareholder,
uint256 balanceUpdate,
bool isRemoving
) external;
}
文件 16 的 29:IUniswapV2Factory.sol
pragma solidity >=0.5.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 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;
}
文件 17 的 29:IUniswapV2Pair.sol
pragma solidity >=0.5.0;
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;
}
文件 18 的 29: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 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);
}
文件 19 的 29:IUniswapV2Router02.sol
pragma solidity >=0.6.2;
import './IUniswapV2Router01.sol';
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;
}
文件 20 的 29:IYDF.sol
pragma solidity ^0.8.9;
import '@openzeppelin/contracts/interfaces/IERC20.sol';
interface IYDF is IERC20 {
function addToBuyTracker(address _user, uint256 _amount) external;
function burn(uint256 _amount) external;
function stakeMintToVester(uint256 _amount) external;
}
文件 21 的 29:IYDFVester.sol
pragma solidity ^0.8.9;
interface IYDFVester {
function createVest(address user, uint256 amount) external;
}
文件 22 的 29:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_transferOwnership(_msgSender());
}
modifier onlyOwner() {
_checkOwner();
_;
}
function owner() public view virtual returns (address) {
return _owner;
}
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 23 的 29:StakeRewards.sol
pragma solidity ^0.8.9;
import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/token/ERC721/IERC721.sol';
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol';
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';
import './interfaces/IStakeRewards.sol';
contract StakeRewards is IStakeRewards, Ownable {
address public ydf;
IERC721 private sYDF;
IERC721 private slYDF;
IUniswapV2Router02 private uniswapV2Router;
uint256 public compoundBuySlippage = 2;
uint256 public totalStakedUsers;
uint256 public totalSharesDeposited;
struct Share {
uint256 amount;
uint256 stakedTime;
}
struct Reward {
uint256 totalExcluded;
uint256 totalRealised;
}
mapping(address => Share) private shares;
mapping(address => Reward) public rewards;
uint256 public totalRewards;
uint256 public totalDistributed;
uint256 public rewardsPerShare;
uint256 private constant ACC_FACTOR = 10**36;
event AddShares(address indexed user, uint256 amount);
event RemoveShares(address indexed user, uint256 amount);
event ClaimReward(address user);
event DistributeReward(address indexed user, uint256 amount);
event DepositRewards(address indexed user, uint256 amountTokens);
modifier onlyToken() {
require(
msg.sender == address(sYDF) || msg.sender == address(slYDF),
'must be stake token'
);
_;
}
constructor(address _ydf, address _dexRouter) {
ydf = _ydf;
uniswapV2Router = IUniswapV2Router02(_dexRouter);
}
function setShare(
address shareholder,
uint256 balanceUpdate,
bool isRemoving
) external override onlyToken {
if (isRemoving) {
_removeShares(shareholder, balanceUpdate);
emit RemoveShares(shareholder, balanceUpdate);
} else {
_addShares(shareholder, balanceUpdate);
emit AddShares(shareholder, balanceUpdate);
}
}
function _addShares(address shareholder, uint256 amount) private {
if (shares[shareholder].amount > 0) {
_distributeReward(shareholder, false);
}
uint256 sharesBefore = shares[shareholder].amount;
totalSharesDeposited += amount;
shares[shareholder].amount += amount;
shares[shareholder].stakedTime = block.timestamp;
if (sharesBefore == 0 && shares[shareholder].amount > 0) {
totalStakedUsers++;
}
rewards[shareholder].totalExcluded = getCumulativeRewards(
shares[shareholder].amount
);
}
function _removeShares(address shareholder, uint256 amount) private {
require(
shares[shareholder].amount > 0 &&
(amount == 0 || amount <= shares[shareholder].amount),
'you can only unstake if you have some staked'
);
_distributeReward(shareholder, false);
uint256 removeAmount = amount == 0 ? shares[shareholder].amount : amount;
totalSharesDeposited -= removeAmount;
shares[shareholder].amount -= removeAmount;
rewards[shareholder].totalExcluded = getCumulativeRewards(
shares[shareholder].amount
);
}
function depositRewards() external payable override {
uint256 _amount = msg.value;
require(_amount > 0, 'must provide ETH to deposit for rewards');
require(totalSharesDeposited > 0, 'must be shares to distribute rewards');
totalRewards += _amount;
rewardsPerShare += (ACC_FACTOR * _amount) / totalSharesDeposited;
emit DepositRewards(msg.sender, _amount);
}
function _distributeReward(address shareholder, bool compound) internal {
if (shares[shareholder].amount == 0) {
return;
}
uint256 amount = getUnpaid(shareholder);
rewards[shareholder].totalRealised += amount;
rewards[shareholder].totalExcluded = getCumulativeRewards(
shares[shareholder].amount
);
if (amount > 0) {
totalDistributed += amount;
uint256 _balBefore = address(this).balance;
if (compound) {
uint256 _tokensToReceiveNoSlip = _getTokensToReceiveOnBuyNoSlippage(
amount
);
address[] memory path = new address[](2);
path[0] = uniswapV2Router.WETH();
path[1] = ydf;
uniswapV2Router.swapExactETHForTokens{ value: amount }(
(_tokensToReceiveNoSlip * (100 - compoundBuySlippage)) / 100,
path,
shareholder,
block.timestamp
);
} else {
payable(shareholder).call{ value: amount }('');
}
require(address(this).balance >= _balBefore - amount, 'took too much');
emit DistributeReward(shareholder, amount);
}
}
function _getTokensToReceiveOnBuyNoSlippage(uint256 _amountETH)
internal
view
returns (uint256)
{
address pairAddy = IUniswapV2Factory(uniswapV2Router.factory()).getPair(
uniswapV2Router.WETH(),
ydf
);
IUniswapV2Pair pair = IUniswapV2Pair(pairAddy);
(uint112 _r0, uint112 _r1, ) = pair.getReserves();
if (pair.token0() == uniswapV2Router.WETH()) {
return (_amountETH * _r1) / _r0;
} else {
return (_amountETH * _r0) / _r1;
}
}
function claimReward(bool _compound) external override {
_distributeReward(msg.sender, _compound);
emit ClaimReward(msg.sender);
}
function getUnpaid(address shareholder) public view returns (uint256) {
if (shares[shareholder].amount == 0) {
return 0;
}
uint256 earnedRewards = getCumulativeRewards(shares[shareholder].amount);
uint256 rewardsExcluded = rewards[shareholder].totalExcluded;
if (earnedRewards <= rewardsExcluded) {
return 0;
}
return earnedRewards - rewardsExcluded;
}
function getCumulativeRewards(uint256 share) internal view returns (uint256) {
return (share * rewardsPerShare) / ACC_FACTOR;
}
function getShares(address user) external view override returns (uint256) {
return shares[user].amount;
}
function getsYDF() external view returns (address) {
return address(sYDF);
}
function getslYDF() external view returns (address) {
return address(slYDF);
}
function setCompoundBuySlippage(uint8 _slippage) external onlyOwner {
require(_slippage <= 100, 'cannot be more than 100% slippage');
compoundBuySlippage = _slippage;
}
function setsYDF(address _sYDF) external onlyOwner {
sYDF = IERC721(_sYDF);
}
function setslYDF(address _slYDF) external onlyOwner {
slYDF = IERC721(_slYDF);
}
}
文件 24 的 29:Strings.sol
pragma solidity ^0.8.0;
library Strings {
bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
function toHexString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0x00";
}
uint256 temp = value;
uint256 length = 0;
while (temp != 0) {
length++;
temp >>= 8;
}
return toHexString(value, length);
}
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _HEX_SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
}
文件 25 的 29:YDF.sol
pragma solidity ^0.8.9;
import '@openzeppelin/contracts/token/ERC20/ERC20.sol';
import '@openzeppelin/contracts/access/Ownable.sol';
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol';
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';
import './interfaces/IYDF.sol';
import './sYDF.sol';
import './slYDF.sol';
import './YDFVester.sol';
import './StakeRewards.sol';
contract YDF is IYDF, ERC20, Ownable {
uint256 private constant EARLY_SELL_EXPIRATION = 90 days;
uint256 private constant SET_AND_LOCK_TAXES = 30 days;
uint256 private constant LAUNCH_MAX_TXN_PERIOD = 30 minutes;
uint256 public taxMarketingPerc = 300;
uint256 public taxRewardsPerc = 200;
uint256 public taxEarlyPerc = 1000;
sYDF private _stakedYDF;
slYDF private _stakedYDFLP;
YDFVester private _vester;
StakeRewards private _rewards;
address public treasury;
uint256 public launchBlock;
uint256 public launchTime;
mapping(address => bool) public isTaxExcluded;
IUniswapV2Router02 public uniswapV2Router;
address public uniswapV2Pair;
mapping(address => bool) public mmPairs;
mapping(address => uint256) public buyTracker;
mapping(address => uint256) public lastBuyTimestamp;
mapping(address => uint256) public sellTracker;
mapping(address => bool) private _isBot;
bool private _swapping = false;
bool private _swapEnabled = true;
modifier onlyStake() {
require(
address(_stakedYDF) == _msgSender() ||
address(_stakedYDFLP) == _msgSender(),
'not a staking contract'
);
_;
}
modifier onlyVest() {
require(address(_vester) == _msgSender(), 'not vesting contract');
_;
}
modifier swapLock() {
_swapping = true;
_;
_swapping = false;
}
event SetMarketMakingPair(address indexed pair, bool isPair);
event SetTreasury(address indexed newTreasury);
event StakeMintToVester(uint256 amount);
event Burn(address indexed user, uint256 amount);
event ResetBuySellMetadata(address indexed user);
event SetTaxExclusion(address indexed user, bool isExcluded);
constructor() ERC20('Yieldification', 'YDF') {
_mint(msg.sender, 696_900_000 * 10**18);
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(
0x1b02dA8Cb0d097eB8D57A175b88c7D8b47997506
);
uniswapV2Pair = IUniswapV2Factory(_uniswapV2Router.factory()).createPair(
address(this),
_uniswapV2Router.WETH()
);
_vester = new YDFVester(address(this));
_rewards = new StakeRewards(address(this), address(_uniswapV2Router));
_stakedYDF = new sYDF(
address(this),
address(_vester),
address(_rewards),
'https://api.yieldification.com/sydf/metadata/'
);
_stakedYDF.setPaymentAddress(msg.sender);
_stakedYDF.setRoyaltyAddress(msg.sender);
_stakedYDF.transferOwnership(msg.sender);
_stakedYDFLP = new slYDF(
uniswapV2Pair,
address(_uniswapV2Router),
address(this),
address(_vester),
address(_rewards),
'https://api.yieldification.com/slydf/metadata/'
);
_stakedYDFLP.setPaymentAddress(msg.sender);
_stakedYDFLP.setRoyaltyAddress(msg.sender);
_stakedYDFLP.transferOwnership(msg.sender);
_vester.addStakingContract(address(_stakedYDF));
_vester.addStakingContract(address(_stakedYDFLP));
_vester.transferOwnership(msg.sender);
_rewards.setsYDF(address(_stakedYDF));
_rewards.setslYDF(address(_stakedYDFLP));
_rewards.transferOwnership(msg.sender);
mmPairs[uniswapV2Pair] = true;
uniswapV2Router = _uniswapV2Router;
treasury = msg.sender;
isTaxExcluded[address(this)] = true;
isTaxExcluded[address(_stakedYDFLP)] = true;
isTaxExcluded[msg.sender] = true;
}
function _transfer(
address sender,
address recipient,
uint256 amount
) internal virtual override {
bool _isBuy = mmPairs[sender] && recipient != address(uniswapV2Router);
bool _isSell = mmPairs[recipient];
if (_isBuy) {
require(launchBlock > 0, 'not launched yet');
buyTracker[recipient] += amount;
lastBuyTimestamp[recipient] = block.timestamp;
} else {
require(!_isBot[recipient], 'sorry bot');
require(!_isBot[sender], 'sorry bot');
require(!_isBot[_msgSender()], 'sorry bot');
}
uint256 contractBalance = balanceOf(address(this));
uint256 _swapAmount = (balanceOf(uniswapV2Pair) * 5) / 1000;
bool _overMinimum = contractBalance >= _swapAmount && _swapAmount > 0;
if (!_swapping && _swapEnabled && _overMinimum && sender != uniswapV2Pair) {
_swapForETH(_swapAmount);
}
uint256 tax = 0;
if (_isSell && !(isTaxExcluded[sender] || isTaxExcluded[recipient])) {
if (
block.timestamp > launchTime + SET_AND_LOCK_TAXES &&
taxMarketingPerc > 100
) {
taxMarketingPerc = 100;
taxRewardsPerc = 100;
taxEarlyPerc = 1300;
}
uint256 _taxEarlyPerc = getSellEarlyTax(sender, amount, taxEarlyPerc);
uint256 _totalTax = taxMarketingPerc + taxRewardsPerc + _taxEarlyPerc;
tax = (amount * _totalTax) / 10000;
if (tax > 0) {
uint256 _taxAmountETH = (tax * (taxMarketingPerc + taxRewardsPerc)) /
_totalTax;
super._transfer(sender, address(this), _taxAmountETH);
if (_taxEarlyPerc > 0) {
_burnWithEvent(sender, tax - _taxAmountETH);
}
}
sellTracker[sender] += amount;
}
super._transfer(sender, recipient, amount - tax);
if (sellTracker[sender] >= buyTracker[sender]) {
_resetBuySellMetadata(sender);
}
if (lastBuyTimestamp[recipient] == 0) {
_resetBuySellMetadata(recipient);
}
}
function _swapForETH(uint256 _amountToSwap) private swapLock {
uint256 _balBefore = address(this).balance;
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = uniswapV2Router.WETH();
_approve(address(this), address(uniswapV2Router), _amountToSwap);
uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
_amountToSwap,
0,
path,
address(this),
block.timestamp
);
uint256 _balToProcess = address(this).balance - _balBefore;
if (_balToProcess > 0) {
uint256 _totalTaxETH = taxMarketingPerc + taxRewardsPerc;
uint256 _marketingETH = (_balToProcess * taxMarketingPerc) / _totalTaxETH;
address _treasury = treasury == address(0) ? owner() : treasury;
if (_marketingETH > 0) {
payable(_treasury).call{ value: _marketingETH }('');
}
uint256 _rewardsETH = _balToProcess - _marketingETH;
if (_rewardsETH > 0) {
if (_rewards.totalSharesDeposited() > 0) {
_rewards.depositRewards{ value: _rewardsETH }();
} else {
payable(_treasury).call{ value: _rewardsETH }('');
}
}
}
}
function getSellEarlyTax(
address _seller,
uint256 _sellAmount,
uint256 _tax
) public view returns (uint256) {
if (lastBuyTimestamp[_seller] == 0) {
return _tax;
}
if (sellTracker[_seller] + _sellAmount > buyTracker[_seller]) {
return _tax;
}
if (block.timestamp > getSellEarlyExpiration(_seller)) {
return 0;
}
uint256 _secondsAfterBuy = block.timestamp - lastBuyTimestamp[_seller];
return
(_tax * (EARLY_SELL_EXPIRATION - _secondsAfterBuy)) /
EARLY_SELL_EXPIRATION;
}
function getSellEarlyExpiration(address _seller)
public
view
returns (uint256)
{
return
lastBuyTimestamp[_seller] == 0
? 0
: lastBuyTimestamp[_seller] + EARLY_SELL_EXPIRATION;
}
function getStakedYDF() external view returns (address) {
return address(_stakedYDF);
}
function getStakedYDFLP() external view returns (address) {
return address(_stakedYDFLP);
}
function getVester() external view returns (address) {
return address(_vester);
}
function getRewards() external view returns (address) {
return address(_rewards);
}
function addToBuyTracker(address _user, uint256 _amount) external onlyVest {
buyTracker[_user] += _amount;
if (lastBuyTimestamp[_user] == 0) {
lastBuyTimestamp[_user] = block.timestamp;
}
}
function resetBuySellMetadata() external {
_resetBuySellMetadata(msg.sender);
emit ResetBuySellMetadata(msg.sender);
}
function _resetBuySellMetadata(address _user) internal {
buyTracker[_user] = balanceOf(_user);
lastBuyTimestamp[_user] = block.timestamp;
sellTracker[_user] = 0;
}
function stakeMintToVester(uint256 _amount) external override onlyStake {
_mint(address(_vester), _amount);
emit StakeMintToVester(_amount);
}
function burn(uint256 _amount) external {
_burnWithEvent(msg.sender, _amount);
}
function _burnWithEvent(address _user, uint256 _amount) internal {
_burn(_user, _amount);
emit Burn(_user, _amount);
}
function setIsTaxExcluded(address _wallet, bool _isExcluded)
external
onlyOwner
{
isTaxExcluded[_wallet] = _isExcluded;
emit SetTaxExclusion(_wallet, _isExcluded);
}
function setMarketMakingPair(address _addy, bool _isPair) external onlyOwner {
require(_addy != uniswapV2Pair, 'cannot change state of built-in pair');
mmPairs[_addy] = _isPair;
emit SetMarketMakingPair(_addy, _isPair);
}
function setSwapEnabled(bool _enabled) external onlyOwner {
_swapEnabled = _enabled;
}
function setTreasury(address _treasury) external onlyOwner {
treasury = _treasury;
emit SetTreasury(_treasury);
}
function startTrading() external onlyOwner {
require(launchBlock == 0, 'already launched');
launchBlock = block.number;
launchTime = block.timestamp;
}
function withdrawETH() external onlyOwner {
payable(owner()).call{ value: address(this).balance }('');
}
receive() external payable {}
}
文件 26 的 29:YDFStake.sol
pragma solidity ^0.8.9;
import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/interfaces/IERC20.sol';
import '@openzeppelin/contracts/token/ERC721/ERC721.sol';
import '@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol';
import '@openzeppelin/contracts/utils/Counters.sol';
import './interfaces/IYDF.sol';
import './interfaces/IYDFVester.sol';
import './interfaces/IStakeRewards.sol';
contract YDFStake is ERC721Enumerable, Ownable {
using Strings for uint256;
using Counters for Counters.Counter;
uint256 private constant ONE_YEAR = 365 days;
uint256 private constant ONE_WEEK = 7 days;
uint16 private constant PERCENT_DENOMENATOR = 10000;
IERC20 internal stakeToken;
IYDF internal ydf;
IYDFVester internal vester;
IStakeRewards internal rewards;
struct AprLock {
uint16 apr;
uint256 lockTime;
}
AprLock[] internal _aprLockOptions;
struct Stake {
uint256 created;
uint256 amountStaked;
uint256 amountYDFBaseEarn;
uint16 apr;
uint256 lockTime;
}
mapping(uint256 => Stake) public stakes;
mapping(uint256 => uint256) public yieldClaimed;
mapping(uint256 => uint256) public lastClaim;
mapping(uint256 => bool) public isBlacklisted;
Counters.Counter internal _ids;
string private baseTokenURI;
address public paymentAddress;
address public royaltyAddress;
uint256 private royaltyBasisPoints = 50;
mapping(address => uint256[]) public allUserOwned;
mapping(uint256 => uint256) public ownedIndex;
mapping(uint256 => uint256) public tokenMintedAt;
mapping(uint256 => uint256) public tokenLastTransferred;
event StakeTokens(
address indexed user,
uint256 indexed tokenId,
uint256 amountStaked,
uint256 lockOptionIndex
);
event UnstakeTokens(address indexed user, uint256 indexed tokenId);
event SetAnnualApr(uint256 indexed newApr);
event SetPaymentAddress(address indexed user);
event SetRoyaltyAddress(address indexed user);
event SetRoyaltyBasisPoints(uint256 indexed _royaltyBasisPoints);
event SetBaseTokenURI(string indexed newUri);
event AddAprLockOption(uint16 indexed apr, uint256 lockTime);
event RemoveAprLockOption(
uint256 indexed index,
uint16 indexed apr,
uint256 lockTime
);
event UpdateAprLockOption(
uint256 indexed index,
uint16 indexed oldApr,
uint256 oldLockTime,
uint16 newApr,
uint256 newLockTime
);
event SetTokenBlacklist(uint256 indexed tokenId, bool isBlacklisted);
constructor(
string memory _name,
string memory _symbol,
address _stakeToken,
address _ydf,
address _vester,
address _rewards,
string memory _baseTokenURI
) ERC721(_name, _symbol) {
stakeToken = IERC20(_stakeToken);
ydf = IYDF(_ydf);
vester = IYDFVester(_vester);
rewards = IStakeRewards(_rewards);
baseTokenURI = _baseTokenURI;
}
function stake(uint256 _amount, uint256 _lockOptIndex) external virtual {
_stake(msg.sender, _amount, _amount, _lockOptIndex, true);
}
function _stake(
address _user,
uint256 _amountStaked,
uint256 _amountYDFBaseEarn,
uint256 _lockOptIndex,
bool _transferStakeToken
) internal {
require(_lockOptIndex < _aprLockOptions.length, 'invalid lock option');
_amountStaked = _amountStaked == 0
? stakeToken.balanceOf(_user)
: _amountStaked;
_amountYDFBaseEarn = _amountYDFBaseEarn == 0
? _amountStaked
: _amountYDFBaseEarn;
require(
_amountStaked > 0 && _amountYDFBaseEarn > 0,
'must stake and be earning at least some tokens'
);
if (_transferStakeToken) {
stakeToken.transferFrom(_user, address(this), _amountStaked);
}
_ids.increment();
stakes[_ids.current()] = Stake({
created: block.timestamp,
amountStaked: _amountStaked,
amountYDFBaseEarn: _amountYDFBaseEarn,
apr: _aprLockOptions[_lockOptIndex].apr,
lockTime: _aprLockOptions[_lockOptIndex].lockTime
});
_safeMint(_user, _ids.current());
tokenMintedAt[_ids.current()] = block.timestamp;
emit StakeTokens(_user, _ids.current(), _amountStaked, _lockOptIndex);
}
function unstake(uint256 _tokenId) public {
address _user = msg.sender;
Stake memory _tokenStake = stakes[_tokenId];
require(
_user == ownerOf(_tokenId),
'only the owner of the staked tokens can unstake'
);
bool _isUnstakingEarly = block.timestamp <
_tokenStake.created + _tokenStake.lockTime;
if (_isUnstakingEarly) {
uint256 _timeStaked = block.timestamp - _tokenStake.created;
uint256 _earnedAmount = (_tokenStake.amountStaked * _timeStaked) /
_tokenStake.lockTime;
stakeToken.transfer(_user, _earnedAmount);
if (address(stakeToken) == address(ydf)) {
ydf.burn(_tokenStake.amountStaked - _earnedAmount);
} else {
stakeToken.transfer(owner(), _tokenStake.amountStaked - _earnedAmount);
}
} else {
stakeToken.transfer(_user, _tokenStake.amountStaked);
}
uint256 _totalEarnedAmount = getTotalEarnedAmount(_tokenId);
if (_totalEarnedAmount > yieldClaimed[_tokenId]) {
_createVestAndMint(_user, _totalEarnedAmount - yieldClaimed[_tokenId]);
}
_burn(_tokenId);
emit UnstakeTokens(_user, _tokenId);
}
function unstakeMulti(uint256[] memory _tokenIds) external {
for (uint256 i = 0; i < _tokenIds.length; i++) {
unstake(_tokenIds[i]);
}
}
function claimAndVestRewards(uint256 _tokenId) public {
require(!isBlacklisted[_tokenId], 'blacklisted NFT');
require(block.timestamp > lastClaim[_tokenId] + ONE_WEEK);
lastClaim[_tokenId] = block.timestamp;
uint256 _totalEarnedAmount = getTotalEarnedAmount(_tokenId);
require(
_totalEarnedAmount > yieldClaimed[_tokenId],
'must have some yield to claim'
);
_createVestAndMint(
ownerOf(_tokenId),
_totalEarnedAmount - yieldClaimed[_tokenId]
);
yieldClaimed[_tokenId] = _totalEarnedAmount;
}
function claimAndVestRewardsMulti(uint256[] memory _tokenIds) external {
for (uint256 i = 0; i < _tokenIds.length; i++) {
claimAndVestRewards(_tokenIds[i]);
}
}
function _createVestAndMint(address _user, uint256 _amount) internal {
vester.createVest(_user, _amount);
ydf.stakeMintToVester(_amount);
}
function royaltyInfo(uint256, uint256 _salePrice)
external
view
returns (address receiver, uint256 royaltyAmount)
{
return (royaltyAddress, (_salePrice * royaltyBasisPoints) / 1000);
}
function tokenURI(uint256 _tokenId)
public
view
virtual
override
returns (string memory)
{
require(_exists(_tokenId), 'token does not exist');
return string(abi.encodePacked(_baseURI(), _tokenId.toString(), '.json'));
}
function contractURI() public view returns (string memory) {
return string(abi.encodePacked(_baseURI(), 'contract.json'));
}
function supportsInterface(bytes4 _interfaceId)
public
view
virtual
override(ERC721Enumerable)
returns (bool)
{
return super.supportsInterface(_interfaceId);
}
function getLastMintedTokenId() external view returns (uint256) {
return _ids.current();
}
function isTokenMinted(uint256 _tokenId) external view returns (bool) {
return _exists(_tokenId);
}
function setPaymentAddress(address _address) external onlyOwner {
paymentAddress = _address;
emit SetPaymentAddress(_address);
}
function setRoyaltyAddress(address _address) external onlyOwner {
royaltyAddress = _address;
emit SetRoyaltyAddress(_address);
}
function setRoyaltyBasisPoints(uint256 _points) external onlyOwner {
royaltyBasisPoints = _points;
emit SetRoyaltyBasisPoints(_points);
}
function setBaseURI(string memory _uri) external onlyOwner {
baseTokenURI = _uri;
emit SetBaseTokenURI(_uri);
}
function getAllUserOwned(address _user)
external
view
returns (uint256[] memory)
{
return allUserOwned[_user];
}
function getTotalEarnedAmount(uint256 _tokenId)
public
view
returns (uint256)
{
Stake memory _tokenStake = stakes[_tokenId];
uint256 _secondsStaked = block.timestamp - _tokenStake.created;
return
(_tokenStake.amountYDFBaseEarn * _tokenStake.apr * _secondsStaked) /
PERCENT_DENOMENATOR /
ONE_YEAR;
}
function getAllLockOptions() external view returns (AprLock[] memory) {
return _aprLockOptions;
}
function addAprLockOption(uint16 _apr, uint256 _lockTime) external onlyOwner {
_addAprLockOption(_apr, _lockTime);
emit AddAprLockOption(_apr, _lockTime);
}
function _addAprLockOption(uint16 _apr, uint256 _lockTime) internal {
_aprLockOptions.push(AprLock({ apr: _apr, lockTime: _lockTime }));
}
function removeAprLockOption(uint256 _index) external onlyOwner {
AprLock memory _option = _aprLockOptions[_index];
_aprLockOptions[_index] = _aprLockOptions[_aprLockOptions.length - 1];
_aprLockOptions.pop();
emit RemoveAprLockOption(_index, _option.apr, _option.lockTime);
}
function updateAprLockOption(
uint256 _index,
uint16 _apr,
uint256 _lockTime
) external onlyOwner {
AprLock memory _option = _aprLockOptions[_index];
_aprLockOptions[_index] = AprLock({ apr: _apr, lockTime: _lockTime });
emit UpdateAprLockOption(
_index,
_option.apr,
_option.lockTime,
_apr,
_lockTime
);
}
function setIsBlacklisted(uint256 _tokenId, bool _isBlacklisted)
external
onlyOwner
{
isBlacklisted[_tokenId] = _isBlacklisted;
emit SetTokenBlacklist(_tokenId, _isBlacklisted);
}
function _baseURI() internal view override returns (string memory) {
return baseTokenURI;
}
function _beforeTokenTransfer(
address _from,
address _to,
uint256 _tokenId
) internal virtual override(ERC721Enumerable) {
require(!isBlacklisted[_tokenId], 'blacklisted NFT');
tokenLastTransferred[_tokenId] = block.timestamp;
super._beforeTokenTransfer(_from, _to, _tokenId);
}
function _afterTokenTransfer(
address _from,
address _to,
uint256 _tokenId
) internal virtual override(ERC721) {
Stake memory _tokenStake = stakes[_tokenId];
if (_from != address(0)) {
uint256 _currIndex = ownedIndex[_tokenId];
uint256 _tokenIdMovingIndices = allUserOwned[_from][
allUserOwned[_from].length - 1
];
allUserOwned[_from][_currIndex] = allUserOwned[_from][
allUserOwned[_from].length - 1
];
allUserOwned[_from].pop();
ownedIndex[_tokenIdMovingIndices] = _currIndex;
rewards.setShare(_from, _tokenStake.amountYDFBaseEarn, true);
}
if (_to != address(0)) {
ownedIndex[_tokenId] = allUserOwned[_to].length;
allUserOwned[_to].push(_tokenId);
rewards.setShare(_to, _tokenStake.amountYDFBaseEarn, false);
}
super._afterTokenTransfer(_from, _to, _tokenId);
}
}
文件 27 的 29:YDFVester.sol
pragma solidity ^0.8.9;
import '@openzeppelin/contracts/access/Ownable.sol';
import './interfaces/IYDF.sol';
contract YDFVester is Ownable {
IYDF private _ydf;
uint256 public fullyVestedPeriod = 90 days;
uint256 public withdrawsPerPeriod = 10;
struct TokenVest {
uint256 start;
uint256 end;
uint256 totalWithdraws;
uint256 withdrawsCompleted;
uint256 amount;
}
mapping(address => TokenVest[]) public vests;
address[] public stakeContracts;
event CreateVest(address indexed user, uint256 amount);
event Withdraw(address indexed user, uint256 index, uint256 amountWithdrawn);
modifier onlyStake() {
bool isStake;
for (uint256 i = 0; i < stakeContracts.length; i++) {
if (msg.sender == stakeContracts[i]) {
isStake = true;
break;
}
}
require(isStake, 'not a staking contract');
_;
}
constructor(address _token) {
_ydf = IYDF(_token);
}
function createVest(address _user, uint256 _amount) external onlyStake {
vests[_user].push(
TokenVest({
start: block.timestamp,
end: block.timestamp + fullyVestedPeriod,
totalWithdraws: withdrawsPerPeriod,
withdrawsCompleted: 0,
amount: _amount
})
);
emit CreateVest(_user, _amount);
}
function withdraw(uint256 _index) external {
address _user = msg.sender;
TokenVest storage _vest = vests[_user][_index];
require(_vest.amount > 0, 'vest does not exist');
require(
_vest.withdrawsCompleted < _vest.totalWithdraws,
'already withdrew all tokens'
);
uint256 _tokensPerWithdrawPeriod = _vest.amount / _vest.totalWithdraws;
uint256 _withdrawsAllowed = getWithdrawsAllowed(_user, _index);
_withdrawsAllowed = _withdrawsAllowed > _vest.totalWithdraws
? _vest.totalWithdraws
: _withdrawsAllowed;
require(
_vest.withdrawsCompleted < _withdrawsAllowed,
'currently vesting, please wait for next withdrawable time period'
);
uint256 _withdrawsToComplete = _withdrawsAllowed - _vest.withdrawsCompleted;
_vest.withdrawsCompleted = _withdrawsAllowed;
_ydf.transfer(_user, _tokensPerWithdrawPeriod * _withdrawsToComplete);
_ydf.addToBuyTracker(
_user,
_tokensPerWithdrawPeriod * _withdrawsToComplete
);
if (_vest.withdrawsCompleted == _vest.totalWithdraws) {
vests[_user][_index] = vests[_user][vests[_user].length - 1];
vests[_user].pop();
}
emit Withdraw(
_user,
_index,
_tokensPerWithdrawPeriod * _withdrawsToComplete
);
}
function getWithdrawsAllowed(address _user, uint256 _index)
public
view
returns (uint256)
{
TokenVest memory _vest = vests[_user][_index];
uint256 _secondsPerWithdrawPeriod = (_vest.end - _vest.start) /
_vest.totalWithdraws;
return (block.timestamp - _vest.start) / _secondsPerWithdrawPeriod;
}
function getUserVests(address _user)
external
view
returns (TokenVest[] memory)
{
return vests[_user];
}
function getYDF() external view returns (address) {
return address(_ydf);
}
function addStakingContract(address _contract) external onlyOwner {
stakeContracts.push(_contract);
}
}
文件 28 的 29:sYDF.sol
pragma solidity ^0.8.9;
import './YDFStake.sol';
contract sYDF is YDFStake {
constructor(
address _ydf,
address _vester,
address _rewards,
string memory _baseTokenURI
)
YDFStake(
'Staked Yieldification',
'sYDF',
_ydf,
_ydf,
_vester,
_rewards,
_baseTokenURI
)
{
_addAprLockOption(2500, 0);
_addAprLockOption(5000, 14 days);
_addAprLockOption(10000, 120 days);
_addAprLockOption(15000, 240 days);
_addAprLockOption(20000, 360 days);
}
}
文件 29 的 29:slYDF.sol
pragma solidity ^0.8.9;
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';
import '@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol';
import './YDFStake.sol';
contract slYDF is YDFStake {
address private _uniswapRouter;
uint8 public zapBuySlippage = 2;
uint8 public zapSellSlippage = 25;
event StakeLiquidity(address indexed user, uint256 amountUniLPStaked);
event ZapETHOnly(
address indexed user,
uint256 amountETH,
uint256 amountUniLPStaked
);
event ZapYDFOnly(
address indexed user,
uint256 amountYDF,
uint256 amountUniLPStaked
);
event ZapETHAndYDF(
address indexed user,
uint256 amountETH,
uint256 amountYDF,
uint256 amountUniLPStaked
);
constructor(
address _pair,
address _router,
address _ydf,
address _vester,
address _rewards,
string memory _baseTokenURI
)
YDFStake(
'Staked Yieldification Liquidity',
'slYDF',
_pair,
_ydf,
_vester,
_rewards,
_baseTokenURI
)
{
_uniswapRouter = _router;
_addAprLockOption(5000, 0);
_addAprLockOption(7500, 14 days);
_addAprLockOption(15000, 120 days);
_addAprLockOption(22500, 240 days);
_addAprLockOption(30000, 360 days);
}
function stake(uint256 _amount, uint256 _lockOptIndex) external override {
_stakeLp(msg.sender, _amount, _lockOptIndex, true);
emit StakeLiquidity(msg.sender, _amount);
}
function zapAndStakeETHOnly(uint256 _lockOptIndex) external payable {
require(msg.value > 0, 'need to provide ETH to zap');
uint256 _ethBalBefore = address(this).balance - msg.value;
uint256 _ydfBalanceBefore = ydf.balanceOf(address(this));
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(_uniswapRouter);
uint256 _tokensToReceiveNoSlip = _getTokensToReceiveOnBuyNoSlippage(
msg.value / 2
);
address[] memory path = new address[](2);
path[0] = _uniswapV2Router.WETH();
path[1] = address(ydf);
_uniswapV2Router.swapExactETHForTokens{ value: msg.value / 2 }(
(_tokensToReceiveNoSlip * (100 - zapBuySlippage)) / 100,
path,
address(this),
block.timestamp
);
uint256 _lpBalBefore = stakeToken.balanceOf(address(this));
_addLp(ydf.balanceOf(address(this)) - _ydfBalanceBefore, msg.value / 2);
uint256 _lpBalanceToStake = stakeToken.balanceOf(address(this)) -
_lpBalBefore;
_stakeLp(msg.sender, _lpBalanceToStake, _lockOptIndex, false);
_returnExcessETH(msg.sender, _ethBalBefore);
_returnExcessYDF(msg.sender, _ydfBalanceBefore);
emit ZapETHOnly(msg.sender, msg.value, _lpBalanceToStake);
}
function zapAndStakeETHAndYDF(uint256 _amountYDF, uint256 _lockOptIndex)
external
payable
{
require(msg.value > 0, 'need to provide ETH to zap');
uint256 _ethBalBefore = address(this).balance - msg.value;
uint256 _ydfBalBefore = ydf.balanceOf(address(this));
ydf.transferFrom(msg.sender, address(this), _amountYDF);
uint256 _ydfToProcess = ydf.balanceOf(address(this)) - _ydfBalBefore;
uint256 _lpBalBefore = stakeToken.balanceOf(address(this));
_addLp(_ydfToProcess, msg.value);
uint256 _lpBalanceToStake = stakeToken.balanceOf(address(this)) -
_lpBalBefore;
_stakeLp(msg.sender, _lpBalanceToStake, _lockOptIndex, false);
_returnExcessETH(msg.sender, _ethBalBefore);
_returnExcessYDF(msg.sender, _ydfBalBefore);
emit ZapETHAndYDF(msg.sender, msg.value, _amountYDF, _lpBalanceToStake);
}
function zapAndStakeYDFOnly(uint256 _amountYDF, uint256 _lockOptIndex)
external
{
require(
_aprLockOptions[_lockOptIndex].lockTime > 0,
'cannot zap and stake YDF only without lockup period'
);
uint256 _ethBalBefore = address(this).balance;
uint256 _ydfBalBefore = ydf.balanceOf(address(this));
ydf.transferFrom(msg.sender, address(this), _amountYDF);
uint256 _ydfToProcess = ydf.balanceOf(address(this)) - _ydfBalBefore;
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(_uniswapRouter);
uint256 _ethToReceiveNoSlip = _getETHToReceiveOnSellNoSlippage(
_ydfToProcess / 2
);
address[] memory path = new address[](2);
path[0] = address(ydf);
path[1] = _uniswapV2Router.WETH();
ydf.approve(address(_uniswapV2Router), _ydfToProcess / 2);
_uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(
_ydfToProcess / 2,
(_ethToReceiveNoSlip * (100 - zapSellSlippage)) / 100,
path,
address(this),
block.timestamp
);
uint256 _lpBalBefore = stakeToken.balanceOf(address(this));
_addLp(_ydfToProcess / 2, address(this).balance - _ethBalBefore);
uint256 _lpBalanceToStake = stakeToken.balanceOf(address(this)) -
_lpBalBefore;
_stakeLp(msg.sender, _lpBalanceToStake, _lockOptIndex, false);
_returnExcessETH(msg.sender, _ethBalBefore);
_returnExcessYDF(msg.sender, _ydfBalBefore);
emit ZapYDFOnly(msg.sender, _amountYDF, _lpBalanceToStake);
}
function _addLp(uint256 tokenAmount, uint256 ethAmount) private {
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(_uniswapRouter);
ydf.approve(address(_uniswapV2Router), tokenAmount);
_uniswapV2Router.addLiquidityETH{ value: ethAmount }(
address(ydf),
tokenAmount,
0,
0,
address(this),
block.timestamp
);
}
function _getTokensToReceiveOnBuyNoSlippage(uint256 _amountETH)
internal
view
returns (uint256)
{
IUniswapV2Pair pair = IUniswapV2Pair(address(stakeToken));
(uint112 _r0, uint112 _r1, ) = pair.getReserves();
if (pair.token0() == IUniswapV2Router02(_uniswapRouter).WETH()) {
return (_amountETH * _r1) / _r0;
} else {
return (_amountETH * _r0) / _r1;
}
}
function _getETHToReceiveOnSellNoSlippage(uint256 _amountYDF)
internal
view
returns (uint256)
{
IUniswapV2Pair pair = IUniswapV2Pair(address(stakeToken));
(uint112 _r0, uint112 _r1, ) = pair.getReserves();
if (pair.token0() == IUniswapV2Router02(_uniswapRouter).WETH()) {
return (_amountYDF * _r0) / _r1;
} else {
return (_amountYDF * _r1) / _r0;
}
}
function _stakeLp(
address _user,
uint256 _amountStakeToken,
uint256 _lockOptIndex,
bool _transferStakeToken
) internal {
IUniswapV2Pair pair = IUniswapV2Pair(address(stakeToken));
_amountStakeToken = _amountStakeToken == 0
? pair.balanceOf(_user)
: _amountStakeToken;
(uint112 res0, uint112 res1, ) = pair.getReserves();
address t0 = pair.token0();
uint256 ydfReserves = t0 == address(ydf) ? res0 : res1;
uint256 singleSideTokenAmount = (_amountStakeToken * ydfReserves) /
stakeToken.totalSupply();
_stake(
_user,
_amountStakeToken,
singleSideTokenAmount * 2,
_lockOptIndex,
_transferStakeToken
);
}
function _returnExcessETH(address _user, uint256 _initialBal) internal {
if (address(this).balance > _initialBal) {
payable(_user).call{ value: address(this).balance - _initialBal }('');
require(address(this).balance >= _initialBal, 'took too much');
}
}
function _returnExcessYDF(address _user, uint256 _initialBal) internal {
uint256 _currentBal = ydf.balanceOf(address(this));
if (_currentBal > _initialBal) {
ydf.transfer(_user, _currentBal - _initialBal);
require(ydf.balanceOf(address(this)) >= _initialBal, 'took too much');
}
}
function setZapBuySlippage(uint8 _slippage) external onlyOwner {
require(_slippage <= 100, 'cannot be more than 100% slippage');
zapBuySlippage = _slippage;
}
function setZapSellSlippage(uint8 _slippage) external onlyOwner {
require(_slippage <= 100, 'cannot be more than 100% slippage');
zapSellSlippage = _slippage;
}
receive() external payable {}
}
{
"compilationTarget": {
"contracts/YDF.sol": "YDF"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "none"
},
"optimizer": {
"enabled": true,
"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":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"ResetBuySellMetadata","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"bool","name":"isPair","type":"bool"}],"name":"SetMarketMakingPair","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"SetTaxExclusion","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newTreasury","type":"address"}],"name":"SetTreasury","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"StakeMintToVester","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":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"addToBuyTracker","outputs":[],"stateMutability":"nonpayable","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":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"buyTracker","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRewards","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_seller","type":"address"}],"name":"getSellEarlyExpiration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_seller","type":"address"},{"internalType":"uint256","name":"_sellAmount","type":"uint256"},{"internalType":"uint256","name":"_tax","type":"uint256"}],"name":"getSellEarlyTax","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakedYDF","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getStakedYDFLP","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getVester","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isTaxExcluded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lastBuyTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"launchTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"mmPairs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"resetBuySellMetadata","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"sellTracker","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"},{"internalType":"bool","name":"_isExcluded","type":"bool"}],"name":"setIsTaxExcluded","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_addy","type":"address"},{"internalType":"bool","name":"_isPair","type":"bool"}],"name":"setMarketMakingPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_enabled","type":"bool"}],"name":"setSwapEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeMintToVester","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxEarlyPerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxMarketingPerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxRewardsPerc","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV2Pair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uniswapV2Router","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]