ETH Price: $2,585.36 (-2.96%)

Contract

0x3C9C09C4Cfda9D2c35142AAea706E9FC9EA28F27
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Deny204323962024-08-01 8:06:23195 days ago1722499583IN
0x3C9C09C4...C9EA28F27
0 ETH0.000162326.95699146
Rely204323962024-08-01 8:06:23195 days ago1722499583IN
0x3C9C09C4...C9EA28F27
0 ETH0.000329446.95699146
Rely204323952024-08-01 8:06:11195 days ago1722499571IN
0x3C9C09C4...C9EA28F27
0 ETH0.000313966.63017827

View more zero value Internal Transactions in Advanced View mode

Advanced mode:
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
GasService

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
Yes with 500 runs

Other Settings:
cancun EvmVersion
File 1 of 7 : GasService.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

import {Auth} from "src/Auth.sol";
import {IGasService} from "src/interfaces/gateway/IGasService.sol";
import {MathLib} from "src/libraries/MathLib.sol";
import {BytesLib} from "src/libraries/BytesLib.sol";
import {MessagesLib} from "src/libraries/MessagesLib.sol";

/// @title  GasService
/// @notice This is a utility contract used in calculations of the
///         transaction cost for a message / proof being sent across all supported adapters
///         and executed on Centrifuge Chain.
contract GasService is IGasService, Auth {
    using MathLib for uint64;
    using MathLib for uint256;
    using BytesLib for bytes;

    /// @dev Prices are fixed-point integers with 18 decimals
    uint256 internal constant PRICE_DENOMINATOR = 10 ** 18;

    /// @inheritdoc IGasService
    uint64 public proofCost;
    /// @inheritdoc IGasService
    uint64 public messageCost;
    /// @inheritdoc IGasService
    uint128 public gasPrice;
    /// @inheritdoc IGasService
    uint64 public lastUpdatedAt;
    /// @inheritdoc IGasService
    uint256 public tokenPrice;

    constructor(uint64 messageCost_, uint64 proofCost_, uint128 gasPrice_, uint256 tokenPrice_) Auth(msg.sender) {
        messageCost = messageCost_;
        proofCost = proofCost_;
        gasPrice = gasPrice_;
        tokenPrice = tokenPrice_;
        lastUpdatedAt = uint64(block.timestamp);
    }

    /// @inheritdoc IGasService
    function file(bytes32 what, uint64 value) external auth {
        if (what == "messageCost") messageCost = value;
        else if (what == "proofCost") proofCost = value;
        else revert("GasService/file-unrecognized-param");
        emit File(what, value);
    }

    /// --- Incoming message handling ---
    /// @inheritdoc IGasService
    function handle(bytes calldata message) public auth {
        MessagesLib.Call call = MessagesLib.messageType(message);

        if (call == MessagesLib.Call.UpdateCentrifugeGasPrice) {
            updateGasPrice(message.toUint128(1), message.toUint64(17));
        } else {
            revert("GasService/invalid-message");
        }
    }

    /// --- Update methods ---
    /// @inheritdoc IGasService
    function updateGasPrice(uint128 value, uint64 computedAt) public auth {
        require(value != 0, "GasService/price-cannot-be-zero");
        require(gasPrice != value, "GasService/already-set-price");
        require(lastUpdatedAt < computedAt, "GasService/outdated-price");
        gasPrice = value;
        lastUpdatedAt = computedAt;
        emit UpdateGasPrice(value, computedAt);
    }

    /// @inheritdoc IGasService
    function updateTokenPrice(uint256 value) external auth {
        tokenPrice = value;
        emit UpdateTokenPrice(value);
    }

    /// --- Estimations ---
    /// @inheritdoc IGasService
    function estimate(bytes calldata payload) public view returns (uint256) {
        uint256 totalCost;
        uint8 call = payload.toUint8(0);
        if (call == uint8(MessagesLib.Call.MessageProof)) {
            totalCost = proofCost.mulDiv(gasPrice, PRICE_DENOMINATOR, MathLib.Rounding.Up);
        } else {
            totalCost = messageCost.mulDiv(gasPrice, PRICE_DENOMINATOR, MathLib.Rounding.Up);
        }

        return totalCost.mulDiv(tokenPrice, PRICE_DENOMINATOR, MathLib.Rounding.Up);
    }

    /// @inheritdoc IGasService
    function shouldRefuel(address, bytes calldata) public pure returns (bool success) {
        success = true;
    }
}

