ETH Price: $2,093.50 (+1.99%)
 

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

Please try again later

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
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

Contract Source Code Verified (Exact Match)

Contract Name:
LlamaGuardOracleProxy

Compiler Version
v0.8.27+commit.40a35a09

Optimization Enabled:
Yes with 10000 runs

Other Settings:
shanghai EvmVersion
// SPDX-License-Identifier: BUSL-1.1
pragma solidity ^0.8.27;

import { ILlamaGuardOracle } from "./interfaces/ILlamaGuardOracle.sol";
import { AbstractCreReceiver } from "./abstracts/AbstractCreReceiver.sol";
import { Ownable2Step, Ownable } from "@openzeppelin/contracts/access/Ownable2Step.sol";

/**
 * @title LlamaGuardOracleProxy
 * @notice Proxy contract that receives Chainlink CRE workflow reports and forwards them to LlamaGuardOracle
 * @dev Extends AbstractCreReceiver for workflow validation and Ownable2Step for secure ownership management.
 *      Acts as an intermediary between Chainlink CRE workflows and the LlamaGuardOracle, decoding incoming
 *      reports and calling updateLatestRiskRoundData on the oracle.
 */
contract LlamaGuardOracleProxy is Ownable2Step, AbstractCreReceiver {
    // ═══════════════════════════════════════════════════════════════════════════
    // STATE VARIABLES
    // ═══════════════════════════════════════════════════════════════════════════

    /// @notice The LlamaGuard oracle instance that receives decoded risk parameter updates
    ILlamaGuardOracle public llamaguardOracle;

    /// @notice Human-readable description of this proxy instance
    string public description;

    // ═══════════════════════════════════════════════════════════════════════════
    // ERRORS
    // ═══════════════════════════════════════════════════════════════════════════

    /// @notice Thrown when the provided LlamaGuard oracle address is invalid or lacks write access for this proxy
    error InvalidLlamaGuardOracle();

    // ═══════════════════════════════════════════════════════════════════════════
    // CONSTRUCTOR
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * @notice Initializes the proxy with oracle address and workflow configuration
     * @param llamaGuardOracleAddress Address of the LlamaGuardOracle contract (must be non-zero)
     * @param workflowId The Chainlink CRE workflow ID to accept reports from
     * @param expectedForwarder The expected forwarder address for workflow validation
     * @param expectedAuthor The expected author address for workflow validation
     * @param expectedWorkflowName The expected workflow name for validation
     * @param _description Human-readable description of this proxy instance
     * @param isReportWriteSecured_ Whether to enforce report metadata checks
     */
    constructor(
        address llamaGuardOracleAddress,
        bytes32 workflowId,
        address expectedForwarder,
        address expectedAuthor,
        bytes10 expectedWorkflowName,
        string memory _description,
        bool isReportWriteSecured_
    )
        Ownable(msg.sender)
        AbstractCreReceiver(
            workflowId,
            expectedForwarder,
            expectedAuthor,
            expectedWorkflowName,
            isReportWriteSecured_
        )
    {
        require(llamaGuardOracleAddress != address(0), InvalidLlamaGuardOracle());

        llamaguardOracle = ILlamaGuardOracle(llamaGuardOracleAddress);
        description = _description;
    }

    /// @inheritdoc AbstractCreReceiver
    function _processReport(bytes calldata report) internal override {
        // Decode the report directly into UpdateInput struct
        ILlamaGuardOracle.UpdateInput memory input = abi.decode(report, (ILlamaGuardOracle.UpdateInput));

        llamaguardOracle.updateLatestRiskRoundData(input);
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // ADMIN FUNCTIONS
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * @notice Updates the LlamaGuard oracle address
     * @dev The new oracle must grant WRITER_ROLE to this proxy before calling this function
     * @param newLlamaGuardOracle Address of the new LlamaGuardOracle contract
     */
    function setLlamaGuardOracle(address newLlamaGuardOracle) external onlyOwner {
        ILlamaGuardOracle newLlamaguardOracle = ILlamaGuardOracle(newLlamaGuardOracle);
        require(newLlamaguardOracle.hasWriteAccess(address(this)), InvalidLlamaGuardOracle());
        llamaguardOracle = newLlamaguardOracle;
    }

    /// @notice Set or update workflow configuration
    /// @param workflowId The workflow ID to configure
    /// @param expectedForwarder The expected forwarder address
    /// @param expectedAuthor The expected author address
    /// @param expectedWorkflowName The expected workflow name
    /// @param isActive Whether the workflow is active
    function setWorkflowConfig(
        bytes32 workflowId,
        address expectedForwarder,
        address expectedAuthor,
        bytes10 expectedWorkflowName,
        bool isActive
    )
        external
        onlyOwner
    {
        workflowConfigs[workflowId] = WorkflowConfig({
            expectedForwarder: expectedForwarder,
            expectedAuthor: expectedAuthor,
            expectedWorkflowName: expectedWorkflowName,
            isActive: isActive
        });

        emit WorkflowConfigUpdated(workflowId, expectedForwarder, expectedAuthor, expectedWorkflowName, isActive);
    }

    /// @notice Activate or deactivate a workflow
    /// @param workflowId The workflow ID to update
    /// @param isActive Whether the workflow should be active
    function setWorkflowActive(bytes32 workflowId, bool isActive) external onlyOwner {
        WorkflowConfig storage config = workflowConfigs[workflowId];
        config.isActive = isActive;

        emit WorkflowConfigUpdated(
            workflowId, config.expectedForwarder, config.expectedAuthor, config.expectedWorkflowName, isActive
        );
    }
}

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

/**
 * @title ILlamaGuardOracle
 * @notice Interface for LlamaGuard Oracle combining Chainlink AggregatorV3
 * @dev Implements risk parameter update history with update type validation
 */
interface ILlamaGuardOracle {
    // ═══════════════════════════════════════════════════════════════════════════
    // STRUCTS
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * @notice Structure for storing risk parameter updates
     */
    struct RiskParameterUpdate {
        uint256 timestamp; // Timestamp of the update
        bytes newValue; // ABI-encoded price (int256) for Chainlink AggregatorV3 compatibility
        string referenceId; // External reference, potentially linking to off-chain data
        bytes previousValue; // Previous newValue (price) for historical comparison
        string updateType; // Classification of the update for validation purposes
        uint256 updateId; // Unique identifier (equals roundId)
        address market; // Address for market of the parameter update
        bytes additionalData; // ABI-encoded tuple: (uint256 supply, int256 price, uint256 state)
    }

    /**
     * @notice Structure for update input data
     * @dev Used as input parameter for updateLatestRiskRoundData function to enable single-struct external calls
     */
    struct UpdateInput {
        string referenceId; // External reference ID for the update
        bytes newValue; // ABI-encoded price (int256) - used as the Chainlink round answer
        string updateType; // Classification of the update for validation purposes (must be authorized)
        bytes additionalData; // ABI-encoded tuple (uint256 supply, int256 price, uint256 state)
    }

    // ═══════════════════════════════════════════════════════════════════════════
    // EVENTS
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * @notice Emitted when a parameter update is recorded
     */
    event ParameterUpdated(
        string referenceId,
        bytes newValue,
        bytes previousValue,
        uint256 timestamp,
        string indexed updateType,
        uint256 indexed updateId,
        bytes additionalData
    );

    /**
     * @notice Emitted when a new update type is added
     */
    event UpdateTypeAdded(string indexed updateType);

    // ═══════════════════════════════════════════════════════════════════════════
    // ERRORS
    // ═══════════════════════════════════════════════════════════════════════════

    /// @notice Thrown when an unauthorized update type is used
    error UnauthorizedUpdateType(string updateType);

    /// @notice Thrown when update type string is invalid (empty or too long)
    error InvalidUpdateTypeString(string updateType);

    /// @notice Thrown when attempting to add a duplicate update type
    error UpdateTypeAlreadyExists(string updateType);

    /// @notice Thrown when querying an invalid update ID
    error InvalidUpdateId(uint256 updateId);

    /// @notice Thrown when attempting to update/query an unauthorized market
    error UnauthorizedMarket(address market);

    /// @notice Thrown when market address is address(0)
    error InvalidMarketAddress(address market);

    /// @notice Thrown when attempting to add a market that is already authorized
    error MarketAlreadyAuthorized(address market);

    /// @notice Thrown when attempting to remove a market that is not authorized
    error MarketNotFound(address market);

    // ═══════════════════════════════════════════════════════════════════════════
    // EVENTS - Market Authorization
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * @notice Emitted when a market is added to the authorized list
     * @param market Address of the newly authorized market
     */
    event AuthorizedMarketAdded(address indexed market);

    /**
     * @notice Emitted when a market is removed from the authorized list
     * @param market Address of the deauthorized market
     */
    event AuthorizedMarketRemoved(address indexed market);

    // ═══════════════════════════════════════════════════════════════════════════
    // MUTATORS
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * @notice Update the oracle with new risk round data
     * @dev Only callable by addresses with WRITER_ROLE.
     *      input.newValue contains ABI-encoded price (int256) for Chainlink AggregatorV3 compatibility.
     *      input.additionalData contains the full data bundle: abi.encode(uint256 supply, int256 price, uint256 state).
     * @param input UpdateInput struct containing referenceId, newValue, updateType, and additionalData
     */
    function updateLatestRiskRoundData(UpdateInput calldata input) external;

    /**
     * @notice Add a new authorized update type
     * @dev Only callable by owner/admin
     * @param newUpdateType The update type string to authorize (1-64 chars)
     */
    function addUpdateType(string calldata newUpdateType) external;

    // ═══════════════════════════════════════════════════════════════════════════
    // VIEWS
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * @notice Fetch an update record by its ID
     * @param updateId The unique update identifier (equals roundId)
     * @return The RiskParameterUpdate struct for the specified ID
     */
    function getUpdateById(uint256 updateId) external view returns (RiskParameterUpdate memory);

    /**
     * @notice Check if an address has write access
     * @param account The address to check
     * @return True if the address has WRITER_ROLE
     */
    function hasWriteAccess(address account) external view returns (bool);

    /**
     * @notice Check if an update type is valid
     * @param updateType The update type string to check
     * @return True if the update type is authorized
     */
    function isValidUpdateType(string calldata updateType) external view returns (bool);

    /**
     * @notice Fetches the most recent update for a specific parameter type
     * @dev Reverts with InvalidUpdateId(0) if no update exists for the updateType.
     *      The input market address will be rewritten to the returned RiskParameterUpdate.market field.
     * @param updateType The parameter type identifier (e.g., "price", "supply", "risk_state")
     * @param market The market address to be written to the returned RiskParameterUpdate.market field
     * @return The most recent RiskParameterUpdate for the specified updateType,
     *         with the market field set to the input market address
     */
    function getLatestUpdateByParameterAndMarket(
        string calldata updateType,
        address market
    )
        external
        view
        returns (RiskParameterUpdate memory);

    // ═══════════════════════════════════════════════════════════════════════════
    // MARKET AUTHORIZATION FUNCTIONS
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * @notice Add a market address to the authorized list
     * @dev Restricted to DEFAULT_ADMIN_ROLE
     * @param market Address of the market to authorize (must be non-zero)
     */
    function addAuthorizedMarket(address market) external;

    /**
     * @notice Remove a market address from the authorized list
     * @dev Restricted to DEFAULT_ADMIN_ROLE
     * @param market Address of the market to deauthorize
     */
    function removeAuthorizedMarket(address market) external;

    /**
     * @notice Check if a market address is authorized
     * @param market Address to check
     * @return bool True if market is authorized, false otherwise
     */
    function isAuthorizedMarket(address market) external view returns (bool);
}

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

import { IReceiver } from "@chainlink/contracts/src/v0.8/keystone/interfaces/IReceiver.sol";
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";

/// @title AbstractCreReceiver - Abstract receiver with workflow validation and metadata decoding
/// @notice Supports multiple workflows via a mapping from workflow ID to configuration
abstract contract AbstractCreReceiver is IReceiver {
    /// @notice Configuration for a workflow
    struct WorkflowConfig {
        address expectedForwarder;
        address expectedAuthor;
        bytes10 expectedWorkflowName;
        bool isActive;
    }

    /// @notice Mapping from workflow ID to its configuration
    mapping(bytes32 workflowId => WorkflowConfig) public workflowConfigs;

    /// @notice Whether to enforce metadata/forwarder checks before processing.
    bool public immutable isReportWriteSecured;

    // ═══════════════════════════════════════════════════════════════════════════
    // ERRORS
    // ═══════════════════════════════════════════════════════════════════════════

    /// @notice Thrown when the workflow author in metadata doesn't match the expected author
    error InvalidAuthor(address received, address expected);

    /// @notice Thrown when the workflow name in metadata doesn't match the expected name
    error InvalidWorkflowName(bytes10 received, bytes10 expected);

    /// @notice Thrown when the workflow ID is not configured in the workflowConfigs mapping
    error InvalidWorkflowId(bytes32 workflowId);

    /// @notice Thrown when msg.sender doesn't match the expected forwarder for the workflow
    error InvalidForwarder(address received, address expected);

    /// @notice Thrown when attempting to process a report for an inactive workflow
    error WorkflowNotActive(bytes32 workflowId);

    // ═══════════════════════════════════════════════════════════════════════════
    // EVENTS
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * @notice Emitted when a workflow configuration is created or updated
     * @param workflowId The unique identifier of the workflow
     * @param expectedForwarder The forwarder address authorized to submit reports
     * @param expectedAuthor The author address expected in report metadata
     * @param expectedWorkflowName The workflow name expected in report metadata
     * @param isActive Whether the workflow is enabled for report processing
     */
    event WorkflowConfigUpdated(
        bytes32 indexed workflowId,
        address expectedForwarder,
        address expectedAuthor,
        bytes10 expectedWorkflowName,
        bool isActive
    );

    // ═══════════════════════════════════════════════════════════════════════════
    // CONSTRUCTOR
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * @notice Initializes the receiver with a single workflow configuration
     * @param workflowId The Chainlink CRE workflow ID to configure
     * @param expectedForwarder The forwarder address authorized to submit reports
     * @param expectedAuthor The author address expected in report metadata
     * @param expectedWorkflowName The workflow name expected in report metadata
     * @param isReportWriteSecured_ Whether to enforce report metadata checks
     */
    constructor(
        bytes32 workflowId,
        address expectedForwarder,
        address expectedAuthor,
        bytes10 expectedWorkflowName,
        bool isReportWriteSecured_
    )
    {
        isReportWriteSecured = isReportWriteSecured_;
        workflowConfigs[workflowId] = WorkflowConfig({
            expectedForwarder: expectedForwarder,
            expectedAuthor: expectedAuthor,
            expectedWorkflowName: expectedWorkflowName,
            isActive: true
        });

        emit WorkflowConfigUpdated(workflowId, expectedForwarder, expectedAuthor, expectedWorkflowName, true);
    }

    /// @inheritdoc IReceiver
    function onReport(bytes calldata metadata, bytes calldata report) external override {
        if (isReportWriteSecured) {
            (bytes32 workflowId, address workflowOwner, bytes10 workflowName) = _getWorkflowMetaData(metadata);

            WorkflowConfig storage config = workflowConfigs[workflowId];

            // Check if workflow exists and is active
            if (!config.isActive) {
                revert WorkflowNotActive(workflowId);
            }

            if (msg.sender != config.expectedForwarder) {
                revert InvalidForwarder(msg.sender, config.expectedForwarder);
            }

            if (workflowOwner != config.expectedAuthor) {
                revert InvalidAuthor(workflowOwner, config.expectedAuthor);
            }

            if (workflowName != config.expectedWorkflowName) {
                revert InvalidWorkflowName(workflowName, config.expectedWorkflowName);
            }
        }

        _processReport(report);
    }

    /// @notice Extracts the workflow name and the workflow owner from the metadata parameter of onReport
    /// @param metadata The metadata in bytes format
    /// @return workflowId The id of the workflow
    /// @return workflowOwner The owner of the workflow
    /// @return workflowName  The name of the workflow
    function _getWorkflowMetaData(bytes memory metadata)
        internal
        pure
        returns (bytes32 workflowId, address workflowOwner, bytes10 workflowName)
    {
        assembly {
            workflowId := mload(add(metadata, 32))
            workflowName := mload(add(metadata, 64))
            workflowOwner := shr(96, mload(add(metadata, 74)))
        }
    }

    /// @notice Get workflow configuration by ID
    /// @param workflowId The workflow ID to query
    /// @return config The workflow configuration
    function getWorkflowConfig(bytes32 workflowId) external view returns (WorkflowConfig memory) {
        return workflowConfigs[workflowId];
    }

    /// @notice Check if a workflow is active
    /// @param workflowId The workflow ID to check
    /// @return True if the workflow is active
    function isWorkflowActive(bytes32 workflowId) external view returns (bool) {
        return workflowConfigs[workflowId].isActive;
    }

    /// @notice Abstract function to process the report
    /// @param report The report calldata
    function _processReport(bytes calldata report) internal virtual;

    // ═══════════════════════════════════════════════════════════════════════════
    // ERC165 SUPPORT
    // ═══════════════════════════════════════════════════════════════════════════

    /**
     * @notice Checks if the contract supports a given interface
     * @param interfaceId The interface identifier to check (ERC-165)
     * @return True if the contract supports the interface (IReceiver or IERC165)
     */
    function supportsInterface(bytes4 interfaceId) public pure virtual override returns (bool) {
        return interfaceId == type(IReceiver).interfaceId || interfaceId == type(IERC165).interfaceId;
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (access/Ownable2Step.sol)

pragma solidity ^0.8.20;

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

/**
 * @dev Contract module which provides access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * This extension of the {Ownable} contract includes a two-step mechanism to transfer
 * ownership, where the new owner must call {acceptOwnership} in order to replace the
 * old one. This can help prevent common mistakes, such as transfers of ownership to
 * incorrect accounts, or to contracts that are unable to interact with the
 * permission system.
 *
 * The initial owner is specified at deployment time in the constructor for `Ownable`. This
 * can later be changed with {transferOwnership} and {acceptOwnership}.
 *
 * This module is used through inheritance. It will make available all functions
 * from parent (Ownable).
 */
abstract contract Ownable2Step is Ownable {
    address private _pendingOwner;

    event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Returns the address of the pending owner.
     */
    function pendingOwner() public view virtual returns (address) {
        return _pendingOwner;
    }

    /**
     * @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
     * Can only be called by the current owner.
     *
     * Setting `newOwner` to the zero address is allowed; this can be used to cancel an initiated ownership transfer.
     */
    function transferOwnership(address newOwner) public virtual override onlyOwner {
        _pendingOwner = newOwner;
        emit OwnershipTransferStarted(owner(), newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual override {
        delete _pendingOwner;
        super._transferOwnership(newOwner);
    }

    /**
     * @dev The new owner accepts the ownership transfer.
     */
    function acceptOwnership() public virtual {
        address sender = _msgSender();
        if (pendingOwner() != sender) {
            revert OwnableUnauthorizedAccount(sender);
        }
        _transferOwnership(sender);
    }
}

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import {IERC165} from "../../vendor/openzeppelin-solidity/v5.0.2/contracts/utils/introspection/IERC165.sol";

/// @title IReceiver - receives keystone reports
/// @notice Implementations must support the IReceiver interface through ERC165.
interface IReceiver is IERC165 {
  /// @notice Handles incoming keystone reports.
  /// @dev If this function call reverts, it can be retried with a higher gas
  /// limit. The receiver is responsible for discarding stale reports.
  /// @param metadata Report's metadata.
  /// @param report Workflow report.
  function onReport(bytes calldata metadata, bytes calldata report) external;
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[ERC].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {Context} from "../utils/Context.sol";

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * The initial owner is set to the address provided by the deployer. This can
 * later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby disabling any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

Settings
{
  "remappings": [
    "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
    "forge-std/=node_modules/forge-std/src/",
    "@chainlink/contracts/=node_modules/@chainlink/contracts/",
    "chaos-agents/=node_modules/chaos-agents/src/",
    "openzeppelin-contracts/contracts/=node_modules/@openzeppelin/contracts-v5/",
    "openzeppelin-contracts-upgradeable/contracts/=node_modules/@openzeppelin/contracts-upgradeable-v5/",
    "aave-v3-horizon/=node_modules/@aave-dao/aave-v3-horizon/",
    "@aave-dao/=node_modules/@aave-dao/",
    "@arbitrum/=node_modules/@arbitrum/",
    "@bgd-labs/=node_modules/@bgd-labs/",
    "@eth-optimism/=node_modules/@eth-optimism/",
    "@offchainlabs/=node_modules/@offchainlabs/",
    "@scroll-tech/=node_modules/@scroll-tech/",
    "@zksync/=node_modules/@zksync/",
    "solady/=node_modules/solady/",
    "solidity-utils/=node_modules/chaos-agents/lib/solidity-utils/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 10000
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "none",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "shanghai",
  "viaIR": false
}

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"llamaGuardOracleAddress","type":"address"},{"internalType":"bytes32","name":"workflowId","type":"bytes32"},{"internalType":"address","name":"expectedForwarder","type":"address"},{"internalType":"address","name":"expectedAuthor","type":"address"},{"internalType":"bytes10","name":"expectedWorkflowName","type":"bytes10"},{"internalType":"string","name":"_description","type":"string"},{"internalType":"bool","name":"isReportWriteSecured_","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"received","type":"address"},{"internalType":"address","name":"expected","type":"address"}],"name":"InvalidAuthor","type":"error"},{"inputs":[{"internalType":"address","name":"received","type":"address"},{"internalType":"address","name":"expected","type":"address"}],"name":"InvalidForwarder","type":"error"},{"inputs":[],"name":"InvalidLlamaGuardOracle","type":"error"},{"inputs":[{"internalType":"bytes32","name":"workflowId","type":"bytes32"}],"name":"InvalidWorkflowId","type":"error"},{"inputs":[{"internalType":"bytes10","name":"received","type":"bytes10"},{"internalType":"bytes10","name":"expected","type":"bytes10"}],"name":"InvalidWorkflowName","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"bytes32","name":"workflowId","type":"bytes32"}],"name":"WorkflowNotActive","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"workflowId","type":"bytes32"},{"indexed":false,"internalType":"address","name":"expectedForwarder","type":"address"},{"indexed":false,"internalType":"address","name":"expectedAuthor","type":"address"},{"indexed":false,"internalType":"bytes10","name":"expectedWorkflowName","type":"bytes10"},{"indexed":false,"internalType":"bool","name":"isActive","type":"bool"}],"name":"WorkflowConfigUpdated","type":"event"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"description","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"workflowId","type":"bytes32"}],"name":"getWorkflowConfig","outputs":[{"components":[{"internalType":"address","name":"expectedForwarder","type":"address"},{"internalType":"address","name":"expectedAuthor","type":"address"},{"internalType":"bytes10","name":"expectedWorkflowName","type":"bytes10"},{"internalType":"bool","name":"isActive","type":"bool"}],"internalType":"struct AbstractCreReceiver.WorkflowConfig","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReportWriteSecured","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"workflowId","type":"bytes32"}],"name":"isWorkflowActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"llamaguardOracle","outputs":[{"internalType":"contract ILlamaGuardOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"metadata","type":"bytes"},{"internalType":"bytes","name":"report","type":"bytes"}],"name":"onReport","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newLlamaGuardOracle","type":"address"}],"name":"setLlamaGuardOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"workflowId","type":"bytes32"},{"internalType":"bool","name":"isActive","type":"bool"}],"name":"setWorkflowActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"workflowId","type":"bytes32"},{"internalType":"address","name":"expectedForwarder","type":"address"},{"internalType":"address","name":"expectedAuthor","type":"address"},{"internalType":"bytes10","name":"expectedWorkflowName","type":"bytes10"},{"internalType":"bool","name":"isActive","type":"bool"}],"name":"setWorkflowConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"workflowId","type":"bytes32"}],"name":"workflowConfigs","outputs":[{"internalType":"address","name":"expectedForwarder","type":"address"},{"internalType":"address","name":"expectedAuthor","type":"address"},{"internalType":"bytes10","name":"expectedWorkflowName","type":"bytes10"},{"internalType":"bool","name":"isActive","type":"bool"}],"stateMutability":"view","type":"function"}]

60a060405234801561000f575f5ffd5b50604051611aaa380380611aaa83398101604081905261002e9161027f565b8585858584338061005857604051631e4fbdf760e01b81525f600482015260240160405180910390fd5b610061816101d6565b5080151560809081526040805191820181526001600160a01b03808716835285811660208085019182526001600160b01b031987168585019081526001606087018181525f8d8152600290945292869020965187549086166001600160a01b031990911617875592519583018054915192511515600160f01b0260ff60f01b1960b09490941c600160a01b026001600160f01b031990931697909516969096171716919091179092555186917f2b064f441dd44982f23715878bcf0128a150601864482118ed9c867b3924c3199161016c918891889188916001600160a01b0394851681529290931660208301526001600160b01b0319166040820152901515606082015260800190565b60405180910390a25050506001600160a01b03891691506101a290505760405163f105a73560e01b815260040160405180910390fd5b600380546001600160a01b0319166001600160a01b03891617905560046101c98382610435565b50505050505050506104ef565b600180546001600160a01b03191690556101ef816101f2565b50565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80516001600160a01b0381168114610257575f5ffd5b919050565b634e487b7160e01b5f52604160045260245ffd5b80518015158114610257575f5ffd5b5f5f5f5f5f5f5f60e0888a031215610295575f5ffd5b61029e88610241565b9650602088015195506102b360408901610241565b94506102c160608901610241565b60808901519094506001600160b01b0319811681146102de575f5ffd5b60a08901519093506001600160401b038111156102f9575f5ffd5b88015f601f82018b1361030a575f5ffd5b81516001600160401b038111156103235761032361025c565b604051601f8201601f19908116603f011681016001600160401b03811182821017156103515761035161025c565b6040528181528382016020018d1015610368575f5ffd5b5f5b828110156103865760208186018101518383018201520161036a565b505f9181016020019190915293506103a391505060c08901610270565b905092959891949750929550565b600181811c908216806103c557607f821691505b6020821081036103e357634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111561043057805f5260205f20601f840160051c8101602085101561040e5750805b601f840160051c820191505b8181101561042d575f815560010161041a565b50505b505050565b81516001600160401b0381111561044e5761044e61025c565b6104628161045c84546103b1565b846103e9565b6020601f821160018114610494575f831561047d5750848201515b5f19600385901b1c1916600184901b17845561042d565b5f84815260208120601f198516915b828110156104c357878501518255602094850194600190920191016104a3565b50848210156104e057868401515f19600387901b60f8161c191681555b50505050600190811b01905550565b60805161159c61050e5f395f818161026a0152610885015261159c5ff3fe608060405234801561000f575f5ffd5b50600436106100fb575f3560e01c8063805f213211610093578063e30c397811610063578063e30c39781461049a578063eb29b17c146104b8578063f2fde38b146104cb578063fec936af146104de575f5ffd5b8063805f2132146102b157806384d26ae9146102c45780638da5cb5b14610436578063e2d44dcc14610453575f5ffd5b80635bb6ba46116100ce5780635bb6ba4614610265578063715018a61461028c5780637284e4161461029457806379ba5097146102a9575f5ffd5b806301ffc9a7146100ff578063232e392a14610127578063387b13511461013c578063399dae7814610181575b5f5ffd5b61011261010d366004610fd9565b6104f1565b60405190151581526020015b60405180910390f35b61013a610135366004611054565b610589565b005b60035461015c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011e565b61020461018f3660046110d8565b60026020525f90815260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff9182169181169074010000000000000000000000000000000000000000810460b01b907e01000000000000000000000000000000000000000000000000000000000000900460ff1684565b6040805173ffffffffffffffffffffffffffffffffffffffff95861681529490931660208501527fffffffffffffffffffff00000000000000000000000000000000000000000000909116918301919091521515606082015260800161011e565b6101127f000000000000000000000000000000000000000000000000000000000000000081565b61013a610768565b61029c61077b565b60405161011e9190611150565b61013a610807565b61013a6102bf3660046111a7565b610883565b6103af6102d23660046110d8565b604080516080810182525f808252602082018190529181018290526060810191909152505f908152600260209081526040918290208251608081018452815473ffffffffffffffffffffffffffffffffffffffff90811682526001909201549182169281019290925274010000000000000000000000000000000000000000810460b01b7fffffffffffffffffffff0000000000000000000000000000000000000000000016928201929092527e0100000000000000000000000000000000000000000000000000000000000090910460ff161515606082015290565b60405161011e91905f60808201905073ffffffffffffffffffffffffffffffffffffffff835116825273ffffffffffffffffffffffffffffffffffffffff60208401511660208301527fffffffffffffffffffff00000000000000000000000000000000000000000000604084015116604083015260608301511515606083015292915050565b5f5473ffffffffffffffffffffffffffffffffffffffff1661015c565b6101126104613660046110d8565b5f908152600260205260409020600101547e01000000000000000000000000000000000000000000000000000000000000900460ff1690565b60015473ffffffffffffffffffffffffffffffffffffffff1661015c565b61013a6104c6366004611213565b610b30565b61013a6104d9366004611241565b610c6d565b61013a6104ec366004611241565b610d1c565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f805f213200000000000000000000000000000000000000000000000000000000148061058357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b610591610e30565b6040805160808101825273ffffffffffffffffffffffffffffffffffffffff808716825285811660208084019182527fffffffffffffffffffff000000000000000000000000000000000000000000008716848601908152861515606086019081525f8c8152600290935291869020945185549085167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161785559151600190940180549251915115157e01000000000000000000000000000000000000000000000000000000000000027fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60b09390931c74010000000000000000000000000000000000000000027fffff000000000000000000000000000000000000000000000000000000000000909416959094169490941791909117161790555185907f2b064f441dd44982f23715878bcf0128a150601864482118ed9c867b3924c3199061075990879087908790879073ffffffffffffffffffffffffffffffffffffffff94851681529290931660208301527fffffffffffffffffffff00000000000000000000000000000000000000000000166040820152901515606082015260800190565b60405180910390a25050505050565b610770610e30565b6107795f610e82565b565b600480546107889061125a565b80601f01602080910402602001604051908101604052809291908181526020018280546107b49061125a565b80156107ff5780601f106107d6576101008083540402835291602001916107ff565b820191905f5260205f20905b8154815290600101906020018083116107e257829003601f168201915b505050505081565b600154339073ffffffffffffffffffffffffffffffffffffffff168114610877576040517f118cdaa700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b61088081610e82565b50565b7f000000000000000000000000000000000000000000000000000000000000000015610b20575f5f5f6108ea87878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250610eb392505050565b5f83815260026020526040902060018101549396509194509250907e01000000000000000000000000000000000000000000000000000000000000900460ff16610963576040517f6420bb8e0000000000000000000000000000000000000000000000000000000081526004810185905260240161086e565b805473ffffffffffffffffffffffffffffffffffffffff1633146109d45780546040517f0962e84200000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161086e565b600181015473ffffffffffffffffffffffffffffffffffffffff848116911614610a505760018101546040517fb8a98af800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8086166004830152909116602482015260440161086e565b60018101547fffffffffffffffffffff000000000000000000000000000000000000000000008381167401000000000000000000000000000000000000000090920460b01b1614610b1b5760018101546040517f6c4609a60000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffff0000000000000000000000000000000000000000000084811660048301527401000000000000000000000000000000000000000090920460b01b909116602482015260440161086e565b505050505b610b2a8282610ecf565b50505050565b610b38610e30565b5f82815260026020526040908190206001810180548415157e01000000000000000000000000000000000000000000000000000000000000027fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821681179283905583549451939487947f2b064f441dd44982f23715878bcf0128a150601864482118ed9c867b3924c31994610c609473ffffffffffffffffffffffffffffffffffffffff9384169484169316929092179174010000000000000000000000000000000000000000900460b01b90889073ffffffffffffffffffffffffffffffffffffffff94851681529290931660208301527fffffffffffffffffffff00000000000000000000000000000000000000000000166040820152901515606082015260800190565b60405180910390a2505050565b610c75610e30565b6001805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff00000000000000000000000000000000000000009091168117909155610cd75f5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b610d24610e30565b6040517ff7c1ec9f000000000000000000000000000000000000000000000000000000008152306004820152819073ffffffffffffffffffffffffffffffffffffffff82169063f7c1ec9f90602401602060405180830381865afa158015610d8e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610db291906112ab565b610de8576040517ff105a73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610779576040517f118cdaa700000000000000000000000000000000000000000000000000000000815233600482015260240161086e565b600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905561088081610f65565b60208101516040820151604a90920151909260609190911c9190565b5f610edc828401846113cb565b6003546040517f7890626800000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690637890626890610f339084906004016114b8565b5f604051808303815f87803b158015610f4a575f5ffd5b505af1158015610f5c573d5f5f3e3d5ffd5b50505050505050565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f60208284031215610fe9575f5ffd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611018575f5ffd5b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611042575f5ffd5b919050565b8015158114610880575f5ffd5b5f5f5f5f5f60a08688031215611068575f5ffd5b853594506110786020870161101f565b93506110866040870161101f565b925060608601357fffffffffffffffffffff00000000000000000000000000000000000000000000811681146110ba575f5ffd5b915060808601356110ca81611047565b809150509295509295909350565b5f602082840312156110e8575f5ffd5b5035919050565b5f81518084525f5b81811015611113576020818501810151868301820152016110f7565b505f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f61101860208301846110ef565b5f5f83601f840112611172575f5ffd5b50813567ffffffffffffffff811115611189575f5ffd5b6020830191508360208285010111156111a0575f5ffd5b9250929050565b5f5f5f5f604085870312156111ba575f5ffd5b843567ffffffffffffffff8111156111d0575f5ffd5b6111dc87828801611162565b909550935050602085013567ffffffffffffffff8111156111fb575f5ffd5b61120787828801611162565b95989497509550505050565b5f5f60408385031215611224575f5ffd5b82359150602083013561123681611047565b809150509250929050565b5f60208284031215611251575f5ffd5b6110188261101f565b600181811c9082168061126e57607f821691505b6020821081036112a5577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b5f602082840312156112bb575f5ffd5b815161101881611047565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516080810167ffffffffffffffff81118282101715611316576113166112c6565b60405290565b5f82601f83011261132b575f5ffd5b8135602083015f5f67ffffffffffffffff84111561134b5761134b6112c6565b506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85018116603f0116810181811067ffffffffffffffff82111715611398576113986112c6565b6040528381529050808284018710156113af575f5ffd5b838360208301375f602085830101528094505050505092915050565b5f602082840312156113db575f5ffd5b813567ffffffffffffffff8111156113f1575f5ffd5b820160808185031215611402575f5ffd5b61140a6112f3565b813567ffffffffffffffff811115611420575f5ffd5b61142c8682850161131c565b825250602082013567ffffffffffffffff811115611448575f5ffd5b6114548682850161131c565b602083015250604082013567ffffffffffffffff811115611473575f5ffd5b61147f8682850161131c565b604083015250606082013567ffffffffffffffff81111561149e575f5ffd5b6114aa8682850161131c565b606083015250949350505050565b602081525f8251608060208401526114d360a08401826110ef565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261150e82826110ef565b91505060408401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301606085015261154a82826110ef565b91505060608401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301608085015261158682826110ef565b9594505050505056fea164736f6c634300081b000a000000000000000000000000eb28cddcbe782b84f33668c3423ae5b070db971a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c4c6c616d6147756172642055535442204f7261636c652050726f787900000000

Deployed Bytecode

0x608060405234801561000f575f5ffd5b50600436106100fb575f3560e01c8063805f213211610093578063e30c397811610063578063e30c39781461049a578063eb29b17c146104b8578063f2fde38b146104cb578063fec936af146104de575f5ffd5b8063805f2132146102b157806384d26ae9146102c45780638da5cb5b14610436578063e2d44dcc14610453575f5ffd5b80635bb6ba46116100ce5780635bb6ba4614610265578063715018a61461028c5780637284e4161461029457806379ba5097146102a9575f5ffd5b806301ffc9a7146100ff578063232e392a14610127578063387b13511461013c578063399dae7814610181575b5f5ffd5b61011261010d366004610fd9565b6104f1565b60405190151581526020015b60405180910390f35b61013a610135366004611054565b610589565b005b60035461015c9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011e565b61020461018f3660046110d8565b60026020525f90815260409020805460019091015473ffffffffffffffffffffffffffffffffffffffff9182169181169074010000000000000000000000000000000000000000810460b01b907e01000000000000000000000000000000000000000000000000000000000000900460ff1684565b6040805173ffffffffffffffffffffffffffffffffffffffff95861681529490931660208501527fffffffffffffffffffff00000000000000000000000000000000000000000000909116918301919091521515606082015260800161011e565b6101127f000000000000000000000000000000000000000000000000000000000000000081565b61013a610768565b61029c61077b565b60405161011e9190611150565b61013a610807565b61013a6102bf3660046111a7565b610883565b6103af6102d23660046110d8565b604080516080810182525f808252602082018190529181018290526060810191909152505f908152600260209081526040918290208251608081018452815473ffffffffffffffffffffffffffffffffffffffff90811682526001909201549182169281019290925274010000000000000000000000000000000000000000810460b01b7fffffffffffffffffffff0000000000000000000000000000000000000000000016928201929092527e0100000000000000000000000000000000000000000000000000000000000090910460ff161515606082015290565b60405161011e91905f60808201905073ffffffffffffffffffffffffffffffffffffffff835116825273ffffffffffffffffffffffffffffffffffffffff60208401511660208301527fffffffffffffffffffff00000000000000000000000000000000000000000000604084015116604083015260608301511515606083015292915050565b5f5473ffffffffffffffffffffffffffffffffffffffff1661015c565b6101126104613660046110d8565b5f908152600260205260409020600101547e01000000000000000000000000000000000000000000000000000000000000900460ff1690565b60015473ffffffffffffffffffffffffffffffffffffffff1661015c565b61013a6104c6366004611213565b610b30565b61013a6104d9366004611241565b610c6d565b61013a6104ec366004611241565b610d1c565b5f7fffffffff0000000000000000000000000000000000000000000000000000000082167f805f213200000000000000000000000000000000000000000000000000000000148061058357507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b610591610e30565b6040805160808101825273ffffffffffffffffffffffffffffffffffffffff808716825285811660208084019182527fffffffffffffffffffff000000000000000000000000000000000000000000008716848601908152861515606086019081525f8c8152600290935291869020945185549085167fffffffffffffffffffffffff00000000000000000000000000000000000000009091161785559151600190940180549251915115157e01000000000000000000000000000000000000000000000000000000000000027fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff60b09390931c74010000000000000000000000000000000000000000027fffff000000000000000000000000000000000000000000000000000000000000909416959094169490941791909117161790555185907f2b064f441dd44982f23715878bcf0128a150601864482118ed9c867b3924c3199061075990879087908790879073ffffffffffffffffffffffffffffffffffffffff94851681529290931660208301527fffffffffffffffffffff00000000000000000000000000000000000000000000166040820152901515606082015260800190565b60405180910390a25050505050565b610770610e30565b6107795f610e82565b565b600480546107889061125a565b80601f01602080910402602001604051908101604052809291908181526020018280546107b49061125a565b80156107ff5780601f106107d6576101008083540402835291602001916107ff565b820191905f5260205f20905b8154815290600101906020018083116107e257829003601f168201915b505050505081565b600154339073ffffffffffffffffffffffffffffffffffffffff168114610877576040517f118cdaa700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b61088081610e82565b50565b7f000000000000000000000000000000000000000000000000000000000000000015610b20575f5f5f6108ea87878080601f0160208091040260200160405190810160405280939291908181526020018383808284375f92019190915250610eb392505050565b5f83815260026020526040902060018101549396509194509250907e01000000000000000000000000000000000000000000000000000000000000900460ff16610963576040517f6420bb8e0000000000000000000000000000000000000000000000000000000081526004810185905260240161086e565b805473ffffffffffffffffffffffffffffffffffffffff1633146109d45780546040517f0962e84200000000000000000000000000000000000000000000000000000000815233600482015273ffffffffffffffffffffffffffffffffffffffff909116602482015260440161086e565b600181015473ffffffffffffffffffffffffffffffffffffffff848116911614610a505760018101546040517fb8a98af800000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8086166004830152909116602482015260440161086e565b60018101547fffffffffffffffffffff000000000000000000000000000000000000000000008381167401000000000000000000000000000000000000000090920460b01b1614610b1b5760018101546040517f6c4609a60000000000000000000000000000000000000000000000000000000081527fffffffffffffffffffff0000000000000000000000000000000000000000000084811660048301527401000000000000000000000000000000000000000090920460b01b909116602482015260440161086e565b505050505b610b2a8282610ecf565b50505050565b610b38610e30565b5f82815260026020526040908190206001810180548415157e01000000000000000000000000000000000000000000000000000000000000027fff00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821681179283905583549451939487947f2b064f441dd44982f23715878bcf0128a150601864482118ed9c867b3924c31994610c609473ffffffffffffffffffffffffffffffffffffffff9384169484169316929092179174010000000000000000000000000000000000000000900460b01b90889073ffffffffffffffffffffffffffffffffffffffff94851681529290931660208301527fffffffffffffffffffff00000000000000000000000000000000000000000000166040820152901515606082015260800190565b60405180910390a2505050565b610c75610e30565b6001805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff00000000000000000000000000000000000000009091168117909155610cd75f5473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a350565b610d24610e30565b6040517ff7c1ec9f000000000000000000000000000000000000000000000000000000008152306004820152819073ffffffffffffffffffffffffffffffffffffffff82169063f7c1ec9f90602401602060405180830381865afa158015610d8e573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610db291906112ab565b610de8576040517ff105a73500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610779576040517f118cdaa700000000000000000000000000000000000000000000000000000000815233600482015260240161086e565b600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905561088081610f65565b60208101516040820151604a90920151909260609190911c9190565b5f610edc828401846113cb565b6003546040517f7890626800000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff1690637890626890610f339084906004016114b8565b5f604051808303815f87803b158015610f4a575f5ffd5b505af1158015610f5c573d5f5f3e3d5ffd5b50505050505050565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b5f60208284031215610fe9575f5ffd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611018575f5ffd5b9392505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611042575f5ffd5b919050565b8015158114610880575f5ffd5b5f5f5f5f5f60a08688031215611068575f5ffd5b853594506110786020870161101f565b93506110866040870161101f565b925060608601357fffffffffffffffffffff00000000000000000000000000000000000000000000811681146110ba575f5ffd5b915060808601356110ca81611047565b809150509295509295909350565b5f602082840312156110e8575f5ffd5b5035919050565b5f81518084525f5b81811015611113576020818501810151868301820152016110f7565b505f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b602081525f61101860208301846110ef565b5f5f83601f840112611172575f5ffd5b50813567ffffffffffffffff811115611189575f5ffd5b6020830191508360208285010111156111a0575f5ffd5b9250929050565b5f5f5f5f604085870312156111ba575f5ffd5b843567ffffffffffffffff8111156111d0575f5ffd5b6111dc87828801611162565b909550935050602085013567ffffffffffffffff8111156111fb575f5ffd5b61120787828801611162565b95989497509550505050565b5f5f60408385031215611224575f5ffd5b82359150602083013561123681611047565b809150509250929050565b5f60208284031215611251575f5ffd5b6110188261101f565b600181811c9082168061126e57607f821691505b6020821081036112a5577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b5f602082840312156112bb575f5ffd5b815161101881611047565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040516080810167ffffffffffffffff81118282101715611316576113166112c6565b60405290565b5f82601f83011261132b575f5ffd5b8135602083015f5f67ffffffffffffffff84111561134b5761134b6112c6565b506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f85018116603f0116810181811067ffffffffffffffff82111715611398576113986112c6565b6040528381529050808284018710156113af575f5ffd5b838360208301375f602085830101528094505050505092915050565b5f602082840312156113db575f5ffd5b813567ffffffffffffffff8111156113f1575f5ffd5b820160808185031215611402575f5ffd5b61140a6112f3565b813567ffffffffffffffff811115611420575f5ffd5b61142c8682850161131c565b825250602082013567ffffffffffffffff811115611448575f5ffd5b6114548682850161131c565b602083015250604082013567ffffffffffffffff811115611473575f5ffd5b61147f8682850161131c565b604083015250606082013567ffffffffffffffff81111561149e575f5ffd5b6114aa8682850161131c565b606083015250949350505050565b602081525f8251608060208401526114d360a08401826110ef565b905060208401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301604085015261150e82826110ef565b91505060408401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301606085015261154a82826110ef565b91505060608401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301608085015261158682826110ef565b9594505050505056fea164736f6c634300081b000a

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

000000000000000000000000eb28cddcbe782b84f33668c3423ae5b070db971a000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001c4c6c616d6147756172642055535442204f7261636c652050726f787900000000

-----Decoded View---------------
Arg [0] : llamaGuardOracleAddress (address): 0xEb28cDDCBE782B84f33668C3423ae5b070dB971a
Arg [1] : workflowId (bytes32): 0x0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : expectedForwarder (address): 0x0000000000000000000000000000000000000000
Arg [3] : expectedAuthor (address): 0x0000000000000000000000000000000000000000
Arg [4] : expectedWorkflowName (bytes10): 0x00000000000000000000
Arg [5] : _description (string): LlamaGuard USTB Oracle Proxy
Arg [6] : isReportWriteSecured_ (bool): False

-----Encoded View---------------
9 Constructor Arguments found :
Arg [0] : 000000000000000000000000eb28cddcbe782b84f33668c3423ae5b070db971a
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [7] : 000000000000000000000000000000000000000000000000000000000000001c
Arg [8] : 4c6c616d6147756172642055535442204f7261636c652050726f787900000000


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

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.