Skip to content

Artifacts

DISCLAIMER // NFA // DYOR

This analysis is based on decompiled bytecode — the contract source code is not verified on Etherscan. Function names, parameter types, and internal logic are inferred from selector matching, transaction input decoding, and event log analysis. We are not smart contract security experts. This document should not be considered a comprehensive security audit or financial advice. Always verify critical information independently.

⊙ generated by robots | curated by humans

METADATA
Contract Address 0x99c96efF...Ab2dCC (etherscan)
Network Ethereum Mainnet
Analysis Date 2026-03-29

Overview

This document contains raw analysis artifacts including function selector mappings, event signatures, storage slot snapshots, transaction summaries, and verification commands. All artifacts are preserved for transparency and independent verification.

Artifact Location: /artifacts/0x99c96efF...Ab2dCC/


Reconstructed Solidity Source

Based on bytecode analysis, transaction patterns, storage slot reads, and event log decoding, the contract logic appears to follow this structure:

// SPDX-License-Identifier: UNLICENSED
// WARNING: Reconstructed from bytecode - NOT the original source code
// 16 function selectors remain unidentified and are not represented here

pragma solidity ^0.8.0;

interface IWETH {
    function deposit() external payable;
    function approve(address spender, uint256 amount) external returns (bool);
}

interface ISwapRouter {
    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 IERC20 {
    function balanceOf(address account) external view returns (uint256);
}

contract SentinelMitesVault {

    //////////////////////////////////////////////////////////////
    //  STRUCTS
    //////////////////////////////////////////////////////////////

    struct Vault {
        uint256 profit;              // Accumulated profit (wei)
        uint256 depositAmount;       // Original ETH deposit (wei)
        uint256 sentAmount;          // Declared SENT token amount
        uint256 tradeCountBuy;       // Number of buy trades
        uint256 tradeCountSell;      // Number of sell trades
        uint256 active;              // 1 = active, 0 = inactive
        uint256 depositTimestamp;    // When deposit was made
        uint256 lastTradeTimestamp;  // When last trade executed
        address lastTradeToken;      // Last traded token address
        uint256 lastTradeAmount;     // Last trade token amount
        uint256 accumulatedValue;    // Accumulated ETH value
    }

    //////////////////////////////////////////////////////////////
    //  STORAGE
    //////////////////////////////////////////////////////////////

    // Slot 0
    address public owner;

    // Slot 1
    uint256 private _active;  // 1 = active

    // Slot 2 (empty/unused)

    // Slot 3
    uint256 private _userCount;

    // Slot 4 (empty/unused)

    // Slot 5
    address public keeper;

    // Slot 6
    address public feeRecipient;

    // Slot 7
    uint256 private _depositFee;  // 0.01 ETH stored; 0.005 ETH observed

    // Slot 8
    uint256 private _totalDeposits;

    // Slot 9
    uint256 public totalTradesExecuted;

    // Slot 10
    uint256 public totalProfitGenerated;

    // Slot 11
    uint256 private _totalOperations;

    // Slot 14
    uint256 private _sentThreshold;  // 10,000 SENT

    // Dynamic storage
    address[] public users;
    mapping(address => bool) public isTracked;
    mapping(address => mapping(uint256 => Vault)) public vaults;

    // Immutable references (set in constructor)
    address public immutable weth;
    address public immutable swapRouter;
    address public immutable sentToken;
    address public presaleContract;

    // Constants
    uint256 public constant MAX_TRADE_ETH = 0.5 ether;
    uint256 public constant SWAP_DEADLINE_BUFFER = 60;

    //////////////////////////////////////////////////////////////
    //  EVENTS
    //////////////////////////////////////////////////////////////

    event OwnershipTransferred(
        address indexed previousOwner,
        address indexed newOwner
    );
    event VaultDeposit(
        address indexed user,
        uint256 indexed vaultId,
        uint256 ethAmount,
        uint256 sentAmount
    );
    event TradeExecuted(
        address indexed user,
        uint256 indexed vaultId,
        address indexed token,
        uint256 ethAmount,
        uint256 tokenAmount,
        uint256 direction,
        uint256 timestamp
    );
    event TopUpOrWithdraw(
        address indexed user,
        uint256 indexed vaultId,
        uint256 amount
    );

    //////////////////////////////////////////////////////////////
    //  MODIFIERS
    //////////////////////////////////////////////////////////////

    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }

