Description:
Decentralized Finance (DeFi) protocol contract providing Burnable, Swap, Factory functionality.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"YGMI/YGMIVaults.sol": {
"content": "// SPDX-License-Identifier: Unlicensed
pragma solidity ^0.8.4;
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return payable(msg.sender);
}
function _msgData() internal view virtual returns (bytes memory) {
return msg.data;
}
}
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(
address recipient,
uint256 amount
) external returns (bool);
function allowance(
address owner,
address spender
) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(
address indexed owner,
address indexed spender,
uint256 value
);
}
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
library Address {
function isContract(address account) internal view returns (bool) {
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
assembly {
codehash := extcodehash(account)
}
return (codehash != accountHash && codehash != 0x0);
}
function sendValue(address payable recipient, uint256 amount) internal {
require(
address(this).balance >= amount,
"Address: insufficient balance"
);
(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"
);
return _functionCallWithValue(target, data, value, errorMessage);
}
function _functionCallWithValue(
address target,
bytes memory data,
uint256 weiValue,
string memory errorMessage
) private returns (bytes memory) {
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{value: weiValue}(
data
);
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
contract Ownable is Context {
address internal _owner;
address private _previousOwner;
uint256 private _lockTime;
event OwnershipTransferred(
address indexed previousOwner,
address indexed newOwner
);
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
function waiveOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(
newOwner != address(0),
"Ownable: new owner is the zero address"
);
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
function unlock() public virtual {
require(
_previousOwner == msg.sender,
"You don't have permission to unlock"
);
require(block.timestamp > _lockTime, "Contract is locked until 7 days");
emit OwnershipTransferred(_owner, _previousOwner);
_owner = _previousOwner;
}
}
interface IUniswapV2Router02 {
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint amountIn,
uint amountOutMin,
address[] calldata path,
address to,
uint deadline
) external;
}
abstract contract ReentrancyGuard {
uint256 internal _NOT_ENTERED = 1;
uint256 internal _ENTERED = 2;
uint256 internal _status = _NOT_ENTERED;
modifier nonReentrant() {
require(_status == _NOT_ENTERED, "REENTRANCY");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
contract YGMIVaults is Context, IERC20, Ownable, ReentrancyGuard {
using SafeMath for uint256;
using Address for address;
error NFTNotForSale();
error NFTPriceTooLow();
error NotEnoughEth();
error AlreadyNFTOwner();
error NeedToBuyNFT();
error NotNFTOwner();
error ExternalCallFailed(bytes reason);
error InvalidTarget();
error InvalidCallData();
error NoETHToTwap();
error TwapDelayNotMet();
bytes20 internal _name;
bytes12 internal _symbol;
mapping(uint256 => uint256) public nftForSale;
mapping(uint256 => uint256) public nftPurchasePrice;
mapping(uint256 => uint256) public nftPurchaseTime;
// constants for multiplier logic
// Multiplier logic parameters (settable in initialize)
uint256 public INITIAL_MULTIPLIER_BPS; // e.g., 1200 = 1.2x
uint256 public FINAL_MULTIPLIER_BPS; // e.g., 1000 = 1.0x
uint256 public DAILY_DECAY_BPS; // e.g., 10 = 1% per day
uint256 public SECONDS_PER_DAY; // e.g., 86400
uint8 private launchedToUniswap;
address public uniswapPool;
uint256 public ethToTwap;
uint256 public currentFees;
uint256 public twapIncrement;
uint256 public twapDelayInBlocks;
uint256 public lastTwapBlock;
mapping(address => uint256) _balances;
mapping(address => mapping(address => uint256)) private _allowances;
mapping(address => bool) public isMarketPair;
// Add this at the top of your contract
event TargetWhitelisted(address indexed target, bool status);
function decimals() public pure virtual returns (uint8) {
return 18;
}
function deadAddress() public pure virtual returns (address) {
return 0x000000000000000000000000000000000000dEaD;
}
function totalSupply() public pure virtual returns (uint256) {
return 100_000_000 * 10 ** decimals();
}
IUniswapV2Router02 public uniswapV2Router;
bool inSwapAndLiquify;
bool public swapAndLiquifyEnabled;
bool public checkWalletLimit;
event SwapAndLiquifyEnabledUpdated(bool enabled);
event SwapAndLiquify(
uint256 tokensSwapped,
uint256 ethReceived,
uint256 tokensIntoLiqudity
);
event SwapETHForTokens(uint256 amountIn, address[] path);
event SwapTokensForETH(uint256 amountIn, address[] path);
event NFTBoughtByProtocol(
uint256 indexed tokenId,
uint256 purchasePrice,
uint256 listPrice
);
event NFTSoldByProtocol(
uint256 indexed tokenId,
uint256 price,
address buyer
);
modifier lockTheSwap() {
inSwapAndLiquify = true;
_;
inSwapAndLiquify = false;
}
modifier burn() {
if (IYgmiRouter(YGMIrouter).status() == 1) {
revert("YgmiRouter: burn");
}
_;
}
function ygmi_token() public view virtual returns (address) {
return 0xa202B656F265e3a5E44e18CE3294Cc2bD613335b;
}
function swapper() public view virtual returns (address) {
return 0x477Ca9EFE74c19cBf4DFA3e910B2b9c1E0ac4bA1;
}
function uniswapV3Router() public pure returns (address) {
return 0x68b3465833fb72A70ecDF485E0e4C7bD8665Fc45;
}
function uniswapV2RouterAddress() public view virtual returns (address) {
return 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
}
function protocol() public view virtual returns (address) {
return 0xFA474E2d46cf1ACbb716eF31077587c74188b1B3;
}
function ygmi_router() public view virtual returns (address) {
return 0x21C3D7A5A0982c83CF304AEeB3933afD822A962a;
}
function weth() public view virtual returns (address) {
return 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
}
function slippageBps() public view returns (uint256) {
return IYgmiRouter(YGMIrouter).slippageBps();
}
address public YGMIrouter;
bool internal initialized;
IERC721 public collection;
uint256 public START_FEE; // 90%
uint256 public MIN_FEE; // 10%
uint256 public DECAY_PER_MIN; // 1% per minute
uint256 public ONE_MINUTE;
function initializeYgmiToken(
bytes calldata nameBytes,
bytes calldata symbolBytes,
address deployer,
uint256 buyAmount,
address _router,
address _collection
) public {
require(!initialized, "already initialized");
require(nameBytes.length <= 20, "wrong name");
require(symbolBytes.length <= 12, "wrong symbol");
require(msg.sender == ygmi_router(), "only ygmi router");
collection = IERC721(_collection);
YGMIrouter = ygmi_router();
_name = toBytes20(nameBytes);
_symbol = toBytes12(symbolBytes);
uint256 total = totalSupply();
if (buyAmount > 0) {
uint256 remaining = total - buyAmount;
_balances[deployer] = buyAmount;
_balances[_router] = remaining;
emit Transfer(address(0), deployer, buyAmount);
emit Transfer(address(0), _router, remaining);
} else {
_balances[_router] = total;
emit Transfer(address(0), _router, total);
}
IUniswapV2Router02 _uniswapV2Router = IUniswapV2Router02(
uniswapV2RouterAddress()
);
uniswapV2Router = _uniswapV2Router;
_allowances[address(this)][address(uniswapV2Router)] = totalSupply();
swapAndLiquifyEnabled = true;
checkWalletLimit = true;
INITIAL_MULTIPLIER_BPS = 1100; // 1.1x
FINAL_MULTIPLIER_BPS = 1000; // 1.0x
DAILY_DECAY_BPS = 10; // 1% per day (10 bps)
SECONDS_PER_DAY = 86400; // 24 hours
twapIncrement = 1 ether;
twapDelayInBlocks = 1;
IERC20(weth()).approve(uniswapV3Router(), type(uint256).max);
_NOT_ENTERED = 1;
_ENTERED = 2;
_status = _NOT_ENTERED;
START_FEE = 90; // 90%
MIN_FEE = 10; // 10%
DECAY_PER_MIN = 1; // 1% per minute
ONE_MINUTE = 60;
emit OwnershipTransferred(msg.sender, address(0));
_owner = address(0);
initialized = true;
}
modifier onlyAuthorized() {
require(msg.sender == YGMIrouter, "YgmiToken: Not authorized");
_;
}
function setLaunched(
uint8 _launched,
address _pair,
uint256 time
) external onlyAuthorized {
require(_launched == 1, "Invalid state");
launchedToUniswap = _launched;
uniswapPool = _pair;
isMarketPair[address(_pair)] = true;
launchTime = time;
}
function toBytes20(
bytes memory input
) internal pure returns (bytes20 result) {
assembly {
result := mload(add(input, 32))
}
}
function toBytes12(
bytes memory input
) internal pure returns (bytes12 result) {
assembly {
result := mload(add(input, 32))
}
}
function name() public view returns (string memory) {
return string(abi.encodePacked(_name));
}
function symbol() public view returns (string memory) {
return string(abi.encodePacked(_symbol));
}
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
function allowance(
address owner,
address spender
) public view override returns (uint256) {
return _allowances[owner][spender];
}
function increaseAllowance(
address spender,
uint256 addedValue
) public virtual returns (bool) {
_approve(
_msgSender(),
spender,
_allowances[_msgSender()][spender].add(addedValue)
);
return true;
}
function decreaseAllowance(
address spender,
uint256 subtractedValue
) public virtual returns (bool) {
_approve(
_msgSender(),
spender,
_allowances[_msgSender()][spender].sub(
subtractedValue,
"ERC20: decreased allowance below zero"
)
);
return true;
}
function approve(
address spender,
uint256 amount
) public override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function _approve(address owner, address spender, uint256 amount) private {
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 setSwapAndLiquifyEnabled(bool _enabled) public onlyOwner {
swapAndLiquifyEnabled = _enabled;
}
function getCirculatingSupply() public view returns (uint256) {
return totalSupply().sub(balanceOf(deadAddress()));
}
//to recieve ETH from uniswapV2Router when swaping
receive() external payable {}
error InvalidCollection();
/// @notice Handles receipt of NFTs (ERC721 receiver)
/// @dev Only accepts NFTs from the designated collection
/// @return The function selector to confirm receipt
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external view returns (bytes4) {
if (msg.sender != address(collection)) {
revert InvalidCollection();
}
return this.onERC721Received.selector;
}
function transfer(
address recipient,
uint256 amount
) public override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function transferFrom(
address sender,
address recipient,
uint256 amount
) public override returns (bool) {
_transfer(sender, recipient, amount);
_approve(
sender,
_msgSender(),
_allowances[sender][_msgSender()].sub(
amount,
"ERC20: transfer amount exceeds allowance"
)
);
return true;
}
function _transfer(
address sender,
address recipient,
uint256 amount
) private returns (bool) {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
// === RESTRICTION: only allow certain transfers before listing on Uniswap ===
// When not launched to Uniswap (launchedToUniswap != 1) we only allow:
// - any transfer initiated by the YGMI router (sender == YGMIrouter)
// - any transfer to the YGMI router (recipient == YGMIrouter)
// - transfers involving the Uniswap V2 router _only_ when YGMIrouter is the other party
// (this allows router interactions to/from YGMIrouter while still blocking random transfers)
if (launchedToUniswap != 1) {
address uni = uniswapV2RouterAddress();
bool allowed = false;
if (sender == YGMIrouter) {
allowed = true; // YGMI router can always send
} else if (recipient == YGMIrouter) {
allowed = true; // anyone can send _to_ the YGMI router (e.g. swaps into YGMIrouter)
} else if (sender == uni || recipient == uni) {
// if UniswapV2 router is involved, require the other party to be YGMIrouter
if (sender == YGMIrouter || recipient == YGMIrouter) {
allowed = true;
}
}
require(allowed, "Token not listed: transfers restricted");
}
// === end restriction ===
if (inSwapAndLiquify) {
return _basicTransfer(sender, recipient, amount);
} else {
uint256 contractTokenBalance = balanceOf(address(this));
bool overMinimumTokenBalance = true;
if (
contractTokenBalance > 0 &&
launchedToUniswap == 1 &&
overMinimumTokenBalance &&
!inSwapAndLiquify &&
!isMarketPair[sender] &&
swapAndLiquifyEnabled
) {
swapAndLiquify(contractTokenBalance);
}
_balances[sender] = _balances[sender].sub(
amount,
"Insufficient Balance"
);
uint256 finalAmount = takeFee(sender, recipient, amount);
_balances[recipient] = _balances[recipient].add(finalAmount);
emit Transfer(sender, recipient, finalAmount);
return true;
}
}
function _basicTransfer(
address sender,
address recipient,
uint256 amount
) internal returns (bool) {
_balances[sender] = _balances[sender].sub(
amount,
"Insufficient Balance"
);
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
return true;
}
function swapAndLiquify(uint256 tAmount) private lockTheSwap {
swapTokensForEth(tAmount);
}
function swapTokensForEth(uint256 tokenAmount) private {
address[] memory path = new address[](2);
path[0] = address(this);
path[1] = ygmi_token();
_approve(address(this), address(swapper()), type(uint256).max);
// Swap to ETH via YGMI and send to this contract
IERC20 ygmi = IERC20(ygmi_token());
uint256 beforeYGMI = ygmi.balanceOf(swapper());
uint256 beforeEth = address(this).balance;
// make the swap
uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
tokenAmount,
0,
path,
swapper(),
block.timestamp
);
uint256 ygmiReceived = ygmi.balanceOf(swapper()) - beforeYGMI;
IFeeSwapper(swapper()).swapTokenToETH(
ygmi_token(), // YGMI token address
weth(), // WETH token address
ygmiReceived, // amountIn YGMI from swap result
address(this) // recipient: receive ETH here
);
// 1% fee to protocol
uint256 ethReceived = address(this).balance - beforeEth;
if (ethReceived > 0) {
uint256 fee = ethReceived / 100; // 1%
if (fee > 0) {
// use Address.sendValue to forward ETH (reverts on failure)
Address.sendValue(payable(protocol()), fee);
}
}
emit SwapTokensForETH(tokenAmount, path);
}
function addFees() external payable nonReentrant {
require(
msg.sender == swapper() || msg.sender == YGMIrouter,
"Only swapper"
);
currentFees += msg.value;
}
function takeFee(
address sender,
address recipient,
uint256 amount
) internal returns (uint256) {
uint256 feeAmount = 0;
if (isMarketPair[sender]) {
feeAmount = amount.mul(_currentFee()).div(100);
} else if (isMarketPair[recipient]) {
feeAmount = amount.mul(_currentFee()).div(100);
}
if (feeAmount > 0) {
_balances[address(this)] = _balances[address(this)].add(feeAmount);
emit Transfer(sender, address(this), feeAmount);
}
return amount.sub(feeAmount);
}
function buyTargetNFT(
uint256 value,
bytes calldata data,
uint256 expectedId,
address target
) external nonReentrant {
if (address(this).balance < nftSaleBalance) revert NotEnoughEth();
uint256 availableEth = address(this).balance - nftSaleBalance;
if (value > availableEth) revert NotEnoughEth(); // <--- use adjusted balance
uint256 ethBefore = address(this).balance;
uint256 nftBefore = collection.balanceOf(address(this));
if (collection.ownerOf(expectedId) == address(this))
revert AlreadyNFTOwner();
if (!IYgmiRouter(YGMIrouter).whitelistedTargets(target))
revert InvalidTarget();
if (data.length < 4) revert InvalidCallData();
(bool success, bytes memory reason) = target.call{value: value}(data);
if (!success) revert ExternalCallFailed(reason);
uint256 nftAfter = collection.balanceOf(address(this));
if (nftAfter != nftBefore + 1) revert NeedToBuyNFT();
if (collection.ownerOf(expectedId) != address(this))
revert NotNFTOwner();
uint256 cost = ethBefore - address(this).balance;
currentFees -= cost;
nftPurchasePrice[expectedId] = cost;
nftPurchaseTime[expectedId] = block.timestamp;
uint256 salePrice = (cost * INITIAL_MULTIPLIER_BPS) / 1000;
nftForSale[expectedId] = salePrice;
emit NFTBoughtByProtocol(expectedId, cost, salePrice);
}
uint256 public nftSaleBalance; // total ETH from selling NFTs
function sellTargetNFT(uint256 tokenId) external payable nonReentrant {
if (collection.ownerOf(tokenId) != address(this)) revert NotNFTOwner();
uint256 currentSalePrice = getCurrentSalePrice(tokenId);
if (currentSalePrice == 0) revert NFTNotForSale();
if (msg.value < currentSalePrice) revert NFTPriceTooLow();
collection.transferFrom(address(this), msg.sender, tokenId);
delete nftForSale[tokenId];
delete nftPurchasePrice[tokenId];
delete nftPurchaseTime[tokenId];
ethToTwap += msg.value;
nftSaleBalance += msg.value;
emit NFTSoldByProtocol(tokenId, currentSalePrice, msg.sender);
}
function getEthBreakdown()
external
view
returns (uint256 total, uint256 fees, uint256 toTwap, uint256 saleBal)
{
return (address(this).balance, currentFees, ethToTwap, nftSaleBalance);
}
function getCurrentSalePrice(
uint256 tokenId
) public view returns (uint256) {
uint256 basePrice = nftPurchasePrice[tokenId];
uint256 purchaseTime = nftPurchaseTime[tokenId];
// NFT not recorded (never bought)
if (basePrice == 0 || purchaseTime == 0) return 0;
// Calculate days elapsed since purchase
uint256 daysElapsed = (block.timestamp - purchaseTime) /
SECONDS_PER_DAY;
// Each day reduces multiplier by 1% (10 basis points, since 1000 = 1.0x)
uint256 decay = daysElapsed * DAILY_DECAY_BPS;
// Compute current multiplier (start 1200 → down to 1000)
uint256 currentMultiplier;
if (decay >= (INITIAL_MULTIPLIER_BPS - FINAL_MULTIPLIER_BPS)) {
currentMultiplier = FINAL_MULTIPLIER_BPS;
} else {
currentMultiplier = INITIAL_MULTIPLIER_BPS - decay;
}
// Return current sale price
return (basePrice * currentMultiplier) / 1000;
}
function processTokenTwap() external nonReentrant burn {
if (ethToTwap == 0) revert NoETHToTwap();
if (block.number < lastTwapBlock + twapDelayInBlocks)
revert TwapDelayNotMet();
uint256 ethAmount = twapIncrement;
if (ethToTwap < twapIncrement) ethAmount = ethToTwap;
uint256 reward = (ethAmount * 5) / 1000; // 0.5% reward
uint256 swapAmount = ethAmount - reward;
ethToTwap -= ethAmount;
lastTwapBlock = block.number;
// --- Wrap ETH to WETH ---
IWETH(weth()).deposit{value: swapAmount}();
uint256 amountOutMin = 0;
// Check YGMIrouter setting for quoting minimum amount out
if (IYgmiRouter(YGMIrouter).useQuoteMinAmountOut()) {
address quoterAddress = IYgmiRouter(YGMIrouter).quoter();
uint256 quotedOut = IUniswapV3Quoter(quoterAddress)
.quoteExactInputSingle(
weth(), // tokenIn (WETH)
ygmi_token(), // tokenOut
10000, // fee tier
swapAmount, // amountIn
0 // sqrtPriceLimitX96
);
require(quotedOut > 0, "Invalid quote");
// Apply slippage from YGMIrouter
amountOutMin =
(quotedOut * IYgmiRouter(YGMIrouter).slippageBps()) /
10000;
}
// --- Swap WETH → YGMI on Uniswap V3 ---
IUniswapV3SwapRouter.ExactInputSingleParams memory params = IUniswapV3SwapRouter
.ExactInputSingleParams({
tokenIn: weth(),
tokenOut: ygmi_token(),
fee: 10000,
recipient: address(this), // keep YGMI in contract
deadline: block.timestamp,
amountIn: swapAmount,
amountOutMinimum: amountOutMin,
sqrtPriceLimitX96: 0
});
IUniswapV3SwapRouter(uniswapV3Router()).exactInputSingle(params);
// --- Buy and burn tokens ---
uint256 ygmiBalance = IERC20(ygmi_token()).balanceOf(address(this));
IERC20(ygmi_token()).approve(address(uniswapV2Router), ygmiBalance);
_buyAndBurnTokens(ygmiBalance);
// --- Transfer reward to caller ---
if (reward > 0) {
(bool success, ) = msg.sender.call{value: reward}("");
require(success, "Transfer failed.");
}
}
function _buyAndBurnTokens(uint256 amountIn) internal {
if (amountIn == 0) revert NoETHToTwap();
address[] memory path = new address[](2);
path[0] = ygmi_token();
path[1] = address(this);
uniswapV2Router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
amountIn,
0,
path,
deadAddress(),
block.timestamp
);
}
uint256 private launchTime;
function _currentFee() internal view returns (uint256) {
uint256 lt = launchTime;
if (lt == 0) return START_FEE;
uint256 minutesSince = (block.timestamp - lt) / ONE_MINUTE;
if (minutesSince >= (START_FEE - MIN_FEE)) return MIN_FEE;
return START_FEE - (minutesSince * DECAY_PER_MIN);
}
}
interface IFeeSwapper {
function swapTokenToETH(
address ygmi,
address weth,
uint256 amountIn,
address recipient
) external;
}
interface IERC721 {
function balanceOf(address owner) external view returns (uint256);
function ownerOf(uint256 id) external view returns (address);
function transferFrom(address from, address to, uint256 id) external;
}
interface IUniswapV3Quoter {
function quoteExactInputSingle(
address tokenIn,
address tokenOut,
uint24 fee,
uint256 amountIn,
uint160 sqrtPriceLimitX96
) external returns (uint256 amountOut);
}
interface IUniswapV3SwapRouter {
struct ExactInputSingleParams {
address tokenIn;
address tokenOut;
uint24 fee;
address recipient;
uint256 deadline;
uint256 amountIn;
uint256 amountOutMinimum;
uint160 sqrtPriceLimitX96;
}
function exactInputSingle(
ExactInputSingleParams calldata params
) external payable returns (uint256 amountOut);
}
interface IWETH {
function deposit() external payable;
function withdraw(uint256) external;
function approve(address spender, uint256 amount) external returns (bool);
}
interface IYgmiRouter {
function status() external view returns (uint8);
function useQuoteMinAmountOut() external view returns (bool);
function quoter() external view returns (address);
function whitelistedTargets(address target) external view returns (bool);
function slippageBps() external view returns (uint256);
}
"
}
},
"settings": {
"optimizer": {
"enabled": true,
"runs": 200
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"remappings": []
}
}}
Submitted on: 2025-10-28 10:05:10
Comments
Log in to comment.
No comments yet.