Holesky Testnet

Contract

0x9408a6DE3c7BA7e80c25a053aBaf2a1a9338Fef7

Overview

ETH Balance

0 ETH

Multichain Info

N/A
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block
From
To
25450352024-10-16 13:09:48114 days ago1729084188  Contract Creation0 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
HistoricDataFeedStoreV2

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 1 : HistoricDataFeedStoreV2.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/// @title Mapping of mappings Historic Data Feed Storage
/// @dev Storage layout
///
/// mapping(key => mapping(counter => Transmission {bytes24 value, uint64 timestamp}))
/// array[key] -> latestCounter
/// We have a mapping of mappings where:
/// - key is the feed id and mapping[key] is the mapping of counters;
/// - counter is incremented whenever a new value for a feed is stored
///   and presents a continuous feed history.
/// Latest counter is stored at array[key].
/// Each counter mapping is stored at keccak256(key) address.
/// The value is then stored at keccak256(key) + counter.
contract HistoricDataFeedStoreV2 {
  /// @notice Mask for getters
  /// @dev The maximum length of the key is defined by the mask from the selector.
  /// This evaluates to 29 bits, which is the maximum length of the key.
  bytes32 internal constant CONTRACT_MANAGEMENT_SELECTOR_GETTER =
    0x00000000000000000000000000000000000000000000000000000000E0000000;

  /// @notice Mask for getFeedById(uint32 key)
  bytes32 internal constant CONTRACT_MANAGEMENT_SELECTOR_GET_FEED_LATEST =
    0x0000000000000000000000000000000000000000000000000000000080000000;

  /// @notice Mask for getLatestCounter(uint32 key)
  bytes32 internal constant CONTRACT_MANAGEMENT_SELECTOR_GET_LATEST_COUNTER =
    0x0000000000000000000000000000000000000000000000000000000040000000;

  /// @notice Mask for getFeedAtCounter(uint32 key, uint256 counter)
  bytes32 internal constant CONTRACT_MANAGEMENT_SELECTOR_GET_FEED_AT_COUNTER =
    0x0000000000000000000000000000000000000000000000000000000020000000;

  /// @notice Maximum value for the counter
  /// @dev When the counter reaches the maximum value, it resets to one.
  /// This is to have less gas cost when the value is incremented again.
  uint16 internal constant MAX_COUNTER = 0xFFFF;

  /// @notice Owner of the contract
  /// @dev The owner is the address that deployed the contract
  address internal immutable owner;

  /// @notice Constructor
  /// @dev Sets the owner of the contract - the address that deployed the contract
  constructor(address owner_) {
    owner = owner_;
  }

  /// @notice Fallback function
  /// @dev The fallback function is used to set or get data feeds according to the provided selector.
  fallback() external {
    bytes32 selector;

    // Getters
    assembly {
      // Get the address of the first free memory slot
      let ptr := mload(0x40)

      // Store selector in memory at location free memory slot + 28 bytes
      calldatacopy(add(ptr, 0x1C), 0x00, 0x04)

      // Load selector from memory
      selector := mload(ptr)

      if and(selector, CONTRACT_MANAGEMENT_SELECTOR_GETTER) {
        // Key is the first 4 bytes of the calldata after the selector
        let key := and(selector, not(CONTRACT_MANAGEMENT_SELECTOR_GETTER))

        // getFeedAtCounter(uint32 key, uint256 counter) returns (bytes32 value)
        if and(selector, CONTRACT_MANAGEMENT_SELECTOR_GET_FEED_AT_COUNTER) {
          // Store key in memory at the last 4 bytes of the second slot 60-64
          mstore(0x20, key)

          // keccak256(key) gives the address of the counters mapping
          // providedCounter is the bytes of the calldata after the selector (first 4 bytes)
          // Load value at counters[counter + providedCounter] and store it at memory location 0
          mstore(0x00, sload(add(keccak256(0x3C, 0x04), calldataload(0x04))))

          // Return value stored at memory location 0
          return(0x00, 0x20)
        }

        // Load the latest counter at array[key]
        let counter := sload(key)

        // getFeedById(uint32 key) returns (bytes32 value)
        if and(selector, CONTRACT_MANAGEMENT_SELECTOR_GET_FEED_LATEST) {
          // Store key in memory at the last 4 bytes of the second slot 60-64
          mstore(0x00, key)

          // keccak256(key) gives the address of the counters mapping
          // then load the value at counters[latest counter] and store it at memory location 0
          mstore(0x00, sload(add(keccak256(0x1C, 0x04), counter)))
        }
        // getLatestCounter(uint32 key) returns (uint256 counter)
        if and(selector, CONTRACT_MANAGEMENT_SELECTOR_GET_LATEST_COUNTER) {
          // Store the counter at array[key] in memory at the last 4 bytes of the first slot 28-32
          mstore(0x20, counter)
        }
        // Return value stored at memory location 0
        return(0x00, 0x40)
      }
    }

    address _owner = owner;

    // Setters
    assembly {
      // Check if sender is owner
      if iszero(eq(_owner, caller())) {
        revert(0x00, 0x00)
      }

      // setFeeds(bytes)
      if eq(selector, 0x1a2d80ac) {
        // Bytes should be in the format of:
        // <key1><value1>...<keyN><valueN>
        // where key is uint32 and value is bytes32

        // Get the current timestamp
        let time := timestamp()

        // Get the length of the calldata
        let len := calldatasize()

        for {
          // Start at location 0x04 where first key is stored after the selector
          let i := 0x04
        } lt(i, len) {
          // Increment by 36 bytes (4 bytes for key and 32 bytes for value)
          i := add(i, 0x24)
        } {
          // Store key in memory at the last 4 bytes of the second slot 60-64
          calldatacopy(0x1C, i, 0x04)

          // Load key from memory
          let key := mload(0x00)

          // Calculate the counters mapping address based on keccak256(key)
          let countersAddress := keccak256(0x1C, 0x04)

          // Load the latest counter and increment it by 1
          let currentCounter := addmod(sload(key), 1, MAX_COUNTER)

          // To avoid getting a zero value in storage when reset to zero,
          // the counter is always one greater than the actual value.
          // This prevents a higher gas cost when the value is incremented again.
          if iszero(currentCounter) {
            currentCounter := 1
          }

          // Store new counter value at array[key]
          sstore(key, currentCounter)

          // Store { value, timestamp } at counters[currentCounter]
          sstore(
            add(countersAddress, currentCounter),
            or(calldataload(add(i, 0x04)), time)
          )
        }
        return(0x00, 0x00)
      }
      // Revert if selector is not recognized.
      revert(0x00, 0x00)
    }
  }
}

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