    modifier onlyKeeper() {
        require(msg.sender == keeper, "Not keeper");
        _;
    }

    //////////////////////////////////////////////////////////////
    //  CONSTRUCTOR
    //////////////////////////////////////////////////////////////

    constructor(
        address _weth,
        address _swapRouter,
        address _sentToken,
        address _feeRecipient,
        address _keeper
    ) {
        owner = msg.sender;
        weth = _weth;
        swapRouter = _swapRouter;
        sentToken = _sentToken;
        feeRecipient = _feeRecipient;
        keeper = _keeper;
        _active = 1;

        emit OwnershipTransferred(address(0), msg.sender);
    }

    //////////////////////////////////////////////////////////////
    //  USER FUNCTIONS
    //////////////////////////////////////////////////////////////

    /// @notice Deposit ETH to create a new vault position
    /// @param sentAmount Declared SENT token holdings
    /// @dev Does NOT transfer SENT — only records the declared amount
    function deposit(uint256 sentAmount) external payable {
        require(msg.value > 0, "No ETH sent");

        // Check SENT balance if declared
        if (sentAmount > 0) {
            uint256 balance = IERC20(sentToken).balanceOf(msg.sender);
            require(balance >= sentAmount, "Insufficient SENT balance");
        }

        // Send fee to recipient
        uint256 fee = 0.005 ether;  // Observed fee amount
        payable(feeRecipient).transfer(fee);

        // Register user if new
        if (!isTracked[msg.sender]) {
            isTracked[msg.sender] = true;
            users.push(msg.sender);
            _userCount++;
        }

        // Create vault
        uint256 vaultId = _getNextVaultId(msg.sender);
        uint256 netDeposit = msg.value - fee;

        vaults[msg.sender][vaultId] = Vault({
            profit: 0,
            depositAmount: netDeposit,
            sentAmount: sentAmount,
            tradeCountBuy: 0,
            tradeCountSell: 0,
            active: 1,
            depositTimestamp: block.timestamp,
            lastTradeTimestamp: 0,
            lastTradeToken: address(0),
            lastTradeAmount: 0,
            accumulatedValue: 0
        });

        _totalDeposits += netDeposit;
        _totalOperations++;

        emit VaultDeposit(msg.sender, vaultId, netDeposit, sentAmount);
    }

    /// @notice Top up an existing vault
    function topUp(uint256 vaultId, uint256 /* unknown */) external payable {
        require(msg.value > 0, "No ETH sent");
        // Update vault deposit amount and emit event
        vaults[msg.sender][vaultId].depositAmount += msg.value;
        _totalOperations++;

        emit TopUpOrWithdraw(msg.sender, vaultId, msg.value);
    }

    /// @notice Withdraw full vault balance
    function withdraw(uint256 vaultId) external {
        Vault storage vault = vaults[msg.sender][vaultId];
        require(vault.active == 1, "Vault not active");

        uint256 amount = vault.depositAmount + vault.profit;
        vault.active = 0;
        vault.depositAmount = 0;

        payable(msg.sender).transfer(amount);
        _totalOperations++;

        emit TopUpOrWithdraw(msg.sender, vaultId, amount);
    }

    /// @notice Withdraw partial amount from vault
    function withdrawPartial(uint256 vaultId, uint256 amount) external {
        Vault storage vault = vaults[msg.sender][vaultId];
        require(vault.active == 1, "Vault not active");
        require(vault.depositAmount >= amount, "Insufficient balance");

        vault.depositAmount -= amount;
        payable(msg.sender).transfer(amount);
        _totalOperations++;

        emit TopUpOrWithdraw(msg.sender, vaultId, amount);
    }

