Goerli Testnet

Contract

0x15d5678FF44883444264f7947c1c5C31d07b4482
Source Code

Overview

ETH Balance

0 ETH

Multi Chain

Multichain Addresses

0 address found via
Transaction Hash
Method
Block
From
To
Value
Execute Messages94376602023-07-31 6:47:48132 days 46 mins ago1690786068IN
0x15d567...d07b4482
0 ETH0.00000080.01037239
Execute Messages94376342023-07-31 6:41:48132 days 52 mins ago1690785708IN
0x15d567...d07b4482
0 ETH0.000003890.05000013
Execute Messages94376192023-07-31 6:37:48132 days 56 mins ago1690785468IN
0x15d567...d07b4482
0 ETH0.000000850.0103724
Execute Messages94342612023-07-30 16:13:48132 days 15 hrs ago1690733628IN
0x15d567...d07b4482
0 ETH0.000124011.50000006
0x60e0604094342222023-07-30 16:02:48132 days 15 hrs ago1690732968IN
 Contract Creation
0 ETH0.000017130.02346357

Latest 6 internal transactions

Advanced mode:
Parent Txn Hash Block From To Value
94376602023-07-31 6:47:48132 days 46 mins ago1690786068
0x15d567...d07b4482
0 ETH
94376602023-07-31 6:47:48132 days 46 mins ago1690786068
0x15d567...d07b4482
0 ETH
94376342023-07-31 6:41:48132 days 52 mins ago1690785708
0x15d567...d07b4482
0 ETH
94376342023-07-31 6:41:48132 days 52 mins ago1690785708
0x15d567...d07b4482
0 ETH
94376192023-07-31 6:37:48132 days 56 mins ago1690785468
0x15d567...d07b4482
0 ETH
94342612023-07-30 16:13:48132 days 15 hrs ago1690733628
0x15d567...d07b4482
0 ETH
Loading...
Loading

Similar Match Source Code
This contract matches the deployed Bytecode of the Source Code for Contract 0x27c646...fb75b579
The constructor portion of the code might be different and could alter the actual behaviour of the contract

Contract Name:
Yaru

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
Yes with 800 runs

Other Settings:
default evmVersion

Contract Source Code (Solidity Standard Json-Input format)

File 6 of 6 : Yaru.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.17;

import { IHashi, IOracleAdapter } from "./interfaces/IHashi.sol";
import { Message } from "./interfaces/IMessage.sol";
import { IMessageExecutor } from "./interfaces/IMessageExecutor.sol";
import { MessageHashCalculator } from "./utils/MessageHashCalculator.sol";

contract Yaru is IMessageExecutor, MessageHashCalculator {
    IHashi public immutable hashi;
    address public immutable yaho;
    uint256 public immutable chainId;
    mapping(uint256 => bool) public executed;
    address public sender;

    error ReentranceNotAllowed(address);
    error UnequalArrayLengths(address emitter);
    error AlreadyExecuted(address emitter, uint256 id);
    error InvalidSender(address emitter, address sender);
    error HashMismatch(address emitter, uint256 id, bytes32 reportedHash, bytes32 calculatedHash);
    error CallFailed(address emitter, uint256 id);

    /// @param _hashi Address of the Hashi contract.
    /// @param _yaho Address of the Yaho contract
    constructor(IHashi _hashi, address _yaho, uint256 _chainId) {
        hashi = _hashi;
        yaho = _yaho;
        chainId = _chainId;
    }

    /// @dev Executes messages validated by a given set of oracle adapters
    /// @param messages Array of messages to execute.
    /// @param messageIds Array of corresponding messageIds to query for hashes from the given oracle adapters.
    /// @param senders Array of addresses that sent the corresponding messages.
    /// @param oracleAdapters Array of oracle adapters to query.
    /// @return returnDatas Array of data returned from each executed message.
    function executeMessages(
        Message[] memory messages,
        uint256[] memory messageIds,
        address[] memory senders,
        IOracleAdapter[] memory oracleAdapters
    ) public returns (bytes[] memory) {
        if (sender != address(0)) revert ReentranceNotAllowed(address(0));
        if (messages.length != senders.length || messages.length != messageIds.length)
            revert UnequalArrayLengths(address(this));
        bytes[] memory returnDatas = new bytes[](messages.length);
        for (uint256 i = 0; i < messages.length; i++) {
            uint256 id = messageIds[i];

            if (executed[id]) revert AlreadyExecuted(address(this), id);
            if (senders[i] == address(0)) revert InvalidSender(address(this), senders[i]);

            executed[id] = true;

            Message memory message = messages[i];
            sender = senders[i];
            bytes32 reportedHash = hashi.getHash(chainId, id, oracleAdapters);
            bytes32 calculatedHash = calculateHash(chainId, id, yaho, sender, message);
            if (reportedHash != calculatedHash) revert HashMismatch(address(this), id, reportedHash, calculatedHash);

            (bool success, bytes memory returnData) = address(message.to).call(message.data);
            if (!success) revert CallFailed(address(this), id);

            delete sender;
            returnDatas[i] = returnData;
            emit MessageIdExecuted(message.toChainId, bytes32(id));
        }
        return returnDatas;
    }
}