Contract ABI

[{"inputs":[{"internalType":"address","name":"owner_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"stateMutability":"nonpayable","type":"fallback"}]

60a060405234801561001057600080fd5b506040516101cf3803806101cf83398101604081905261002f91610040565b6001600160a01b0316608052610070565b60006020828403121561005257600080fd5b81516001600160a01b038116811461006957600080fd5b9392505050565b60805161014561008a6000396000609001526101456000f3fe608060405234801561001057600080fd5b50600060405160046000601c83013751905063e000000081161561008e5763e0000000198116632000000082161561005957806020526004356004603c20015460005260206000f35b805463800000008316156100775781600052806004601c2001546000525b634000000083161561008857806020525b60406000f35b7f00000000000000000000000000000000000000000000000000000000000000003381146100bb57600080fd5b631a2d80ac820361010a57423660045b8181101561010857600481601c376000516004601c2061ffff6001835408806100f2575060015b91829055600483013585179101556024016100cb565b005b600080fdfea26469706673582212204a7c38e6d9b723ea65e6d451d6a8436444c333499ad610af033e7360a2558aea64736f6c63430008180033000000000000000000000000d756119012ccabbc59910de0ecebe406b5b952be

Deployed Bytecode

0x608060405234801561001057600080fd5b50600060405160046000601c83013751905063e000000081161561008e5763e0000000198116632000000082161561005957806020526004356004603c20015460005260206000f35b805463800000008316156100775781600052806004601c2001546000525b634000000083161561008857806020525b60406000f35b7f000000000000000000000000d756119012ccabbc59910de0ecebe406b5b952be3381146100bb57600080fd5b631a2d80ac820361010a57423660045b8181101561010857600481601c376000516004601c2061ffff6001835408806100f2575060015b91829055600483013585179101556024016100cb565b005b600080fdfea26469706673582212204a7c38e6d9b723ea65e6d451d6a8436444c333499ad610af033e7360a2558aea64736f6c63430008180033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000d756119012ccabbc59910de0ecebe406b5b952be

-----Decoded View---------------
Arg [0] : owner_ (address): 0xd756119012CcabBC59910dE0ecEbE406B5b952bE

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d756119012ccabbc59910de0ecebe406b5b952be


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.