    //////////////////////////////////////////////////////////////
    //  KEEPER FUNCTIONS
    //////////////////////////////////////////////////////////////

    /// @notice Execute a trade on behalf of a user vault
    /// @dev Wraps ETH to WETH and swaps via Uniswap V3
    function executeTrade(
        address user,
        uint256 vaultId,
        address targetToken,
        uint24 feeTier,
        uint256 ethAmount,
        uint256 minTokenOut,
        uint256 direction
    ) external onlyKeeper {
        Vault storage vault = vaults[user][vaultId];
        require(vault.active == 1, "Vault not active");
        require(ethAmount <= MAX_TRADE_ETH, "Exceeds max trade");

        // Wrap ETH to WETH
        IWETH(weth).deposit{value: ethAmount}();
        IWETH(weth).approve(swapRouter, ethAmount);

        // Execute swap via Uniswap V3
        uint256 amountOut = ISwapRouter(swapRouter).exactInputSingle(
            ISwapRouter.ExactInputSingleParams({
                tokenIn: weth,
                tokenOut: targetToken,
                fee: feeTier,
                recipient: address(this),
                deadline: block.timestamp + SWAP_DEADLINE_BUFFER,
                amountIn: ethAmount,
                amountOutMinimum: minTokenOut,
                sqrtPriceLimitX96: 0
            })
        );

        // Update vault state
        vault.tradeCountBuy++;
        vault.lastTradeToken = targetToken;
        vault.lastTradeAmount = amountOut;
        vault.lastTradeTimestamp = block.timestamp;

        // Update globals
        totalTradesExecuted++;
        _totalOperations++;
        // totalProfitGenerated updated via internal calculation

        emit TradeExecuted(
            user, vaultId, targetToken,
            ethAmount, amountOut, direction, block.timestamp
        );
    }

    /// @notice Close a trade position (sell tokens back to ETH)
    function closeTrade(
        address user,
        uint256 vaultId,
        uint24 feeTier,
        uint256 amount,
        uint256 direction
    ) external onlyKeeper {
        Vault storage vault = vaults[user][vaultId];
        require(vault.active == 1, "Vault not active");

        // Reverse swap: token → WETH → ETH
        // (implementation details inferred from transaction patterns)

        vault.tradeCountSell++;
        vault.lastTradeTimestamp = block.timestamp;
        totalTradesExecuted++;
        _totalOperations++;
    }

    //////////////////////////////////////////////////////////////
    //  ADMIN FUNCTIONS
    //////////////////////////////////////////////////////////////

    function setKeeper(address newKeeper) external onlyOwner {
        keeper = newKeeper;
    }

    function setFeeRecipient(address newFeeRecipient) external onlyOwner {
        feeRecipient = newFeeRecipient;
    }

    function setPresaleContract(address _presale) external onlyOwner {
        presaleContract = _presale;
    }

    function transferOwnership(address newOwner) external onlyOwner {
        require(newOwner != address(0), "Zero address");
        address oldOwner = owner;
        owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }

    //////////////////////////////////////////////////////////////
    //  VIEW FUNCTIONS
    //////////////////////////////////////////////////////////////

    function getUserCount() external view returns (uint256) {
        return _userCount;
    }

    function getUserTier(address user, uint256 vaultId)
        external view returns (uint256)
    {
        // Tier calculation based on SENT amount and vault state
        // Implementation details unclear from bytecode
        return 1;  // Placeholder
    }

    function getEligibility(address user)
        external view returns (uint256, uint256, uint256, uint256)
    {
        uint256 sentBalance = IERC20(sentToken).balanceOf(user);
        // Returns eligibility flags + SENT balance + eligible flag
        // Exact logic unclear from bytecode
        return (0, 0, sentBalance, sentBalance >= _sentThreshold ? 1 : 0);
    }

