ETH Price: $1,943.54 (-2.24%)

Transaction Decoder

Block:
24033026 at Dec-17-2025 02:47:59 PM +UTC
Transaction Fee:
0.00008625923651898 ETH $0.17
Gas Used:
73,990 Gas / 1.165822902 Gwei

Account State Difference:

  Address   Before After State Difference Code
(BuilderNet)
116.315819780495228445 Eth116.315898813504094655 Eth0.00007903300886621
0xf5EBbee1...24d0498e3
1.364090794503667417 Eth
Nonce: 2770
1.364004535267148437 Eth
Nonce: 2771
0.00008625923651898

Execution Trace

AuthorizedForwarder.forward( to=0xad88fc1A810379Ef4EFbF2D97EdE57e306178e5a, data=0xBA0CB29E0001EED173A005E0421B93A4D46CE82CCDD85F7EC92D8C53E1282FD654668D08000000000000000000000000000000000000000000000000000000000104CE049139231D452549114FA7C1D129E2C970307577DAB010AB47AA33B91482156BB300000000000000000000000000000000000000000000000000000000000000E00000000000000000000000000000000000000000000000000000000000000580000000000000000000000000000000000000000000000000000000000000070001010000000100010100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000480000000000000000000000000000000000000000000000000000000006942C2380D1E1D1A1512160906190F01040C111708000B180314130A0E1C050207101B0000000000000000000000000000000000000000000000000000000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001F0000000000000000000000000000000000000000000000000000004363FBD2BC000000000000000000000000000000000000000000000000000000436461F470000000000000000000000000000000000000000000000000000000436461F470000000000000000000000000000000000000000000000000000000436461F4700000000000000000000000000000000000000000000000000000004366698440000000000000000000000000000000000000000000000000000000436669844000000000000000000000000000000000000000000000000000000043666984400000000000000000000000000000000000000000000000000000004368601CB400000000000000000000000000000000000000000000000000000043690146200000000000000000000000000000000000000000000000000000004369276BC00000000000000000000000000000000000000000000000000000004369276BC00000000000000000000000000000000000000000000000000000004369276BC000000000000000000000000000000000000000000000000000000043696E8DE800000000000000000000000000000000000000000000000000000043696E8DE800000000000000000000000000000000000000000000000000000043696E8DE800000000000000000000000000000000000000000000000000000043696E8DE8000000000000000000000000000000000000000000000000000000436B990800000000000000000000000000000000000000000000000000000000436B990800000000000000000000000000000000000000000000000000000000436B990800000000000000000000000000000000000000000000000000000000436B990800000000000000000000000000000000000000000000000000000000436B990800000000000000000000000000000000000000000000000000000000436B990800000000000000000000000000000000000000000000000000000000436FCD5AFF000000000000000000000000000000000000000000000000000000436FCD5AFF000000000000000000000000000000000000000000000000000000436FCD5AFF0000000000000000000000000000000000000000000000000000004374535D440000000000000000000000000000000000000000000000000000004374535D440000000000000000000000000000000000000000000000000000004374535D44000000000000000000000000000000000000000000000000000000437634559A000000000000000000000000000000000000000000000000000000437634559A0000000000000000000000000000000000000000000000000000004377E7D4D1000000000000000000000000000000000000000000000000000000000000000B07CCD005B8E485FDDD829182FD202487451F0D83D33DC1B5E50116A1E2AFCF501217633A6F4D14FA56B2734BAF8619248F3951F0ED53132001B602EF0841CAEDF6385C96E9D84EEF123761DB61136B23B57EB1910394632C16387E40BD3A59B5BBC4751AFC838FAEAB4EBEF8E23594C37B8022CD95A8D0F8F1CECDD5D5BC358E152D6D16C4322D345BE73E70D26D88A0E9107C2E29DBB472DC03EFD8EE032D5FE6C8F2E042C380BB86669F90C0A9A81938EF2D33CB07BE657197FA504A376A43AEA400CCA420B5F6764A0A1495A2C3BE6620CDC735B272A7E96232E2056735E10CA7CDE135E3061E6C9E7425435FD2962F9E9BF6D43EB752A7A21464F1880D885D79FED2E138E3B030903632DD3088EA3339626271C2018A722618D90800572E1189C2B365A78B1577B7B1A0E702E685C420775DF733AE64097760BF169095D86CA0824E6389D2B2809B3C2A926EDCABF77B704A6C5CBB2EF5226140DD6B1D3D000000000000000000000000000000000000000000000000000000000000000B70B4157F9EFE678A1C1E5A19DEED3877542F325FFC71B59B1DB7AFB40BBBC1655B144960F4E39723C75499980D0C33F95DB8F06FF28FCA0859DC9BD517CEC7BA5BBA839FE09EB12F565A66C510D50B2CA55124947C67F39133B800BBDA7571427863CBB5F154FD750DE3303E1959FD7729407FEF0ED0BB5A1D13270E5118953F6BB1ED5DD016CADFB7598C433325A84AF2984BCCFF0F53458BB38132E534852B1B31879B641220262E8CC4FEE673B487B462BA19845A7999D079901A573D87A14A1D54394BF39AE060FF46420D33318887775CF3A2C4F7A064E02977908674E12C69C78BD908F03E1F9D2B1239633BB00A5A4F079AE6EF3725D05FA1597655D729172C54AE2ABAD8F1EC7704F19E33925ABFB0402C02DA61C8D1AD46F7F8955738DCC62626F6792BA5E2405B8A8E5A2EB9E7CC2C72AC29807496A504A66440AB32C2B16F59D6A0238206FE21A73D5BC3A1D19EBB8179C4A39D533FF47E4EEB4C )
  • 0xad88fc1a810379ef4efbf2d97ede57e306178e5a.ba0cb29e( )
    // SPDX-License-Identifier: MIT
    // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
    pragma solidity ^0.8.1;
    /**
     * @dev Collection of functions related to the address type
     */
    library Address {
        /**
         * @dev Returns true if `account` is a contract.
         *
         * [IMPORTANT]
         * ====
         * It is unsafe to assume that an address for which this function returns
         * false is an externally-owned account (EOA) and not a contract.
         *
         * Among others, `isContract` will return false for the following
         * types of addresses:
         *
         *  - an externally-owned account
         *  - a contract in construction
         *  - an address where a contract will be created
         *  - an address where a contract lived, but was destroyed
         *
         * Furthermore, `isContract` will also return true if the target contract within
         * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
         * which only has an effect at the end of a transaction.
         * ====
         *
         * [IMPORTANT]
         * ====
         * You shouldn't rely on `isContract` to protect against flash loan attacks!
         *
         * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
         * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
         * constructor.
         * ====
         */
        function isContract(address account) internal view returns (bool) {
            // This method relies on extcodesize/address.code.length, which returns 0
            // for contracts in construction, since the code is only stored at the end
            // of the constructor execution.
            return account.code.length > 0;
        }
        /**
         * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
         * `recipient`, forwarding all available gas and reverting on errors.
         *
         * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
         * of certain opcodes, possibly making contracts go over the 2300 gas limit
         * imposed by `transfer`, making them unable to receive funds via
         * `transfer`. {sendValue} removes this limitation.
         *
         * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more].
         *
         * IMPORTANT: because control is transferred to `recipient`, care must be
         * taken to not create reentrancy vulnerabilities. Consider using
         * {ReentrancyGuard} or the
         * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
         */
        function sendValue(address payable recipient, uint256 amount) internal {
            require(address(this).balance >= amount, "Address: insufficient balance");
            (bool success, ) = recipient.call{value: amount}("");
            require(success, "Address: unable to send value, recipient may have reverted");
        }
        /**
         * @dev Performs a Solidity function call using a low level `call`. A
         * plain `call` is an unsafe replacement for a function call: use this
         * function instead.
         *
         * If `target` reverts with a revert reason, it is bubbled up by this
         * function (like regular Solidity function calls).
         *
         * Returns the raw returned data. To convert to the expected return value,
         * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
         *
         * Requirements:
         *
         * - `target` must be a contract.
         * - calling `target` with `data` must not revert.
         *
         * _Available since v3.1._
         */
        function functionCall(address target, bytes memory data) internal returns (bytes memory) {
            return functionCallWithValue(target, data, 0, "Address: low-level call failed");
        }
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
         * `errorMessage` as a fallback revert reason when `target` reverts.
         *
         * _Available since v3.1._
         */
        function functionCall(
            address target,
            bytes memory data,
            string memory errorMessage
        ) internal returns (bytes memory) {
            return functionCallWithValue(target, data, 0, errorMessage);
        }
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
         * but also transferring `value` wei to `target`.
         *
         * Requirements:
         *
         * - the calling contract must have an ETH balance of at least `value`.
         * - the called Solidity function must be `payable`.
         *
         * _Available since v3.1._
         */
        function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
            return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
        }
        /**
         * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
         * with `errorMessage` as a fallback revert reason when `target` reverts.
         *
         * _Available since v3.1._
         */
        function functionCallWithValue(
            address target,
            bytes memory data,
            uint256 value,
            string memory errorMessage
        ) internal returns (bytes memory) {
            require(address(this).balance >= value, "Address: insufficient balance for call");
            (bool success, bytes memory returndata) = target.call{value: value}(data);
            return verifyCallResultFromTarget(target, success, returndata, errorMessage);
        }
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
         * but performing a static call.
         *
         * _Available since v3.3._
         */
        function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
            return functionStaticCall(target, data, "Address: low-level static call failed");
        }
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
         * but performing a static call.
         *
         * _Available since v3.3._
         */
        function functionStaticCall(
            address target,
            bytes memory data,
            string memory errorMessage
        ) internal view returns (bytes memory) {
            (bool success, bytes memory returndata) = target.staticcall(data);
            return verifyCallResultFromTarget(target, success, returndata, errorMessage);
        }
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
         * but performing a delegate call.
         *
         * _Available since v3.4._
         */
        function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
            return functionDelegateCall(target, data, "Address: low-level delegate call failed");
        }
        /**
         * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
         * but performing a delegate call.
         *
         * _Available since v3.4._
         */
        function functionDelegateCall(
            address target,
            bytes memory data,
            string memory errorMessage
        ) internal returns (bytes memory) {
            (bool success, bytes memory returndata) = target.delegatecall(data);
            return verifyCallResultFromTarget(target, success, returndata, errorMessage);
        }
        /**
         * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
         * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
         *
         * _Available since v4.8._
         */
        function verifyCallResultFromTarget(
            address target,
            bool success,
            bytes memory returndata,
            string memory errorMessage
        ) internal view returns (bytes memory) {
            if (success) {
                if (returndata.length == 0) {
                    // only check isContract if the call was successful and the return data is empty
                    // otherwise we already know that it was a contract
                    require(isContract(target), "Address: call to non-contract");
                }
                return returndata;
            } else {
                _revert(returndata, errorMessage);
            }
        }
        /**
         * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
         * revert reason or using the provided one.
         *
         * _Available since v4.3._
         */
        function verifyCallResult(
            bool success,
            bytes memory returndata,
            string memory errorMessage
        ) internal pure returns (bytes memory) {
            if (success) {
                return returndata;
            } else {
                _revert(returndata, errorMessage);
            }
        }
        function _revert(bytes memory returndata, string memory errorMessage) private pure {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
    // SPDX-License-Identifier: MIT
    pragma solidity 0.8.19;
    import {ConfirmedOwnerWithProposal} from "../shared/access/ConfirmedOwnerWithProposal.sol";
    import {AuthorizedReceiver} from "./AuthorizedReceiver.sol";
    import {Address} from "@openzeppelin/contracts/utils/Address.sol";
    // solhint-disable gas-custom-errors
    contract AuthorizedForwarder is ConfirmedOwnerWithProposal, AuthorizedReceiver {
      using Address for address;
      // solhint-disable-next-line chainlink-solidity/prefix-immutable-variables-with-i
      address public immutable linkToken;
      event OwnershipTransferRequestedWithMessage(address indexed from, address indexed to, bytes message);
      constructor(
        address link,
        address owner,
        address recipient,
        bytes memory message
      ) ConfirmedOwnerWithProposal(owner, recipient) {
        require(link != address(0), "Link token cannot be a zero address");
        linkToken = link;
        if (recipient != address(0)) {
          emit OwnershipTransferRequestedWithMessage(owner, recipient, message);
        }
      }
      string public constant typeAndVersion = "AuthorizedForwarder 1.1.0";
      // @notice Forward a call to another contract
      // @dev Only callable by an authorized sender
      // @param to address
      // @param data to forward
      function forward(address to, bytes calldata data) external validateAuthorizedSender {
        require(to != linkToken, "Cannot forward to Link token");
        _forward(to, data);
      }
      //  @notice Forward multiple calls to other contracts in a multicall style
      //  @dev Only callable by an authorized sender
      //  @param tos An array of addresses to forward the calls to
      //  @param datas An array of data to forward to each corresponding address
      function multiForward(address[] calldata tos, bytes[] calldata datas) external validateAuthorizedSender {
        require(tos.length == datas.length, "Arrays must have the same length");
        for (uint256 i = 0; i < tos.length; ++i) {
          address to = tos[i];
          require(to != linkToken, "Cannot forward to Link token");
          // Perform the forward operation
          _forward(to, datas[i]);
        }
      }
      // @notice Forward a call to another contract
      // @dev Only callable by the owner
      // @param to address
      // @param data to forward
      function ownerForward(address to, bytes calldata data) external onlyOwner {
        _forward(to, data);
      }
      // @notice Transfer ownership with instructions for recipient
      // @param to address proposed recipient of ownership
      // @param message instructions for recipient upon accepting ownership
      function transferOwnershipWithMessage(address to, bytes calldata message) external {
        transferOwnership(to);
        emit OwnershipTransferRequestedWithMessage(msg.sender, to, message);
      }
      // @notice concrete implementation of AuthorizedReceiver
      // @return bool of whether sender is authorized
      function _canSetAuthorizedSenders() internal view override returns (bool) {
        return owner() == msg.sender;
      }
      // @notice common forwarding functionality and validation
      function _forward(address to, bytes calldata data) private {
        require(to.isContract(), "Must forward to a contract");
        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory result) = to.call(data);
        if (!success) {
          if (result.length == 0) revert("Forwarded call reverted without reason");
          assembly {
            revert(add(32, result), mload(result))
          }
        }
      }
    }
    // SPDX-License-Identifier: MIT
    pragma solidity 0.8.19;
    import {IAuthorizedReceiver} from "./interfaces/IAuthorizedReceiver.sol";
    // solhint-disable gas-custom-errors
    abstract contract AuthorizedReceiver is IAuthorizedReceiver {
      mapping(address sender => bool authorized) private s_authorizedSenders;
      address[] private s_authorizedSenderList;
      event AuthorizedSendersChanged(address[] senders, address changedBy);
      // @notice Sets the fulfillment permission for a given node. Use `true` to allow, `false` to disallow.
      // @param senders The addresses of the authorized Chainlink node
      function setAuthorizedSenders(address[] calldata senders) external override validateAuthorizedSenderSetter {
        require(senders.length > 0, "Must have at least 1 sender");
        // Set previous authorized senders to false
        uint256 authorizedSendersLength = s_authorizedSenderList.length;
        for (uint256 i = 0; i < authorizedSendersLength; ++i) {
          s_authorizedSenders[s_authorizedSenderList[i]] = false;
        }
        // Set new to true
        for (uint256 i = 0; i < senders.length; ++i) {
          require(s_authorizedSenders[senders[i]] == false, "Must not have duplicate senders");
          s_authorizedSenders[senders[i]] = true;
        }
        // Replace list
        s_authorizedSenderList = senders;
        emit AuthorizedSendersChanged(senders, msg.sender);
      }
      // @notice Retrieve a list of authorized senders
      // @return array of addresses
      function getAuthorizedSenders() external view override returns (address[] memory) {
        return s_authorizedSenderList;
      }
      // @notice Use this to check if a node is authorized for fulfilling requests
      // @param sender The address of the Chainlink node
      // @return The authorization status of the node
      function isAuthorizedSender(address sender) public view override returns (bool) {
        return s_authorizedSenders[sender];
      }
      // @notice customizable guard of who can update the authorized sender list
      // @return bool whether sender can update authorized sender list
      function _canSetAuthorizedSenders() internal virtual returns (bool);
      // @notice validates the sender is an authorized sender
      function _validateIsAuthorizedSender() internal view {
        require(isAuthorizedSender(msg.sender), "Not authorized sender");
      }
      // @notice prevents non-authorized addresses from calling this method
      modifier validateAuthorizedSender() {
        _validateIsAuthorizedSender();
        _;
      }
      // @notice prevents non-authorized addresses from calling this method
      modifier validateAuthorizedSenderSetter() {
        require(_canSetAuthorizedSenders(), "Cannot set authorized senders");
        _;
      }
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    interface IAuthorizedReceiver {
      function isAuthorizedSender(address sender) external view returns (bool);
      function getAuthorizedSenders() external returns (address[] memory);
      function setAuthorizedSenders(address[] calldata senders) external;
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    import {IOwnable} from "../interfaces/IOwnable.sol";
    /// @title The ConfirmedOwner contract
    /// @notice A contract with helpers for basic contract ownership.
    contract ConfirmedOwnerWithProposal is IOwnable {
      address private s_owner;
      address private s_pendingOwner;
      event OwnershipTransferRequested(address indexed from, address indexed to);
      event OwnershipTransferred(address indexed from, address indexed to);
      constructor(address newOwner, address pendingOwner) {
        // solhint-disable-next-line gas-custom-errors
        require(newOwner != address(0), "Cannot set owner to zero");
        s_owner = newOwner;
        if (pendingOwner != address(0)) {
          _transferOwnership(pendingOwner);
        }
      }
      /// @notice Allows an owner to begin transferring ownership to a new address.
      function transferOwnership(address to) public override onlyOwner {
        _transferOwnership(to);
      }
      /// @notice Allows an ownership transfer to be completed by the recipient.
      function acceptOwnership() external override {
        // solhint-disable-next-line gas-custom-errors
        require(msg.sender == s_pendingOwner, "Must be proposed owner");
        address oldOwner = s_owner;
        s_owner = msg.sender;
        s_pendingOwner = address(0);
        emit OwnershipTransferred(oldOwner, msg.sender);
      }
      /// @notice Get the current owner
      function owner() public view override returns (address) {
        return s_owner;
      }
      /// @notice validate, transfer ownership, and emit relevant events
      function _transferOwnership(address to) private {
        // solhint-disable-next-line gas-custom-errors
        require(to != msg.sender, "Cannot transfer to self");
        s_pendingOwner = to;
        emit OwnershipTransferRequested(s_owner, to);
      }
      /// @notice validate access
      function _validateOwnership() internal view {
        // solhint-disable-next-line gas-custom-errors
        require(msg.sender == s_owner, "Only callable by owner");
      }
      /// @notice Reverts if called by anyone other than the contract owner.
      modifier onlyOwner() {
        _validateOwnership();
        _;
      }
    }
    // SPDX-License-Identifier: MIT
    pragma solidity ^0.8.0;
    interface IOwnable {
      function owner() external returns (address);
      function transferOwnership(address recipient) external;
      function acceptOwnership() external;
    }