File 2 of 6 : IHashi.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.17;

import { IOracleAdapter } from "./IOracleAdapter.sol";

interface IHashi {
    function getHash(
        uint256 domain,
        uint256 id,
        IOracleAdapter[] memory oracleAdapters
    ) external view returns (bytes32 hash);
}

File 3 of 6 : IMessage.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.17;

struct Message {
    address to;
    uint256 toChainId;
    bytes data;
}

File 4 of 6 : IMessageExecutor.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.17;

interface IMessageExecutor {
    event MessageIdExecuted(uint256 indexed fromChainId, bytes32 indexed messageId);
}

File 5 of 6 : IOracleAdapter.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.17;

interface IOracleAdapter {
    event HashStored(uint256 indexed id, bytes32 indexed hashes);

    error InvalidBlockHeaderLength(uint256 length);
    error InvalidBlockHeaderRLP();
    error ConflictingBlockHeader(uint256 blockNumber, bytes32 reportedBlockHash, bytes32 storedBlockHash);

    /// @dev Returns the hash for a given ID, as reported by the oracle.
    /// @param domain Identifier for the domain to query.
    /// @param id Identifier for the ID to query.
    /// @return hash Bytes32 hash reported by the oracle for the given ID on the given domain.
    /// @notice MUST return bytes32(0) if the oracle has not yet reported a hash for the given ID.
    function getHashFromOracle(uint256 domain, uint256 id) external view returns (bytes32 hash);
}

File 6 of 6 : MessageHashCalculator.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity ^0.8.17;

import { Message } from "../interfaces/IMessage.sol";

contract MessageHashCalculator {
    /// @dev Calculates the ID of a given message.
    /// @param chainId ID of the chain on which the message was/will be dispatched.
    /// @param id ID of the message that was/will be dispatched.
    /// @param origin Contract that did/will dispatch the given message.
    /// @param sender Sender of the message that was/will be dispatched.
    /// @param message Message that was/will be dispatched.
    function calculateHash(
        uint256 chainId,
        uint256 id,
        address origin,
        address sender,
        Message memory message
    ) public pure returns (bytes32 calculatedHash) {
        calculatedHash = keccak256(abi.encode(chainId, id, origin, sender, message));
    }
}