    function getStats()
        external view returns (
            uint256 totalDeposits,
            uint256 trades,
            uint256 profit,
            uint256 userCount,
            uint256 operations
        )
    {
        return (
            _totalDeposits,
            totalTradesExecuted,
            totalProfitGenerated,
            _userCount,
            _totalOperations
        );
    }

    //////////////////////////////////////////////////////////////
    //  INTERNAL
    //////////////////////////////////////////////////////////////

    function _getNextVaultId(address user) internal view returns (uint256) {
        // Returns next available vault index for user
        // Implementation inferred from sequential vault IDs
        return 0;  // Simplified — actual logic tracks per-user count
    }
}

Function Selector Mapping

Complete mapping of all 44 function selectors extracted from bytecode dispatch table:

# Matched Selectors (28)
0x1360003f => totalProfitGenerated() view returns (uint256)
0x2e1a7d4d => withdraw(uint256)
0x365b98b2 => users(uint256) view returns (address)
0x3fc8cef3 => weth() view returns (address)
0x444cef88 => sentToken() view returns (address)
0x46904840 => feeRecipient() view returns (address)
0x4af9daa8 => deposit(uint256) payable                    [custom - inferred]
0x63d9df85 => presaleContract() view returns (address)
0x66c91379 => withdrawPartial(uint256,uint256)
0x748747e6 => setKeeper(address)
0x7bbfc69e => vaults(address,uint256) view returns (...)
0x8da5cb5b => owner() view returns (address)
0xa8c94d1b => isTracked(address) view returns (bool)
0xa9bbd114 => setPresaleContract(address)
0xaced1661 => keeper() view returns (address)
0xb5cb15f7 => getUserCount() view returns (uint256)
0xc31c9c07 => swapRouter() view returns (address)
0xc59d4847 => getStats() view returns (uint256,uint256,uint256,uint256,uint256)
0xcbb117a3 => SWAP_DEADLINE_BUFFER() view returns (uint256)
0xcbe9e55e => getUserTier(address,uint256) view returns (uint256)
0xd0fd9cad => MAX_TRADE_ETH() view returns (uint256)
0xd2a037ab => totalTradesExecuted() view returns (uint256)
0xd86938ba => closeTrade(address,uint256,uint24,uint256,uint256)  [custom - inferred]
0xdca11ab8 => getEligibility(address) view returns (uint256,uint256,uint256,uint256)
0xde643a71 => topUp(uint256,uint256)
0xe74b981b => setFeeRecipient(address)
0xea0ccfae => executeTrade(address,uint256,address,uint24,uint256,uint256,uint256)  [custom - inferred]
0xf2fde38b => transferOwnership(address)
0xf8b8790f => (unknown) view returns (uint256)             [returns constant 1000e18]

# Unmatched Selectors (16)
0x06e20080 => UNKNOWN
0x1a519533 => UNKNOWN
0x553a9a93 => UNKNOWN
0x5b451dff => UNKNOWN
0x6f747452 => UNKNOWN
0x8b4c6df1 => UNKNOWN
0x8c07635a => UNKNOWN
0xa0aca335 => UNKNOWN
0xae1e9118 => UNKNOWN
0xb3051d6e => UNKNOWN
0xbda962d5 => UNKNOWN
0xc84d5389 => UNKNOWN
0xc9b6e079 => UNKNOWN
0xda91a291 => UNKNOWN
0xe7ba4fe5 => UNKNOWN
0xe87ce5ee => UNKNOWN
0xf1cb0216 => UNKNOWN

Event Signatures

Event topic hashes observed on-chain:

0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0
=> OwnershipTransferred(address indexed previousOwner, address indexed newOwner)
   Count: 1

0xed9d3a11a7d707b642c8dfb02f78d4eca3b83394e0ff1065c8850d554e9b1cab
=> VaultDeposit(address indexed user, uint256 indexed vaultId, uint256 ethAmount, uint256 sentAmount)
   Count: 28

0x0134eeeac969585050b0bbc7656999d77545758ef6f7739e46ef45752468a59b
=> TradeExecuted(address indexed user, uint256 indexed vaultId, address indexed token, uint256 ethAmount, uint256 tokenAmount, uint256 direction, uint256 timestamp)
   Count: 13