File 2 of 7 : Auth.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

import {IAuth} from "src/interfaces/IAuth.sol";

/// @title  Auth
/// @notice Simple authentication pattern
/// @author Based on code from https://github.com/makerdao/dss
abstract contract Auth is IAuth {
    /// @inheritdoc IAuth
    mapping(address => uint256) public wards;

    constructor(address initialWard) {
        wards[initialWard] = 1;
        emit Rely(initialWard);
    }

    /// @dev Check if the msg.sender has permissions
    modifier auth() {
        require(wards[msg.sender] == 1, "Auth/not-authorized");
        _;
    }

    /// @inheritdoc IAuth
    function rely(address user) external auth {
        wards[user] = 1;
        emit Rely(user);
    }

    /// @inheritdoc IAuth
    function deny(address user) external auth {
        wards[user] = 0;
        emit Deny(user);
    }
}

File 3 of 7 : IGasService.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

interface IGasService {
    event File(bytes32 indexed what, uint64 value);
    event UpdateGasPrice(uint128 value, uint256 computedAt);
    event UpdateTokenPrice(uint256 value);

    /// @notice Using file patter to update state variables;
    /// @dev    Used to update the messageCost and proofCost;
    ///         It is used in occasions where update is done rarely.
    function file(bytes32 what, uint64 value) external;

    /// @notice The cost of 'message' execution on Centrifuge Chain.
    /// @dev    This is a getter method
    /// @return Amount in Weigth ( gas unit on Centrifuge Chain )
    function messageCost() external returns (uint64);

    /// @notice The cost of 'proof' execution on Centrifuge Chain.
    /// @dev    This is a getter method
    /// @return Amount in Weight ( gas unit on Centrifuge Chain )
    function proofCost() external returns (uint64);

    /// @notice Weigth Gas Price from Centrifuge Chain
    /// @dev    This is a getter method
    /// @return The current gas price on Centrifuge Chain
    function gasPrice() external returns (uint128);

    /// @notice Keeps track what was the last time when the gas price was updated
    /// @dev    This is a getter method
    /// @return Timestamp when the gas price was last updated
    function lastUpdatedAt() external returns (uint64);

    /// @notice CFG/ETH price
    /// @dev    This is a getter method
    /// @return The current price
    function tokenPrice() external returns (uint256);

    /// @notice Executes a message from the gateway
    /// @dev    The function can only be executed by the gateway contract.
    function handle(bytes calldata message) external;

    /// @notice Updates the gas price on Centrifuge Chain
    /// @dev    The update comes as a message from the Centrifuge Chain.
    /// @param  value New price in Centrifuge Chain base unit
    /// @param  computedAt Timestamp when the value was evaluated.
    function updateGasPrice(uint128 value, uint64 computedAt) external;

    /// @notice Called to update the  CFG/ETH price
    /// @param  value New price in wei
    function updateTokenPrice(uint256 value) external;

    /// @notice Estimate the total execution cost on Centrifuge Chain in ETH.
    /// @dev    Currently payload is disregarded and not included in the calculation.
    /// @param  payload Estimates the execution cost based on the payload
    /// @return Estimated cost in WEI units
    function estimate(bytes calldata payload) external view returns (uint256);

    /// @notice Used to verify if given user for a given message can take advantage of
    ///         transaction cost prepayment.
    /// @dev    This is used in the Gateway to check if the source of the transaction
    ///         is eligible for tx cost payment from Gateway's balance.
    /// @param  source Source that triggered the transaction
    /// @param  payload The message that is going to be send
    function shouldRefuel(address source, bytes calldata payload) external returns (bool);
}