Settings
{
  "metadata": {
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 800
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract ABI

[{"inputs":[{"internalType":"contract IHashi","name":"_hashi","type":"address"},{"internalType":"address","name":"_yaho","type":"address"},{"internalType":"uint256","name":"_chainId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"emitter","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"AlreadyExecuted","type":"error"},{"inputs":[{"internalType":"address","name":"emitter","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"CallFailed","type":"error"},{"inputs":[{"internalType":"address","name":"emitter","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes32","name":"reportedHash","type":"bytes32"},{"internalType":"bytes32","name":"calculatedHash","type":"bytes32"}],"name":"HashMismatch","type":"error"},{"inputs":[{"internalType":"address","name":"emitter","type":"address"},{"internalType":"address","name":"sender","type":"address"}],"name":"InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ReentranceNotAllowed","type":"error"},{"inputs":[{"internalType":"address","name":"emitter","type":"address"}],"name":"UnequalArrayLengths","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromChainId","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"messageId","type":"bytes32"}],"name":"MessageIdExecuted","type":"event"},{"inputs":[{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address","name":"origin","type":"address"},{"internalType":"address","name":"sender","type":"address"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"toChainId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Message","name":"message","type":"tuple"}],"name":"calculateHash","outputs":[{"internalType":"bytes32","name":"calculatedHash","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"toChainId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct Message[]","name":"messages","type":"tuple[]"},{"internalType":"uint256[]","name":"messageIds","type":"uint256[]"},{"internalType":"address[]","name":"senders","type":"address[]"},{"internalType":"contract IOracleAdapter[]","name":"oracleAdapters","type":"address[]"}],"name":"executeMessages","outputs":[{"internalType":"bytes[]","name":"","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"executed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hashi","outputs":[{"internalType":"contract IHashi","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"yaho","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061007d5760003560e01c8063d3ecebd71161005b578063d3ecebd714610107578063ec2cf2d51461013a578063ee4937ba14610161578063f0edcc5c1461018857600080fd5b806367e404ce146100825780639a8a0592146100b2578063aafd6d65146100e7575b600080fd5b600154610095906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b6100d97f000000000000000000000000000000000000000000000000000000000000006481565b6040519081526020016100a9565b6100fa6100f5366004610898565b61019b565b6040516100a99190610a05565b61012a610115366004610a67565b60006020819052908152604090205460ff1681565b60405190151581526020016100a9565b6100957f0000000000000000000000006a948572432818debbb04a0b82b6c12ec5ca15b581565b6100957f00000000000000000000000075ff4bad26345a5b15ccae256900640373eba60181565b6100d9610196366004610a80565b610625565b6001546060906001600160a01b0316156101d05760405163d86f2cb160e01b8152600060048201526024015b60405180910390fd5b825185511415806101e357508351855114155b156102035760405163018a4ee960e01b81523060048201526024016101c7565b6000855167ffffffffffffffff81111561021f5761021f610661565b60405190808252806020026020018201604052801561025257816020015b606081526020019060019003908161023d5790505b50905060005b865181101561061b57600086828151811061027557610275610af6565b60209081029190910181015160008181529182905260409091205490915060ff16156102bd57604051634da89f7560e11b8152306004820152602481018290526044016101c7565b60006001600160a01b03168683815181106102da576102da610af6565b60200260200101516001600160a01b03160361033b573086838151811061030357610303610af6565b602002602001015160405163708986dd60e11b81526004016101c79291906001600160a01b0392831681529116602082015260400190565b6000818152602081905260408120805460ff19166001179055885189908490811061036857610368610af6565b6020026020010151905086838151811061038457610384610af6565b60209081029190910101516001805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03928316179055604051633ab489d560e21b81526000917f0000000000000000000000006a948572432818debbb04a0b82b6c12ec5ca15b5169063ead2275490610423907f00000000000000000000000000000000000000000000000000000000000000649087908c90600401610b0c565b602060405180830381865afa158015610440573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906104649190610b6a565b6001549091506000906104c6907f00000000000000000000000000000000000000000000000000000000000000649086907f00000000000000000000000075ff4bad26345a5b15ccae256900640373eba601906001600160a01b031687610625565b90508082146104ff5760405163838a8a3160e01b81523060048201526024810185905260448101839052606481018290526084016101c7565b60008084600001516001600160a01b031685604001516040516105229190610b83565b6000604051808303816000865af19150503d806000811461055f576040519150601f19603f3d011682016040523d82523d6000602084013e610564565b606091505b5091509150816105905760405163b9eaeae360e01b8152306004820152602481018790526044016101c7565b6001805473ffffffffffffffffffffffffffffffffffffffff19169055875181908990899081106105c3576105c3610af6565b60200260200101819052508560001b85602001517e769f3f82cb2a521c5b72f211aff687dae3cebd0b4631790417d1b17e15689a60405160405180910390a3505050505050808061061390610b9f565b915050610258565b5095945050505050565b60008585858585604051602001610640959493929190610bc6565b60405160208183030381529060405280519060200120905095945050505050565b634e487b7160e01b600052604160045260246000fd5b6040516060810167ffffffffffffffff8111828210171561069a5761069a610661565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156106c9576106c9610661565b604052919050565b600067ffffffffffffffff8211156106eb576106eb610661565b5060051b60200190565b6001600160a01b038116811461070a57600080fd5b50565b60006060828403121561071f57600080fd5b610727610677565b90508135610734816106f5565b815260208281013581830152604083013567ffffffffffffffff8082111561075b57600080fd5b818501915085601f83011261076f57600080fd5b81358181111561078157610781610661565b610793601f8201601f191685016106a0565b915080825286848285010111156107a957600080fd5b808484018584013760008482840101525080604085015250505092915050565b600082601f8301126107da57600080fd5b813560206107ef6107ea836106d1565b6106a0565b82815260059290921b8401810191818101908684111561080e57600080fd5b8286015b848110156108295780358352918301918301610812565b509695505050505050565b600082601f83011261084557600080fd5b813560206108556107ea836106d1565b82815260059290921b8401810191818101908684111561087457600080fd5b8286015b8481101561082957803561088b816106f5565b8352918301918301610878565b600080600080608085870312156108ae57600080fd5b843567ffffffffffffffff808211156108c657600080fd5b818701915087601f8301126108da57600080fd5b813560206108ea6107ea836106d1565b82815260059290921b8401810191818101908b84111561090957600080fd5b8286015b84811015610941578035868111156109255760008081fd5b6109338e86838b010161070d565b84525091830191830161090d565b509850508801359250508082111561095857600080fd5b610964888389016107c9565b9450604087013591508082111561097a57600080fd5b61098688838901610834565b9350606087013591508082111561099c57600080fd5b506109a987828801610834565b91505092959194509250565b60005b838110156109d05781810151838201526020016109b8565b50506000910152565b600081518084526109f18160208601602086016109b5565b601f01601f19169290920160200192915050565b6000602080830181845280855180835260408601915060408160051b870101925083870160005b82811015610a5a57603f19888603018452610a488583516109d9565b94509285019290850190600101610a2c565b5092979650505050505050565b600060208284031215610a7957600080fd5b5035919050565b600080600080600060a08688031215610a9857600080fd5b85359450602086013593506040860135610ab1816106f5565b92506060860135610ac1816106f5565b9150608086013567ffffffffffffffff811115610add57600080fd5b610ae98882890161070d565b9150509295509295909350565b634e487b7160e01b600052603260045260246000fd5b6000606082018583526020858185015260606040850152818551808452608086019150828701935060005b81811015610b5c5784516001600160a01b031683529383019391830191600101610b37565b509098975050505050505050565b600060208284031215610b7c57600080fd5b5051919050565b60008251610b958184602087016109b5565b9190910192915050565b600060018201610bbf57634e487b7160e01b600052601160045260246000fd5b5060010190565b85815284602082015260006001600160a01b038086166040840152808516606084015260a060808401528084511660a084015250602083015160c08301526040830151606060e0840152610c1e6101008401826109d9565b9897505050505050505056fea164736f6c6343000811000a

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

Txn Hash Block Value Eth2 PubKey Valid
View All Deposits
[ Download: CSV Export  ]
[ 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.