0x91ede45f04a37a7c170f5c1207df3b6bc748dc1e04ad5e917a241d0f52feada3
=> TopUpOrWithdraw(address indexed user, uint256 indexed vaultId, uint256 amount, ...)
   Count: 8

Storage Snapshot

Storage slots read on 2026-03-29:

Slot 0:  0x0000000000000000000000009fbcc72a6bc74d0060e14fe8b8f4b7ccfa63ea03  # owner
Slot 1:  0x0000000000000000000000000000000000000000000000000000000000000001  # active flag
Slot 2:  0x0000000000000000000000000000000000000000000000000000000000000000  # (empty)
Slot 3:  0x0000000000000000000000000000000000000000000000000000000000000055  # userCount (85)
Slot 4:  0x0000000000000000000000000000000000000000000000000000000000000000  # (empty)
Slot 5:  0x0000000000000000000000009fbcc72a6bc74d0060e14fe8b8f4b7ccfa63ea03  # keeper
Slot 6:  0x00000000000000000000000090ff7835f01537bb98d5835e4917f91c1efceead  # feeRecipient
Slot 7:  0x000000000000000000000000000000000000000000000000002386f26fc10000  # fee (0.01 ETH)
Slot 8:  0x000000000000000000000000000000000000000000000000431de5396b62facc  # totalDeposits
Slot 9:  0x00000000000000000000000000000000000000000000000000000000000000a2  # trades (162)
Slot 10: 0x000000000000000000000000000000000000000000000000003ec87442517ed7  # profit (~0.018 ETH)
Slot 11: 0x00000000000000000000000000000000000000000000000000000000000000d7  # operations (215)
Slot 14: 0x00000000000000000000000000000000000000000000021e19e0c9bab2400000  # threshold (10000 tokens)

Transaction Summary

METHOD ID FUNCTION COUNT CALLER VALUE
0x60e03461 (creation) 1 Deployer 0
0x4af9daa8 deposit 47 Various users 0.01-0.25 ETH
0xea0ccfae executeTrade 26 Owner/Keeper 0
0xde643a71 topUp 20 Various users 0.005-0.055 ETH
0xd86938ba closeTrade 5 Owner/Keeper 0
0x2e1a7d4d withdraw 2 Users 0

Total Transactions: 101 (all successful, no errors)


Sample Vault Decode

Vault data for first depositor (0x5db50b4a..., vault 0):

Field 0 (profit):           0.016013 ETH
Field 1 (deposit):          0.070 ETH
Field 2 (SENT amount):      500 SENT
Field 3 (buy trades):       7
Field 4 (sell trades):      7
Field 5 (active):           1 (true)
Field 6 (deposit time):     2026-03-28 12:34:47 UTC
Field 7 (last trade time):  2026-03-29 03:18:59 UTC
Field 8 (last trade token): 0xdAC17F95...831EC7 (USDT)
Field 9 (last trade amt):   109.00 USDT
Field 10 (accumulated):     0.054118 ETH

Internal Transaction Patterns

Two distinct internal transaction destinations observed:

Fee Recipient (0x90fF7835...fceEAD):

  • Always receives exactly 0.005 ETH
  • Triggered during deposit transactions
  • 7+ instances observed in first 20 internal txs

WETH (0xC02aaA39...756Cc2):

  • Receives varying ETH amounts (0.008 - 0.224 ETH)
  • Triggered during executeTrade transactions
  • Represents ETH wrapping before Uniswap swap

Sample Trade Execution Receipt

Transaction: 0x1cdd8480bdc3b31c8f21466238e1099851a645baa5c8ce61e128af60b665e251

STEP EVENT DETAILS
1 WETH Deposit 0.04 ETH wrapped
2 WETH Approval Router approved for 0.04 WETH
3 USDC Transfer 81.16 USDC received from pool
4 WETH Transfer 0.04 WETH sent to pool
5 Uniswap Swap Pool event recorded
6 TradeExecuted Contract event: user, vault, USDC, 0.04 ETH, 81.16 USDC, direction=1