File 4 of 7 : MathLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

/// @title  Math Lib
/// @dev    Standard math utilities missing in the Solidity language.
/// @author Modified from OpenZeppelin Contracts v4.9.3 (utils/math/Math.sol)
library MathLib {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero

    }

    /// @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
    ///         denominator == 0
    /// @dev    Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
    ///         with further edits by Uniswap Labs also under MIT license.
    // slither-disable-start divide-before-multiply
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
            // Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
            // works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }
    // slither-disable-end divide-before-multiply

    /// @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /// @notice Safe type conversion from uint256 to uint8.
    function toUint8(uint256 value) internal pure returns (uint8) {
        if (value > type(uint8).max) {
            revert("MathLib/uint8-overflow");
        }
        return uint8(value);
    }

    /// @notice Safe type conversion from uint256 to uint128.
    function toUint128(uint256 _value) internal pure returns (uint128 value) {
        if (_value > type(uint128).max) {
            revert("MathLib/uint128-overflow");
        } else {
            value = uint128(_value);
        }
    }

    /// @notice Returns the smallest of two numbers.
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? b : a;
    }
}

File 5 of 7 : BytesLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

/// @title  Bytes Lib
/// @dev    Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
///         The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
/// @author Modified from Solidity Bytes Arrays Utils v0.8.0
library BytesLib {
    function slice(bytes memory _bytes, uint256 _start, uint256 _length) internal pure returns (bytes memory) {
        require(_length + 31 >= _length, "slice_overflow");
        require(_bytes.length >= _start + _length, "slice_outOfBounds");

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } { mstore(mc, mload(cc)) }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
                //zero out the 32 bytes slice we are about to return
                //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toAddress(bytes memory _bytes, uint256 _start) internal pure returns (address) {
        require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

    function toUint8(bytes memory _bytes, uint256 _start) internal pure returns (uint8) {
        require(_bytes.length >= _start + 1, "toUint8_outOfBounds");
        uint8 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x1), _start))
        }

        return tempUint;
    }

    function toUint16(bytes memory _bytes, uint256 _start) internal pure returns (uint16) {
        require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
        uint16 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x2), _start))
        }

        return tempUint;
    }

    function toUint64(bytes memory _bytes, uint256 _start) internal pure returns (uint64) {
        require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
        uint64 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x8), _start))
        }

        return tempUint;
    }

    function toUint128(bytes memory _bytes, uint256 _start) internal pure returns (uint128) {
        require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
        uint128 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x10), _start))
        }

        return tempUint;
    }

    function toUint256(bytes memory _bytes, uint256 _start) internal pure returns (uint256) {
        require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
        uint256 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes memory _bytes, uint256 _start) internal pure returns (bytes32) {
        require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
        bytes32 tempBytes32;

        assembly {
            tempBytes32 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes32;
    }

    function toBytes16(bytes memory _bytes, uint256 _start) internal pure returns (bytes16) {
        require(_bytes.length >= _start + 16, "toBytes16_outOfBounds");
        bytes16 tempBytes16;

        assembly {
            tempBytes16 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes16;
    }
}

File 6 of 7 : MessagesLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity 0.8.26;

import {BytesLib} from "src/libraries/BytesLib.sol";

/// @title  MessagesLib
/// @dev    Library for encoding and decoding messages.
library MessagesLib {
    using BytesLib for bytes;

    enum Call {
        /// 0 - An invalid message
        Invalid,
        // --- Gateway ---
        /// 1 - Proof
        MessageProof,
        /// 2 - Initiate Message Recovery
        InitiateMessageRecovery,
        /// 3 - Dispute Message Recovery
        DisputeMessageRecovery,
        /// 4 - Batch Messages
        Batch,
        // --- Root ---
        /// 5 - Schedule an upgrade contract to be granted admin rights
        ScheduleUpgrade,
        /// 6 - Cancel a previously scheduled upgrade
        CancelUpgrade,
        /// 7 - Recover tokens sent to the wrong contract
        RecoverTokens,
        // --- Gas service ---
        /// 8 - Update Centrifuge gas price
        UpdateCentrifugeGasPrice,
        // --- Pool Manager ---
        /// 9 - Add an asset id -> EVM address mapping
        AddAsset,
        /// 10 - Add Pool
        AddPool,
        /// 11 - Add a Pool's Tranche Token
        AddTranche,
        /// 12 - Allow an asset to be used as an asset for investing in pools
        AllowAsset,
        /// 13 - Disallow an asset to be used as an asset for investing in pools
        DisallowAsset,
        /// 14 - Update the price of a Tranche Token
        UpdateTranchePrice,
        /// 15 - Update tranche token metadata
        UpdateTrancheMetadata,
        /// 16 - Update Tranche Hook
        UpdateTrancheHook,
        /// 17 - A transfer of assets
        TransferAssets,
        /// 18 - A transfer of tranche tokens
        TransferTrancheTokens,
        /// 19 - Update a user restriction
        UpdateRestriction,
        /// --- Investment Manager ---
        /// 20 - Increase an investment order by a given amount
        DepositRequest,
        /// 21 - Increase a Redeem order by a given amount
        RedeemRequest,
        /// 22 - Executed Collect Invest
        FulfilledDepositRequest,
        /// 23 - Executed Collect Redeem
        FulfilledRedeemRequest,
        /// 24 - Cancel an investment order
        CancelDepositRequest,
        /// 25 - Cancel a redeem order
        CancelRedeemRequest,
        /// 26 - Executed Decrease Invest Order
        FulfilledCancelDepositRequest,
        /// 27 - Executed Decrease Redeem Order
        FulfilledCancelRedeemRequest,
        /// 28 - Request redeem investor
        TriggerRedeemRequest
    }

    function messageType(bytes memory _msg) internal pure returns (Call _call) {
        _call = Call(_msg.toUint8(0));
    }
}

File 7 of 7 : IAuth.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.5.0;

interface IAuth {
    event Rely(address indexed user);
    event Deny(address indexed user);

    /// @notice Returns whether the target is a ward (has admin access)
    function wards(address target) external view returns (uint256);

    /// @notice Make user a ward (give them admin access)
    function rely(address user) external;

    /// @notice Remove user as a ward (remove admin access)
    function deny(address user) external;
}

Settings
{
  "remappings": [
    "forge-std/=lib/forge-std/src/",
    "@chimera/=lib/chimera/src/",
    "chimera/=lib/chimera/src/",
    "ds-test/=lib/chimera/lib/forge-std/lib/ds-test/src/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 500
  },
  "metadata": {
    "useLiteralContent": false,
    "bytecodeHash": "ipfs",
    "appendCBOR": true
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "evmVersion": "cancun",
  "viaIR": false,
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint64","name":"messageCost_","type":"uint64"},{"internalType":"uint64","name":"proofCost_","type":"uint64"},{"internalType":"uint128","name":"gasPrice_","type":"uint128"},{"internalType":"uint256","name":"tokenPrice_","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"Deny","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"what","type":"bytes32"},{"indexed":false,"internalType":"uint64","name":"value","type":"uint64"}],"name":"File","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"}],"name":"Rely","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"value","type":"uint128"},{"indexed":false,"internalType":"uint256","name":"computedAt","type":"uint256"}],"name":"UpdateGasPrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"UpdateTokenPrice","type":"event"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"deny","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"payload","type":"bytes"}],"name":"estimate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"what","type":"bytes32"},{"internalType":"uint64","name":"value","type":"uint64"}],"name":"file","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gasPrice","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"message","type":"bytes"}],"name":"handle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastUpdatedAt","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"messageCost","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proofCost","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"rely","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"shouldRefuel","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"tokenPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"value","type":"uint128"},{"internalType":"uint64","name":"computedAt","type":"uint64"}],"name":"updateGasPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"}],"name":"updateTokenPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"wards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

