Description:
Decentralized Finance (DeFi) protocol contract providing Swap, Liquidity, Factory, Oracle functionality.
Blockchain: Ethereum
Source Code: View Code On The Blockchain
Solidity Source Code:
{{
"language": "Solidity",
"sources": {
"src/MemeStrategyViews.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import {IUniswapV2Router} from "./interfaces/IUniswapV2Router.sol";
interface IMemeStrategy {
struct MemeToken {
address v2Router;
bool isWhitelisted;
}
struct QueuedPurchase {
uint256 queueId;
address targetAddress;
uint256 ethAmount;
uint256 targetMultiplier;
uint256 maxSlippage;
uint256 targetEntryPrice;
uint256 queuedAt;
bool executed;
bool exists;
bool executeToTreasury;
}
struct Purchase {
uint256 purchaseId;
address tokenAddress;
uint256 tokenAmount;
uint256 buyPricePerUnit;
uint256 targetPrice;
uint256 ethSpent;
uint256 timestamp;
bool sold;
uint256 soldPrice;
uint256 soldTimestamp;
bool isProfit;
uint256 profitOrLoss;
uint256 slippageUsed;
bool executeToTreasury;
}
// Getters
function queuedPurchases(uint256) external view returns (QueuedPurchase memory);
function whitelistedTokens(address) external view returns (MemeToken memory);
function purchases(uint256) external view returns (Purchase memory);
function nextQueueId() external view returns (uint256);
function activeQueueCount() external view returns (uint256);
function totalQueues() external view returns (uint256);
function executorReward() external view returns (uint256);
function paused() external view returns (bool);
function totalPurchases() external view returns (uint256);
function totalProfit() external view returns (uint256);
function totalLoss() external view returns (uint256);
function totalTokensBurned() external view returns (uint256);
function successfulFlips() external view returns (uint256);
function getActivePurchaseCount() external view returns (uint256);
function getWETH() external view returns (address);
}
interface IERC20 {
function balanceOf(address) external view returns (uint256);
}
/// @title MemeStrategyViews
/// @notice Separate contract for large view functions to keep main contract under 24KB
/// @dev Deploy this separately and call with strategy address as first parameter
contract MemeStrategyViews {
uint256 constant BPS_BASE = 10_000;
uint256 constant MAX_BATCH_SIZE = 50;
/* ═══════════════════════════════════════════════════════════════════════════ */
/* QUEUE VIEW FUNCTIONS */
/* ═══════════════════════════════════════════════════════════════════════════ */
/// @notice Get queue items by IDs (backend provides the IDs in desired order)
/// @dev Backend maintains queue order off-chain and provides IDs to query
/// @param strategy Strategy contract address
/// @param queueIds Array of queue IDs to fetch
/// @return Array of queued purchases
function getQueuedPurchasesByIds(
address strategy,
uint256[] calldata queueIds
) external view returns (IMemeStrategy.QueuedPurchase[] memory) {
IMemeStrategy strat = IMemeStrategy(strategy);
uint256 length = queueIds.length > MAX_BATCH_SIZE ? MAX_BATCH_SIZE : queueIds.length;
IMemeStrategy.QueuedPurchase[] memory queued = new IMemeStrategy.QueuedPurchase[](length);
for (uint256 i = 0; i < length; i++) {
queued[i] = strat.queuedPurchases(queueIds[i]);
}
return queued;
}
/// @notice Get basic queue stats
/// @param strategy Strategy contract address
/// @return totalQueues Total number of queues ever created
/// @return activeCount Number of active queues
/// @return nextId Next queue ID to be assigned
function getQueueStats(
address strategy
) external view returns (
uint256 totalQueues,
uint256 activeCount,
uint256 nextId
) {
IMemeStrategy strat = IMemeStrategy(strategy);
return (
strat.totalQueues(),
strat.activeQueueCount(),
strat.nextQueueId()
);
}
/* ═══════════════════════════════════════════════════════════════════════════ */
/* EXECUTABLE QUEUE HELPERS */
/* ═══════════════════════════════════════════════════════════════════════════ */
/// @notice Check if a queued purchase can be executed
/// @param strategy Strategy contract address
/// @param queueId Queue ID to check
function canExecuteQueue(address strategy, uint256 queueId)
external
view
returns (
bool executable,
string memory reason,
uint256 estimatedGas,
uint256 profitability
)
{
IMemeStrategy strat = IMemeStrategy(strategy);
// Direct access by queueId
IMemeStrategy.QueuedPurchase memory queue = strat.queuedPurchases(queueId);
if (!queue.exists || queue.executed) {
return (false, "Queue item not found", 0, 0);
}
if (strat.paused()) {
return (false, "Contract paused", 0, 0);
}
uint256 executorReward = strat.executorReward();
if (strategy.balance < queue.ethAmount + executorReward) {
return (false, "Insufficient ETH fees", 0, 0);
}
// Check target entry price if set
if (queue.targetEntryPrice > 0) {
IMemeStrategy.MemeToken memory tokenInfo = strat.whitelistedTokens(queue.targetAddress);
IUniswapV2Router v2Router = IUniswapV2Router(tokenInfo.v2Router);
address[] memory path = new address[](2);
path[0] = strat.getWETH();
path[1] = queue.targetAddress;
try v2Router.getAmountsOut(1e18, path) returns (uint256[] memory amounts) {
uint256 currentPricePerToken = amounts[1];
uint256 pricePerToken = (1e18 * 1e18) / currentPricePerToken;
if (pricePerToken > queue.targetEntryPrice) {
return (false, "Entry price not reached", 0, 0);
}
} catch {
return (false, "No V2 liquidity", 0, 0);
}
}
estimatedGas = 150_000;
uint256 gasCost = estimatedGas * tx.gasprice;
profitability = executorReward > gasCost ? executorReward - gasCost : 0;
return (true, "", estimatedGas, profitability);
}
/// @notice Check multiple queue IDs for executability (backend provides IDs)
/// @dev Backend maintains queue order and provides IDs to check
/// @param strategy Strategy contract address
/// @param queueIds Array of queue IDs to check
/// @return executableIds Array of executable queue IDs
/// @return reasons Array of execution status reasons
function checkQueueExecutability(
address strategy,
uint256[] calldata queueIds
) external view returns (
uint256[] memory executableIds,
string[] memory reasons
) {
IMemeStrategy strat = IMemeStrategy(strategy);
uint256 length = queueIds.length > MAX_BATCH_SIZE ? MAX_BATCH_SIZE : queueIds.length;
uint256 executorReward = strat.executorReward();
bool isPaused = strat.paused();
address weth = strat.getWETH();
// First pass: count executable items
uint256 count = 0;
bool[] memory isExecutable = new bool[](length);
for (uint256 i = 0; i < length; i++) {
IMemeStrategy.QueuedPurchase memory queue = strat.queuedPurchases(queueIds[i]);
if (!queue.exists || queue.executed) continue;
if (isPaused) continue;
if (strategy.balance < queue.ethAmount + executorReward) continue;
bool priceOk = true;
if (queue.targetEntryPrice > 0) {
IMemeStrategy.MemeToken memory tokenInfo = strat.whitelistedTokens(queue.targetAddress);
IUniswapV2Router v2Router = IUniswapV2Router(tokenInfo.v2Router);
address[] memory path = new address[](2);
path[0] = weth;
path[1] = queue.targetAddress;
try v2Router.getAmountsOut(1e18, path) returns (uint256[] memory amounts) {
uint256 currentPricePerToken = amounts[1];
uint256 pricePerToken = (1e18 * 1e18) / currentPricePerToken;
if (pricePerToken > queue.targetEntryPrice) {
priceOk = false;
}
} catch {
priceOk = false;
}
}
if (priceOk) {
isExecutable[i] = true;
count++;
}
}
// Second pass: collect executable IDs
executableIds = new uint256[](count);
reasons = new string[](count);
uint256 index = 0;
for (uint256 i = 0; i < length; i++) {
if (isExecutable[i]) {
executableIds[index] = queueIds[i];
reasons[index] = "Executable";
index++;
}
}
return (executableIds, reasons);
}
/* ═══════════════════════════════════════════════════════════════════════════ */
/* PURCHASE VIEW FUNCTIONS */
/* ═══════════════════════════════════════════════════════════════════════════ */
/// @notice Check if a purchase can be sold
function canExecuteSale(address strategy, uint256 _purchaseId)
external
view
returns (
bool canSell,
uint256 currentPrice,
uint256 targetPrice,
string memory reason
)
{
IMemeStrategy strat = IMemeStrategy(strategy);
IMemeStrategy.Purchase memory purchase = strat.purchases(_purchaseId);
if (purchase.purchaseId == 0) {
return (false, 0, 0, "Purchase not found");
}
if (purchase.sold) {
return (false, 0, 0, "Already sold");
}
if (strat.paused()) {
return (false, 0, 0, "Contract paused");
}
IERC20 token = IERC20(purchase.tokenAddress);
uint256 balance = token.balanceOf(strategy);
if (balance < purchase.tokenAmount) {
return (false, 0, 0, "Insufficient token balance");
}
IMemeStrategy.MemeToken memory tokenInfo = strat.whitelistedTokens(purchase.tokenAddress);
IUniswapV2Router v2Router = IUniswapV2Router(tokenInfo.v2Router);
address[] memory path = new address[](2);
path[0] = purchase.tokenAddress;
path[1] = strat.getWETH();
try v2Router.getAmountsOut(balance, path) returns (
uint256[] memory amounts
) {
currentPrice = amounts[1] * 1e18 / balance;
} catch {
currentPrice = 0;
}
targetPrice = purchase.targetPrice;
if (currentPrice < targetPrice) {
return (
false,
currentPrice,
targetPrice,
"Target price not reached"
);
}
return (true, currentPrice, targetPrice, "");
}
/// @notice Get strategy statistics
function getStrategyStats(address strategy)
external
view
returns (
uint256 _totalPurchases,
uint256 _activePurchases,
uint256 _completedPurchases,
bool isNetProfit,
uint256 netProfitOrLossETH,
uint256 _totalBurned,
uint256 successRateX100,
uint256 _currentFeesETH,
uint256 strategyTokenPrice
)
{
IMemeStrategy strat = IMemeStrategy(strategy);
_totalPurchases = strat.totalPurchases();
_activePurchases = strat.getActivePurchaseCount();
_completedPurchases = _totalPurchases - _activePurchases;
uint256 totalProfit = strat.totalProfit();
uint256 totalLoss = strat.totalLoss();
isNetProfit = totalProfit > totalLoss;
netProfitOrLossETH = isNetProfit
? totalProfit - totalLoss
: totalLoss - totalProfit;
_totalBurned = strat.totalTokensBurned();
uint256 successfulFlips = strat.successfulFlips();
successRateX100 = _totalPurchases > 0
? ((successfulFlips * 10000) / _totalPurchases)
: 0;
_currentFeesETH = strategy.balance;
strategyTokenPrice = 0; // Removed oracle dependency
}
/// @notice Get purchase history
function getPurchaseHistory(
address strategy,
uint256 offset,
uint256 limit
) external view returns (IMemeStrategy.Purchase[] memory) {
IMemeStrategy strat = IMemeStrategy(strategy);
uint256 totalPurchases = strat.totalPurchases();
if (limit > MAX_BATCH_SIZE) limit = MAX_BATCH_SIZE;
if (offset >= totalPurchases) return new IMemeStrategy.Purchase[](0);
uint256 end = offset + limit;
if (end > totalPurchases) end = totalPurchases;
uint256 length = end - offset;
IMemeStrategy.Purchase[] memory history = new IMemeStrategy.Purchase[](length);
for (uint256 i = 0; i < length; i++) {
history[i] = strat.purchases(offset + i + 1); // purchaseId starts at 1
}
return history;
}
}
"
},
"src/interfaces/IUniswapV2Router.sol": {
"content": "// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
interface IUniswapV2Router {
function swapExactETHForTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable returns (uint256[] memory amounts);
function swapExactTokensForETH(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
function swapExactTokensForTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external returns (uint256[] memory amounts);
// Fee-on-transfer token support (critical for meme tokens with taxes)
function swapExactETHForTokensSupportingFeeOnTransferTokens(
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external payable;
function swapExactTokensForETHSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function swapExactTokensForTokensSupportingFeeOnTransferTokens(
uint256 amountIn,
uint256 amountOutMin,
address[] calldata path,
address to,
uint256 deadline
) external;
function getAmountsOut(
uint256 amountIn,
address[] calldata path
) external view returns (uint256[] memory amounts);
function WETH() external view returns (address);
}
"
}
},
"settings": {
"remappings": [
"solady/=lib/solady/src/",
"permit2/=lib/permit2/",
"@uniswap/v4-core/=lib/v4-core/",
"@uniswap/v4-periphery/=lib/v4-periphery/",
"v4-router/=lib/v4-periphery/lib/v4-router/",
"@ensdomains/=lib/v4-core/node_modules/@ensdomains/",
"@openzeppelin/=lib/v4-core/lib/openzeppelin-contracts/",
"ds-test/=lib/v4-core/lib/forge-std/lib/ds-test/src/",
"erc4626-tests/=lib/v4-core/lib/openzeppelin-contracts/lib/erc4626-tests/",
"forge-gas-snapshot/=lib/permit2/lib/forge-gas-snapshot/src/",
"forge-std/=lib/forge-std/src/",
"hardhat/=lib/v4-core/node_modules/hardhat/",
"openzeppelin-contracts/=lib/v4-core/lib/openzeppelin-contracts/",
"solmate/=lib/v4-core/lib/solmate/",
"v4-core/=lib/v4-core/src/",
"v4-periphery/=lib/v4-periphery/"
],
"optimizer": {
"enabled": true,
"runs": 200
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": true
}
}}
Submitted on: 2025-10-30 17:32:13
Comments
Log in to comment.
No comments yet.