External Contract References

CONTRACT ADDRESS STATUS
Owner/Keeper 0x9fBcc72A6bc74D0060e14Fe8b8f4b7CcFA63eA03 EOA
Fee Recipient 0x90fF7835f01537bB98d5835E4917F91c1EfcEEAD EOA
WETH 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2 ☑ Verified
Uniswap V3 Router 0xe592427A0AEce92De3Edee1F18E0157C05861564 ☑ Verified
SENT Token 0xe88BaAB9192a3cb2C0a50182Ab911506E5aDc304 ☒ See analysis
WETH/USDC Pool 0x88e6A0c2dDD26FEEb64F039a2c41296FcB3f5640 ☑ Verified
Presale Contract 0x0000000000000000000000000000000000000000 Not Set

Verification Commands

Basic Contract Info

# Get contract bytecode size
cast code 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC | wc -c

# Check contract balance
cast balance 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC --ether

# Check if contract exists
cast codesize 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC

View Function Calls

cast call 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC "owner()"
cast call 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC "keeper()"
cast call 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC "feeRecipient()"
cast call 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC "weth()"
cast call 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC "swapRouter()"
cast call 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC "sentToken()"
cast call 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC "getStats()"
cast call 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC "getUserCount()"
cast call 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC "vaults(address,uint256)" <ADDRESS> <ID>
cast call 0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC "getEligibility(address)" <ADDRESS>

Selector Verification

cast sig "topUp(uint256,uint256)"         # 0xde643a71
cast sig "withdraw(uint256)"              # 0x2e1a7d4d
cast sig "owner()"                        # 0x8da5cb5b
cast sig "transferOwnership(address)"     # 0xf2fde38b
cast sig "getUserCount()"                 # 0xb5cb15f7

RESOURCE URL
Etherscan Contract https://etherscan.io/address/0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC
Creation TX https://etherscan.io/tx/0x72ab67618089769e33371233ac21936570e27360c0758f0617d52aec73cdc457
Owner/Keeper https://etherscan.io/address/0x9fBcc72A6bc74D0060e14Fe8b8f4b7CcFA63eA03
Fee Recipient https://etherscan.io/address/0x90ff7835f01537bb98d5835e4917f91c1efceead
SENT Token https://etherscan.io/address/0xe88BaAB9192a3cb2C0a50182Ab911506E5aDc304
Uniswap V3 Router https://etherscan.io/address/0xe592427A0AEce92De3Edee1F18E0157C05861564

Raw Data Files

The following files are stored in /artifacts/0x99c96efF...Ab2dCC/:

FILE DESCRIPTION
bytecode.txt Full contract bytecode (hex, 19.8 KB)

Analysis Metadata

{
  "contract_address": "0x99c96efFDbd52C6868CB500f10350DF444Ab2dCC",
  "network": "ethereum-mainnet",
  "analysis_date": "2026-03-29",
  "analyst": "Claude Opus 4.6",
  "analysis_method": "Bytecode disassembly + transaction pattern analysis + event log decoding",
  "verification_status": "unverified",
  "total_functions": 44,
  "matched_functions": 28,
  "unmatched_functions": 16,
  "admin_functions": 4,
  "keeper_functions": 2,
  "user_functions": 4,
  "view_functions": 18,
  "events": 4,
  "storage_slots_identified": 11,
  "external_dependencies": 3,
  "deployment_block": 24755545,
  "deployment_timestamp": "2026-03-28T10:43:35Z",
  "transaction_count": 101,
  "user_count": 85,
  "total_trades": 162,
  "eth_balance": "4.836 ETH",
  "token_cost": "75 tok"
}

Disclaimer

All artifacts in this document are based on bytecode analysis of an unverified contract. They represent our best interpretation of the contract's behavior but may not perfectly match the original source code. Variable names, function logic, and internal structures are inferred and should not be considered authoritative.