608060405234801561000f575f80fd5b50604051610fef380380610fef83398101604081905261002e916100ed565b335f81815260208190526040808220600190555182917fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a6091a2506001600160801b03909116600160801b026001600160401b0393841668010000000000000000026fffffffffffffffff000000000000000016928416929092179190911760015560035560028054429092166001600160401b031992909216919091179055610143565b80516001600160401b03811681146100e8575f80fd5b919050565b5f805f8060808587031215610100575f80fd5b610109856100d2565b9350610117602086016100d2565b60408601519093506001600160801b0381168114610133575f80fd5b6060959095015193969295505050565b610e9f806101505f395ff3fe608060405234801561000f575f80fd5b50600436106100e5575f3560e01c8063676c0d7711610088578063bf353dbb11610063578063bf353dbb146101ee578063bf48bcb61461020d578063e766cc1214610220578063fe173b9714610233575f80fd5b8063676c0d77146101b15780637ff9b596146101c45780639c52a7f1146101db575f80fd5b80633309fd68116100c35780633309fd681461014f578063492fac911461016357806354aea1271461018a57806365fae35e1461019e575f80fd5b806309eab351146100e95780631293092e146100fe5780631d0ca2e61461013c575b5f80fd5b6100fc6100f7366004610caa565b610265565b005b60015461011e9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b6100fc61014a366004610ce8565b610454565b60015461011e9067ffffffffffffffff1681565b61017a610171366004610d64565b50600192915050565b6040519015158152602001610133565b60025461011e9067ffffffffffffffff1681565b6100fc6101ac366004610db3565b6105bd565b6100fc6101bf366004610dcc565b610655565b6101cd60035481565b604051908152602001610133565b6100fc6101e9366004610db3565b6106e4565b6101cd6101fc366004610db3565b5f6020819052908152604090205481565b6100fc61021b366004610de3565b61077b565b6101cd61022e366004610de3565b6108ff565b60015461024d90600160801b90046001600160801b031681565b6040516001600160801b039091168152602001610133565b335f908152602081905260409020546001146102be5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064015b60405180910390fd5b816001600160801b03165f036103165760405162461bcd60e51b815260206004820152601f60248201527f476173536572766963652f70726963652d63616e6e6f742d62652d7a65726f0060448201526064016102b5565b6001546001600160801b03808416600160801b909204160361037a5760405162461bcd60e51b815260206004820152601c60248201527f476173536572766963652f616c72656164792d7365742d70726963650000000060448201526064016102b5565b60025467ffffffffffffffff8083169116106103d85760405162461bcd60e51b815260206004820152601960248201527f476173536572766963652f6f757464617465642d70726963650000000000000060448201526064016102b5565b600180546001600160801b03908116600160801b918516918202179091556002805467ffffffffffffffff191667ffffffffffffffff84169081179091556040805192835260208301919091527f10ce9b06a6a645c5d87d4e58ab08bcbe9455297f8df1ab3c030fb1cfb1eb3fc4910160405180910390a15050565b335f908152602081905260409020546001146104a85760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016102b5565b816a1b595cdcd859d950dbdcdd60aa1b036104f257600180546fffffffffffffffff000000000000000019166801000000000000000067ffffffffffffffff84160217905561057a565b81681c1c9bdbd990dbdcdd60ba1b03610527576001805467ffffffffffffffff191667ffffffffffffffff831617905561057a565b60405162461bcd60e51b815260206004820152602260248201527f476173536572766963652f66696c652d756e7265636f676e697a65642d706172604482015261616d60f01b60648201526084016102b5565b60405167ffffffffffffffff8216815282907f10fbf5311f0b0b99de084cdac4114a3d88c3bc7cf3ae525e61217ad1a97bca309060200160405180910390a25050565b335f908152602081905260409020546001146106115760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016102b5565b6001600160a01b0381165f8181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b335f908152602081905260409020546001146106a95760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016102b5565b60038190556040518181527f8ef650d2de4208447ddb5de6a4d2bd95d7d04c957df933ff2548882ea2025a389060200160405180910390a150565b335f908152602081905260409020546001146107385760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016102b5565b6001600160a01b0381165f81815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b335f908152602081905260409020546001146107cf5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016102b5565b5f61080e83838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506109f292505050565b9050600881601c81111561082457610824610e22565b036108b7576108b261086f600185858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509293925050610a119050565b6100f7601186868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509293925050610a769050565b505050565b60405162461bcd60e51b815260206004820152601a60248201527f476173536572766963652f696e76616c69642d6d65737361676500000000000060448201526064016102b5565b5f805f6109445f86868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509293925050610adb9050565b90505f1960ff82160161098c57600180546109859167ffffffffffffffff821691600160801b90046001600160801b031690670de0b6b3a764000090610b40565b91506109ce565b600180546109cb9168010000000000000000820467ffffffffffffffff1691600160801b90046001600160801b031690670de0b6b3a764000090610b40565b91505b6003546109e7908390670de0b6b3a76400006001610b40565b925050505b92915050565b5f6109fd8282610adb565b60ff16601c8111156109ec576109ec610e22565b5f610a1d826010610e36565b83511015610a6d5760405162461bcd60e51b815260206004820152601560248201527f746f55696e743132385f6f75744f66426f756e6473000000000000000000000060448201526064016102b5565b50016010015190565b5f610a82826008610e36565b83511015610ad25760405162461bcd60e51b815260206004820152601460248201527f746f55696e7436345f6f75744f66426f756e647300000000000000000000000060448201526064016102b5565b50016008015190565b5f610ae7826001610e36565b83511015610b375760405162461bcd60e51b815260206004820152601360248201527f746f55696e74385f6f75744f66426f756e64730000000000000000000000000060448201526064016102b5565b50016001015190565b5f80610b4d868686610b9b565b90506001836002811115610b6357610b63610e22565b148015610b7f57505f8480610b7a57610b7a610e55565b868809115b15610b9257610b8f600182610e36565b90505b95945050505050565b5f80805f19858709858702925082811083820303915050805f03610bd257838281610bc857610bc8610e55565b0492505050610c87565b808411610c215760405162461bcd60e51b815260206004820152601560248201527f4d6174683a206d756c446976206f766572666c6f77000000000000000000000060448201526064016102b5565b5f848688098519600190810187169687900496828603819004959092119093035f82900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b803567ffffffffffffffff81168114610ca5575f80fd5b919050565b5f8060408385031215610cbb575f80fd5b82356001600160801b0381168114610cd1575f80fd5b9150610cdf60208401610c8e565b90509250929050565b5f8060408385031215610cf9575f80fd5b82359150610cdf60208401610c8e565b80356001600160a01b0381168114610ca5575f80fd5b5f8083601f840112610d2f575f80fd5b50813567ffffffffffffffff811115610d46575f80fd5b602083019150836020828501011115610d5d575f80fd5b9250929050565b5f805f60408486031215610d76575f80fd5b610d7f84610d09565b9250602084013567ffffffffffffffff811115610d9a575f80fd5b610da686828701610d1f565b9497909650939450505050565b5f60208284031215610dc3575f80fd5b610c8782610d09565b5f60208284031215610ddc575f80fd5b5035919050565b5f8060208385031215610df4575f80fd5b823567ffffffffffffffff811115610e0a575f80fd5b610e1685828601610d1f565b90969095509350505050565b634e487b7160e01b5f52602160045260245ffd5b808201808211156109ec57634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52601260045260245ffdfea2646970667358221220ae80874f8ea04d6ef21f8c0f4a895bbd4e5a2f99508c43ef71b57c0151e5cd8764736f6c634300081a003300000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000022b1c8c1227a00000000000000000000000000000000000000000000000000000000a2c07035e200

