ETH Price: $2,047.72 (-0.91%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction and 3 Token Transfers found.

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Method Block
From
To
0x3d602d80236991222025-10-31 18:27:59118 days ago1761935279  Contract Creation0 ETH
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading

Minimal Proxy Contract for 0x6e55562d9c3b122f2a17a2179ef22b54ee625c83

Contract Name:
EtfVault

Compiler Version
v0.8.30+commit.73712a01

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

import "hopium/common/interface/imDirectory.sol";
import "hopium/etf/interface/imEtfRouter.sol";

interface IERC20 {
    function transfer(address to, uint256 value) external returns (bool);
    function balanceOf(address account) external view returns (uint256);
}

contract TransferHelpers {
    error ZeroAmount();
    error EthSendFailed();

    function _sendEth(address to, uint256 amount) internal {
        if (amount == 0) revert ZeroAmount();
        (bool ok, ) = payable(to).call{value: amount}("");
        if (!ok) revert EthSendFailed();
    }

    function _sendToken(address tokenAddress, address toAddress, uint256 amount) internal {
        if (amount == 0) revert ZeroAmount();
        IERC20(tokenAddress).transfer(toAddress, amount);
    }

    function _sendEthOrToken(address tokenAddress, address toAddress) internal {
        if (tokenAddress == address(0)) {
            _sendEth(toAddress, address(this).balance);
        } else {
            _sendToken(tokenAddress, toAddress, IERC20(tokenAddress).balanceOf(address(this)));
        }
    }

    function _recoverAsset(address tokenAddress, address toAddress) internal {
        _sendEthOrToken(tokenAddress, toAddress);
    }
}

/// @notice Etf Vault implementation (logic). Clones delegatecall into this.
/// @dev Assumes ImEtfRouter -> ImDirectory for access control & Directory wiring.
contract EtfVault is ImEtfRouter, TransferHelpers {
    bool private _initialized;

    /// @notice Constructor runs once for the implementation only.
    /// @dev You can pass an existing Directory here; clones still call initialize().
    constructor(address _directory) ImDirectory(_directory) {}

    error AlreadyInitialized();
    /// @notice One-time initializer for clones (constructors don't run for proxies)
    function initialize(address _directory) external {
         if (_initialized) revert AlreadyInitialized();
        _initialized = true;

        _setDirectory(_directory); // from ImDirectory (no modifier)
    }

    /// @notice Redeem underlying tokens to receiver; callable only by EtfRouter
    function redeem(address tokenAddress, uint256 amount, address receiver) external onlyEtfRouter {
        _sendToken(tokenAddress, receiver, amount);
    }

    /// @notice Owner (Directory.owner()) can recover stuck ETH/ERC20
    function recoverAsset(address tokenAddress, address toAddress) external onlyOwner {
        _recoverAsset(tokenAddress, toAddress);
    }

    receive() external payable {}
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

import "hopium/common/interface/imDirectory.sol";

interface IEtfRouter {
    function mintEtfTokens(uint256 etfId, address receiver, string calldata affiliateCode) external payable;
}

abstract contract ImEtfRouter is ImDirectory {

    function getEtfRouter() internal view virtual returns (IEtfRouter) {
        return IEtfRouter(fetchFromDirectory("etf-router"));
    }

    modifier onlyEtfRouter() {
        require(msg.sender == fetchFromDirectory("etf-router"), "msg.sender is not etf router");
        _;
    }
}

// SPDX-License-Identifier: MIT
pragma solidity 0.8.30;

/// @notice Interface used by the registry to talk to the external directory.
interface IDirectory {
    function owner() external view returns (address);
    function fetchFromDirectory(string memory _key) external view returns (address);
}

abstract contract ImDirectory {
    IDirectory public Directory;

    constructor(address _directory) {
        _setDirectory(_directory); // no modifier here
    }

    function changeDirectoryAddress(address _directory) external onlyOwner {
        _setDirectory(_directory);
    }

    function _setDirectory(address _directory) internal {
        require(_directory != address(0), "Directory cannot be zero address");
        require(_directory.code.length > 0, "Directory must be a contract");

        // Sanity check the interface
        try IDirectory(_directory).owner() returns (address) {
            Directory = IDirectory(_directory);
        } catch {
            revert("Directory address does not implement owner()");
        }
    }

    modifier onlyOwner() {
        require(msg.sender == Directory.owner(), "Caller is not the owner");
        _;
    }

    function owner() public view returns (address) {
        return Directory.owner();
    }

    function fetchFromDirectory(string memory _key) public view returns (address) {
        return Directory.fetchFromDirectory(_key);
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "remappings": []
}

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_directory","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"EthSendFailed","type":"error"},{"inputs":[],"name":"ZeroAmount","type":"error"},{"inputs":[],"name":"Directory","outputs":[{"internalType":"contract IDirectory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_directory","type":"address"}],"name":"changeDirectoryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_key","type":"string"}],"name":"fetchFromDirectory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_directory","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"address","name":"toAddress","type":"address"}],"name":"recoverAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.