Deployed Bytecode

0x608060405234801561000f575f80fd5b50600436106100e5575f3560e01c8063676c0d7711610088578063bf353dbb11610063578063bf353dbb146101ee578063bf48bcb61461020d578063e766cc1214610220578063fe173b9714610233575f80fd5b8063676c0d77146101b15780637ff9b596146101c45780639c52a7f1146101db575f80fd5b80633309fd68116100c35780633309fd681461014f578063492fac911461016357806354aea1271461018a57806365fae35e1461019e575f80fd5b806309eab351146100e95780631293092e146100fe5780631d0ca2e61461013c575b5f80fd5b6100fc6100f7366004610caa565b610265565b005b60015461011e9068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020015b60405180910390f35b6100fc61014a366004610ce8565b610454565b60015461011e9067ffffffffffffffff1681565b61017a610171366004610d64565b50600192915050565b6040519015158152602001610133565b60025461011e9067ffffffffffffffff1681565b6100fc6101ac366004610db3565b6105bd565b6100fc6101bf366004610dcc565b610655565b6101cd60035481565b604051908152602001610133565b6100fc6101e9366004610db3565b6106e4565b6101cd6101fc366004610db3565b5f6020819052908152604090205481565b6100fc61021b366004610de3565b61077b565b6101cd61022e366004610de3565b6108ff565b60015461024d90600160801b90046001600160801b031681565b6040516001600160801b039091168152602001610133565b335f908152602081905260409020546001146102be5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064015b60405180910390fd5b816001600160801b03165f036103165760405162461bcd60e51b815260206004820152601f60248201527f476173536572766963652f70726963652d63616e6e6f742d62652d7a65726f0060448201526064016102b5565b6001546001600160801b03808416600160801b909204160361037a5760405162461bcd60e51b815260206004820152601c60248201527f476173536572766963652f616c72656164792d7365742d70726963650000000060448201526064016102b5565b60025467ffffffffffffffff8083169116106103d85760405162461bcd60e51b815260206004820152601960248201527f476173536572766963652f6f757464617465642d70726963650000000000000060448201526064016102b5565b600180546001600160801b03908116600160801b918516918202179091556002805467ffffffffffffffff191667ffffffffffffffff84169081179091556040805192835260208301919091527f10ce9b06a6a645c5d87d4e58ab08bcbe9455297f8df1ab3c030fb1cfb1eb3fc4910160405180910390a15050565b335f908152602081905260409020546001146104a85760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016102b5565b816a1b595cdcd859d950dbdcdd60aa1b036104f257600180546fffffffffffffffff000000000000000019166801000000000000000067ffffffffffffffff84160217905561057a565b81681c1c9bdbd990dbdcdd60ba1b03610527576001805467ffffffffffffffff191667ffffffffffffffff831617905561057a565b60405162461bcd60e51b815260206004820152602260248201527f476173536572766963652f66696c652d756e7265636f676e697a65642d706172604482015261616d60f01b60648201526084016102b5565b60405167ffffffffffffffff8216815282907f10fbf5311f0b0b99de084cdac4114a3d88c3bc7cf3ae525e61217ad1a97bca309060200160405180910390a25050565b335f908152602081905260409020546001146106115760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016102b5565b6001600160a01b0381165f8181526020819052604080822060019055517fdd0e34038ac38b2a1ce960229778ac48a8719bc900b6c4f8d0475c6e8b385a609190a250565b335f908152602081905260409020546001146106a95760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016102b5565b60038190556040518181527f8ef650d2de4208447ddb5de6a4d2bd95d7d04c957df933ff2548882ea2025a389060200160405180910390a150565b335f908152602081905260409020546001146107385760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016102b5565b6001600160a01b0381165f81815260208190526040808220829055517f184450df2e323acec0ed3b5c7531b81f9b4cdef7914dfd4c0a4317416bb5251b9190a250565b335f908152602081905260409020546001146107cf5760405162461bcd60e51b8152602060048201526013602482015272105d5d1a0bdb9bdd0b585d5d1a1bdc9a5e9959606a1b60448201526064016102b5565b5f61080e83838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152506109f292505050565b9050600881601c81111561082457610824610e22565b036108b7576108b261086f600185858080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509293925050610a119050565b6100f7601186868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509293925050610a769050565b505050565b60405162461bcd60e51b815260206004820152601a60248201527f476173536572766963652f696e76616c69642d6d65737361676500000000000060448201526064016102b5565b5f805f6109445f86868080601f0160208091040260200160405190810160405280939291908181526020018383808284375f920191909152509293925050610adb9050565b90505f1960ff82160161098c57600180546109859167ffffffffffffffff821691600160801b90046001600160801b031690670de0b6b3a764000090610b40565b91506109ce565b600180546109cb9168010000000000000000820467ffffffffffffffff1691600160801b90046001600160801b031690670de0b6b3a764000090610b40565b91505b6003546109e7908390670de0b6b3a76400006001610b40565b925050505b92915050565b5f6109fd8282610adb565b60ff16601c8111156109ec576109ec610e22565b5f610a1d826010610e36565b83511015610a6d5760405162461bcd60e51b815260206004820152601560248201527f746f55696e743132385f6f75744f66426f756e6473000000000000000000000060448201526064016102b5565b50016010015190565b5f610a82826008610e36565b83511015610ad25760405162461bcd60e51b815260206004820152601460248201527f746f55696e7436345f6f75744f66426f756e647300000000000000000000000060448201526064016102b5565b50016008015190565b5f610ae7826001610e36565b83511015610b375760405162461bcd60e51b815260206004820152601360248201527f746f55696e74385f6f75744f66426f756e64730000000000000000000000000060448201526064016102b5565b50016001015190565b5f80610b4d868686610b9b565b90506001836002811115610b6357610b63610e22565b148015610b7f57505f8480610b7a57610b7a610e55565b868809115b15610b9257610b8f600182610e36565b90505b95945050505050565b5f80805f19858709858702925082811083820303915050805f03610bd257838281610bc857610bc8610e55565b0492505050610c87565b808411610c215760405162461bcd60e51b815260206004820152601560248201527f4d6174683a206d756c446976206f766572666c6f77000000000000000000000060448201526064016102b5565b5f848688098519600190810187169687900496828603819004959092119093035f82900391909104909201919091029190911760038402600290811880860282030280860282030280860282030280860282030280860282030280860290910302029150505b9392505050565b803567ffffffffffffffff81168114610ca5575f80fd5b919050565b5f8060408385031215610cbb575f80fd5b82356001600160801b0381168114610cd1575f80fd5b9150610cdf60208401610c8e565b90509250929050565b5f8060408385031215610cf9575f80fd5b82359150610cdf60208401610c8e565b80356001600160a01b0381168114610ca5575f80fd5b5f8083601f840112610d2f575f80fd5b50813567ffffffffffffffff811115610d46575f80fd5b602083019150836020828501011115610d5d575f80fd5b9250929050565b5f805f60408486031215610d76575f80fd5b610d7f84610d09565b9250602084013567ffffffffffffffff811115610d9a575f80fd5b610da686828701610d1f565b9497909650939450505050565b5f60208284031215610dc3575f80fd5b610c8782610d09565b5f60208284031215610ddc575f80fd5b5035919050565b5f8060208385031215610df4575f80fd5b823567ffffffffffffffff811115610e0a575f80fd5b610e1685828601610d1f565b90969095509350505050565b634e487b7160e01b5f52602160045260245ffd5b808201808211156109ec57634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52601260045260245ffdfea2646970667358221220ae80874f8ea04d6ef21f8c0f4a895bbd4e5a2f99508c43ef71b57c0151e5cd8764736f6c634300081a0033

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

00000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000022b1c8c1227a00000000000000000000000000000000000000000000000000000000a2c07035e200

-----Decoded View---------------
Arg [0] : messageCost_ (uint64): 20000000000000000
Arg [1] : proofCost_ (uint64): 20000000000000000
Arg [2] : gasPrice_ (uint128): 2500000000000000000
Arg [3] : tokenPrice_ (uint256): 178947400000000

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000470de4df820000
Arg [1] : 00000000000000000000000000000000000000000000000000470de4df820000
Arg [2] : 00000000000000000000000000000000000000000000000022b1c8c1227a0000
Arg [3] : 0000000000000000000000000000000000000000000000000000a2c07035e200


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]

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