ETH Price: $2,098.01 (+0.25%)
 

Overview

ETH Balance

0 ETH

ETH Value

$0.00

Token Holdings

More Info

Private Name Tags

Multichain Info

No addresses found
Transaction Hash
Block
From
To

There are no matching entries

8 Internal Transactions and 4 Token Transfers found.

Latest 8 internal transactions

Parent Transaction Hash Block From To
433627552026-03-14 19:00:574 hrs ago1773514857
0xDaFeB89F...d7a76d19E
16.8 ETH
433627552026-03-14 19:00:574 hrs ago1773514857
0xDaFeB89F...d7a76d19E
16.8 ETH
400015012025-12-26 23:39:0978 days ago1766792349
0xDaFeB89F...d7a76d19E
10.14 ETH
400015012025-12-26 23:39:0978 days ago1766792349
0xDaFeB89F...d7a76d19E
10.14 ETH
337411912025-08-04 1:42:09222 days ago1754271729
0xDaFeB89F...d7a76d19E
6.68 ETH
337411912025-08-04 1:42:09222 days ago1754271729
0xDaFeB89F...d7a76d19E
6.68 ETH
306167772025-05-23 17:55:01295 days ago1748022901
0xDaFeB89F...d7a76d19E
18 ETH
306167772025-05-23 17:55:01295 days ago1748022901
0xDaFeB89F...d7a76d19E
18 ETH

Cross-Chain Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
SmartInvoiceFactoryBundler

Compiler Version
v0.8.26+commit.8a97fa7a

Optimization Enabled:
Yes with 200 runs

Other Settings:
paris EvmVersion
File 1 of 14 : SmartInvoiceFactoryBundler.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

import {ISmartInvoiceFactory} from "./interfaces/ISmartInvoiceFactory.sol";
import {ISmartInvoiceEscrow} from "./interfaces/ISmartInvoiceEscrow.sol";
import {IWRAPPED} from "./interfaces/IWRAPPED.sol";
import {IERC20} from "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import {SafeERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {ReentrancyGuard} from "@openzeppelin/contracts/utils/ReentrancyGuard.sol";

/// @title SmartInvoiceFactoryBundler
/// @notice A contract for creating and managing SmartInvoice escrow with customizable settings.
contract SmartInvoiceFactoryBundler is ReentrancyGuard {
    using SafeERC20 for IERC20;

    /// @notice Address of the SmartInvoiceFactory
    ISmartInvoiceFactory public escrowFactory;

    /// @notice Address of the wrapped native token (e.g., WETH)
    IWRAPPED public wrappedNativeToken;

    /// @notice Error emitted when escrow creation fails
    error EscrowNotCreated();

    /// @notice Error emitted when the fund amount is invalid
    error InvalidFundAmount();

    /// @notice Event emitted when a new escrow is created
    /// @param escrow Address of the newly created escrow
    /// @param token Address of the token used for payment
    /// @param amount The total fund amount transferred to the escrow
    event EscrowCreated(
        address indexed escrow,
        address indexed token,
        uint256 amount
    );

    /// @notice Constructor to initialize the contract with the factory and wrapped token addresses
    /// @param _escrowFactory Address of the SmartInvoiceFactory
    /// @param _wrappedNativeToken Address of the wrapped native token (e.g., WETH)
    constructor(address _escrowFactory, address _wrappedNativeToken) {
        escrowFactory = ISmartInvoiceFactory(_escrowFactory);
        wrappedNativeToken = IWRAPPED(_wrappedNativeToken);
    }

    /// @notice Internal function to deploy a new escrow contract with provided details and milestone amounts
    /// @param _milestoneAmounts Array representing the milestone payment amounts
    /// @param _escrowData Encoded escrow data
    /// @param _fundAmount Total amount to be funded into the escrow
    /// @return escrow Address of the newly deployed escrow
    function deployEscrow(
        address _provider,
        uint256[] memory _milestoneAmounts,
        bytes calldata _escrowData,
        bytes32 _escrowType,
        uint256 _fundAmount
    ) public payable nonReentrant returns (address escrow) {

        // Deploy the new escrow contract using the factory
        escrow = escrowFactory.create(
            _provider,
            _milestoneAmounts,
            _escrowData,
            _escrowType
        );

        // Ensure escrow creation was successful
        if (escrow == address(0)) revert EscrowNotCreated();

        address token = ISmartInvoiceEscrow(escrow).token();

        if (token == address(wrappedNativeToken) && msg.value > 0) {
            // Ensure the fund amount is valid
            if (msg.value != _fundAmount) revert InvalidFundAmount();

            // Transfer the native fund amount to the newly created escrow contract
            // Require the client to approve the fund transfer
            wrappedNativeToken.deposit{value: _fundAmount}();

            // Transfer the fund amount to the newly created escrow contract
            // Require the client to approve the fund transfer
            IERC20(token).safeTransfer(escrow, _fundAmount);
        } else {
            // Transfer the fund amount to the newly created escrow contract
            // Require the client to approve the fund transfer
            IERC20(token).safeTransferFrom(
                msg.sender,
                escrow,
                _fundAmount
            );
        }

        // Emit an event for the escrow creation
        emit EscrowCreated(escrow, token, _fundAmount);
    }
}

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

pragma solidity ^0.8.20;

import {IERC20} from "./IERC20.sol";
import {IERC165} from "./IERC165.sol";

/**
 * @title IERC1363
 * @dev Interface of the ERC-1363 standard as defined in the https://eips.ethereum.org/EIPS/eip-1363[ERC-1363].
 *
 * Defines an extension interface for ERC-20 tokens that supports executing code on a recipient contract
 * after `transfer` or `transferFrom`, or code on a spender contract after `approve`, in a single transaction.
 */
interface IERC1363 is IERC20, IERC165 {
    /*
     * Note: the ERC-165 identifier for this interface is 0xb0202a11.
     * 0xb0202a11 ===
     *   bytes4(keccak256('transferAndCall(address,uint256)')) ^
     *   bytes4(keccak256('transferAndCall(address,uint256,bytes)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256)')) ^
     *   bytes4(keccak256('transferFromAndCall(address,address,uint256,bytes)')) ^
     *   bytes4(keccak256('approveAndCall(address,uint256)')) ^
     *   bytes4(keccak256('approveAndCall(address,uint256,bytes)'))
     */

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferAndCall(address to, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @param data Additional data with no specified format, sent in call to `to`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferAndCall(address to, uint256 value, bytes calldata data) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param from The address which you want to send tokens from.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferFromAndCall(address from, address to, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the allowance mechanism
     * and then calls {IERC1363Receiver-onTransferReceived} on `to`.
     * @param from The address which you want to send tokens from.
     * @param to The address which you want to transfer to.
     * @param value The amount of tokens to be transferred.
     * @param data Additional data with no specified format, sent in call to `to`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function transferFromAndCall(address from, address to, uint256 value, bytes calldata data) external returns (bool);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function approveAndCall(address spender, uint256 value) external returns (bool);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens and then calls {IERC1363Spender-onApprovalReceived} on `spender`.
     * @param spender The address which will spend the funds.
     * @param value The amount of tokens to be spent.
     * @param data Additional data with no specified format, sent in call to `spender`.
     * @return A boolean value indicating whether the operation succeeded unless throwing.
     */
    function approveAndCall(address spender, uint256 value, bytes calldata data) external returns (bool);
}

File 3 of 14 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC165.sol)

pragma solidity ^0.8.20;

import {IERC165} from "../utils/introspection/IERC165.sol";

File 4 of 14 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../token/ERC20/IERC20.sol";

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC-20 standard as defined in the ERC.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the value of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves a `value` amount of tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 value) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets a `value` amount of tokens as the allowance of `spender` over the
     * caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 value) external returns (bool);

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to` using the
     * allowance mechanism. `value` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 value) external returns (bool);
}

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/utils/SafeERC20.sol)

pragma solidity ^0.8.20;

import {IERC20} from "../IERC20.sol";
import {IERC1363} from "../../../interfaces/IERC1363.sol";
import {Address} from "../../../utils/Address.sol";

/**
 * @title SafeERC20
 * @dev Wrappers around ERC-20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    /**
     * @dev An operation with an ERC-20 token failed.
     */
    error SafeERC20FailedOperation(address token);

    /**
     * @dev Indicates a failed `decreaseAllowance` request.
     */
    error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease);

    /**
     * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     */
    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value)));
    }

    /**
     * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
     * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
     */
    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value)));
    }

    /**
     * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful.
     *
     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
     * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
     */
    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 oldAllowance = token.allowance(address(this), spender);
        forceApprove(token, spender, oldAllowance + value);
    }

    /**
     * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no
     * value, non-reverting calls are assumed to be successful.
     *
     * IMPORTANT: If the token implements ERC-7674 (ERC-20 with temporary allowance), and if the "client"
     * smart contract uses ERC-7674 to set temporary allowances, then the "client" smart contract should avoid using
     * this function. Performing a {safeIncreaseAllowance} or {safeDecreaseAllowance} operation on a token contract
     * that has a non-zero temporary allowance (for that particular owner-spender) will result in unexpected behavior.
     */
    function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal {
        unchecked {
            uint256 currentAllowance = token.allowance(address(this), spender);
            if (currentAllowance < requestedDecrease) {
                revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease);
            }
            forceApprove(token, spender, currentAllowance - requestedDecrease);
        }
    }

    /**
     * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
     * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
     * to be set to zero before setting it to a non-zero value, such as USDT.
     *
     * NOTE: If the token implements ERC-7674, this function will not modify any temporary allowance. This function
     * only sets the "standard" allowance. Any temporary allowance will remain active, in addition to the value being
     * set here.
     */
    function forceApprove(IERC20 token, address spender, uint256 value) internal {
        bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value));

        if (!_callOptionalReturnBool(token, approvalCall)) {
            _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0)));
            _callOptionalReturn(token, approvalCall);
        }
    }

    /**
     * @dev Performs an {ERC1363} transferAndCall, with a fallback to the simple {ERC20} transfer if the target has no
     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
     * targeting contracts.
     *
     * Reverts if the returned value is other than `true`.
     */
    function transferAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
        if (to.code.length == 0) {
            safeTransfer(token, to, value);
        } else if (!token.transferAndCall(to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Performs an {ERC1363} transferFromAndCall, with a fallback to the simple {ERC20} transferFrom if the target
     * has no code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
     * targeting contracts.
     *
     * Reverts if the returned value is other than `true`.
     */
    function transferFromAndCallRelaxed(
        IERC1363 token,
        address from,
        address to,
        uint256 value,
        bytes memory data
    ) internal {
        if (to.code.length == 0) {
            safeTransferFrom(token, from, to, value);
        } else if (!token.transferFromAndCall(from, to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Performs an {ERC1363} approveAndCall, with a fallback to the simple {ERC20} approve if the target has no
     * code. This can be used to implement an {ERC721}-like safe transfer that rely on {ERC1363} checks when
     * targeting contracts.
     *
     * NOTE: When the recipient address (`to`) has no code (i.e. is an EOA), this function behaves as {forceApprove}.
     * Opposedly, when the recipient address (`to`) has code, this function only attempts to call {ERC1363-approveAndCall}
     * once without retrying, and relies on the returned value to be true.
     *
     * Reverts if the returned value is other than `true`.
     */
    function approveAndCallRelaxed(IERC1363 token, address to, uint256 value, bytes memory data) internal {
        if (to.code.length == 0) {
            forceApprove(token, to, value);
        } else if (!token.approveAndCall(to, value, data)) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturnBool} that reverts if call fails to meet the requirements.
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        uint256 returnSize;
        uint256 returnValue;
        assembly ("memory-safe") {
            let success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
            // bubble errors
            if iszero(success) {
                let ptr := mload(0x40)
                returndatacopy(ptr, 0, returndatasize())
                revert(ptr, returndatasize())
            }
            returnSize := returndatasize()
            returnValue := mload(0)
        }

        if (returnSize == 0 ? address(token).code.length == 0 : returnValue != 1) {
            revert SafeERC20FailedOperation(address(token));
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     *
     * This is a variant of {_callOptionalReturn} that silently catches all reverts and returns a bool instead.
     */
    function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
        bool success;
        uint256 returnSize;
        uint256 returnValue;
        assembly ("memory-safe") {
            success := call(gas(), token, 0, add(data, 0x20), mload(data), 0, 0x20)
            returnSize := returndatasize()
            returnValue := mload(0)
        }
        return success && (returnSize == 0 ? address(token).code.length > 0 : returnValue == 1);
    }
}

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

pragma solidity ^0.8.20;

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

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @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.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert Errors.InsufficientBalance(address(this).balance, amount);
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert Errors.FailedCall();
        }
    }

    /**
     * @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 or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {Errors.FailedCall} error.
     *
     * 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.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @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`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert Errors.InsufficientBalance(address(this).balance, value);
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {Errors.FailedCall}) in case
     * of an unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {Errors.FailedCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {Errors.FailedCall}.
     */
    function _revert(bytes memory returndata) 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
            assembly ("memory-safe") {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert Errors.FailedCall();
        }
    }
}

File 8 of 14 : Errors.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/Errors.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of common custom errors used in multiple contracts
 *
 * IMPORTANT: Backwards compatibility is not guaranteed in future versions of the library.
 * It is recommended to avoid relying on the error API for critical functionality.
 *
 * _Available since v5.1._
 */
library Errors {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error InsufficientBalance(uint256 balance, uint256 needed);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedCall();

    /**
     * @dev The deployment failed.
     */
    error FailedDeployment();

    /**
     * @dev A necessary precompile is missing.
     */
    error MissingPrecompile(address);
}

// 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.1.0) (utils/ReentrancyGuard.sol)

pragma solidity ^0.8.20;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If EIP-1153 (transient storage) is available on the chain you're deploying at,
 * consider using {ReentrancyGuardTransient} instead.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant NOT_ENTERED = 1;
    uint256 private constant ENTERED = 2;

    uint256 private _status;

    /**
     * @dev Unauthorized reentrant call.
     */
    error ReentrancyGuardReentrantCall();

    constructor() {
        _status = NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be NOT_ENTERED
        if (_status == ENTERED) {
            revert ReentrancyGuardReentrantCall();
        }

        // Any calls to nonReentrant after this point will fail
        _status = ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == ENTERED;
    }
}

File 11 of 14 : ISmartInvoice.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

/// @title ISmartInvoice
/// @notice Interface for the Smart Invoice contract, allowing initialization with recipient details, amounts, and data.
interface ISmartInvoice {
    /**
     * @notice Initializes the Smart Invoice with the provided recipient, amounts, and data.
     * @param _recipient The address of the recipient to receive payments.
     * @param _amounts An array of amounts representing payments or milestones.
     * @param _data Additional data needed for initialization, encoded as bytes.
     */
    function init(
        address _recipient,
        uint256[] calldata _amounts,
        bytes calldata _data
    ) external;
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

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

/// @title ISmartInvoiceEscrow
/// @notice Interface for Smart Invoice Escrow functionality with customizable milestones, releases, and dispute resolution.
interface ISmartInvoiceEscrow is ISmartInvoice {
    /**
        @notice Returns the address of the token used for payment.
        @return token The address of the token used for payment.
    */
    function token() external view returns (address token); 

    /**
     * @notice Adds new milestones to the invoice.
     * @param _milestones An array of milestone amounts to be added.
     */
    function addMilestones(uint256[] calldata _milestones) external;

    /**
     * @notice Adds new milestones to the invoice with additional details.
     * @param _milestones An array of milestone amounts to be added.
     * @param _details Additional details associated with the milestones.
     */
    function addMilestones(
        uint256[] calldata _milestones,
        bytes32 _details
    ) external;

    /**
     * @notice Releases funds for the next milestone.
     */
    function release() external;

    /**
     * @notice Releases funds for a specific milestone.
     * @param _milestone The milestone number to release funds for.
     */
    function release(uint256 _milestone) external;

    /**
     * @notice Releases all tokens of a specified type from the contract.
     * @param _token The address of the token to be released.
     */
    function releaseTokens(address _token) external;

    /**
     * @notice Verifies the client and the contract are correctly paired.
     */
    function verify() external;

    /**
     * @notice Withdraws funds from the contract to the client.
     */
    function withdraw() external;

    /**
     * @notice Withdraws tokens of a specified type from the contract to the client.
     * @param _token The address of the token to be withdrawn.
     */
    function withdrawTokens(address _token) external;

    /**
     * @notice Locks the contract to prevent further actions until resolved.
     * @param _details The details of the dispute or reason for locking.
     */
    function lock(bytes32 _details) external payable;

    /**
     * @notice Resolves a dispute by awarding funds to the client and provider.
     * @param _clientAward The amount to be awarded to the client.
     * @param _providerAward The amount to be awarded to the provider.
     * @param _details Additional details of the resolution.
     */
    function resolve(
        uint256 _clientAward,
        uint256 _providerAward,
        bytes32 _details
    ) external;

    /// @dev Custom errors for more efficient gas usage

    error InvalidProvider();
    error InvalidClient();
    error InvalidResolverType();
    error InvalidResolver();
    error InvalidToken();
    error DurationEnded();
    error DurationTooLong();
    error InvalidResolutionRate();
    error InvalidWrappedNativeToken();
    error NotClient();
    error NotProvider();
    error NotParty();
    error Locked();
    error Terminated();
    error NoMilestones();
    error ExceedsMilestoneLimit();
    error InsufficientBalance();
    error BalanceIsZero();
    error InvalidMilestone();
    error IncorrectDisputeId();
    error InvalidRuling();
    error InvalidIndividualResolver();
    error InvalidArbitratorResolver();
    error NotResolver();
    error ResolutionMismatch();

    /// @notice Emitted when new milestones are added to the invoice.
    /// @param sender The address that added the milestones.
    /// @param invoice The address of the invoice.
    /// @param milestones The array of milestone amounts added.
    event MilestonesAdded(
        address indexed sender,
        address indexed invoice,
        uint256[] milestones
    );

    /// @notice Emitted when the details of the invoice are updated.
    /// @param sender The address that updated the details.
    /// @param details The new details of the invoice.
    event DetailsUpdated(address indexed sender, bytes32 details);

    /// @notice Emitted when a deposit is made into the invoice.
    /// @param sender The address that made the deposit.
    /// @param amount The amount of the deposit.
    event Deposit(address indexed sender, uint256 amount);

    /// @notice Emitted when a milestone is released.
    /// @param milestone The milestone number that was released.
    /// @param amount The amount released for the milestone.
    event Release(uint256 milestone, uint256 amount);

    /// @notice Emitted when funds are withdrawn from the invoice.
    /// @param balance The amount withdrawn.
    event Withdraw(uint256 balance);

    /// @notice Emitted when the contract is locked.
    /// @param sender The address that locked the contract.
    /// @param details The details of the lock.
    event Lock(address indexed sender, bytes32 details);

    /// @notice Emitted when a dispute is resolved.
    /// @param resolver The address that resolved the dispute.
    /// @param clientAward The amount awarded to the client.
    /// @param providerAward The amount awarded to the provider.
    /// @param resolutionFee The fee deducted for resolving the dispute.
    /// @param details Additional details of the resolution.
    event Resolve(
        address indexed resolver,
        uint256 clientAward,
        uint256 providerAward,
        uint256 resolutionFee,
        bytes32 details
    );

    /// @notice Emitted when a ruling is made on a dispute.
    /// @param resolver The address that made the ruling.
    /// @param clientAward The amount awarded to the client.
    /// @param providerAward The amount awarded to the provider.
    /// @param ruling The ruling number representing the decision.
    event Rule(
        address indexed resolver,
        uint256 clientAward,
        uint256 providerAward,
        uint256 ruling
    );

    /// @notice Emitted when the client and invoice are verified.
    /// @param client The address of the client.
    /// @param invoice The address of the invoice.
    event Verified(address indexed client, address indexed invoice);
}

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

/// @title ISmartInvoiceFactory
/// @notice Interface for the Smart Invoice Factory contract that facilitates creating and managing Smart Invoices.
interface ISmartInvoiceFactory {
    /**
     * @notice Creates a new Smart Invoice with the provided recipient, amounts, and data.
     * @param _recipient The address of the recipient to receive payments.
     * @param _amounts An array of amounts representing payments or milestones.
     * @param _data Additional data needed for initialization, encoded as bytes.
     * @param _type The type of the Smart Invoice to be created.
     * @return The address of the newly created Smart Invoice.
     */
    function create(
        address _recipient,
        uint256[] calldata _amounts,
        bytes calldata _data,
        bytes32 _type
    ) external returns (address);

    /**
     * @notice Creates a new Smart Invoice deterministically using a salt value.
     * @param _recipient The address of the recipient to receive payments.
     * @param _amounts An array of amounts representing payments or milestones.
     * @param _data Additional data needed for initialization, encoded as bytes.
     * @param _type The type of the Smart Invoice to be created.
     * @param _salt The salt value used for deterministic address calculation.
     * @return The address of the newly created Smart Invoice.
     */
    function createDeterministic(
        address _recipient,
        uint256[] calldata _amounts,
        bytes calldata _data,
        bytes32 _type,
        bytes32 _salt
    ) external returns (address);

    /**
     * @notice Predicts the deterministic address of a Smart Invoice to be created with a specific salt.
     * @param _type The type of the Smart Invoice.
     * @param _salt The salt value used for deterministic address calculation.
     * @return The predicted deterministic address of the Smart Invoice.
     */
    function predictDeterministicAddress(
        bytes32 _type,
        bytes32 _salt
    ) external returns (address);

    /**
     * @notice Returns the resolution rate for a specific resolver address.
     * @param _resolver The address of the resolver.
     * @return The resolution rate for the specified resolver.
     */
    function resolutionRateOf(
        address _resolver
    ) external view returns (uint256);

    /// @dev Error definitions for more efficient gas usage.

    /// @notice Reverts when the wrapped native token is invalid.
    error InvalidWrappedNativeToken();

    /// @notice Reverts when the requested implementation does not exist.
    error ImplementationDoesNotExist();

    /// @notice Reverts when the implementation address provided is the zero address.
    error ZeroAddressImplementation();

    /// @notice Emitted when a new invoice is created.
    /// @param invoiceId The ID of the created invoice.
    /// @param invoiceAddress The address of the created invoice.
    /// @param amounts The amounts associated with the invoice.
    /// @param invoiceType The type of the invoice.
    /// @param version The version of the invoice implementation.
    event LogNewInvoice(
        uint256 indexed invoiceId,
        address indexed invoiceAddress,
        uint256[] amounts,
        bytes32 indexed invoiceType,
        uint256 version
    );

    /// @notice Emitted when a new implementation is added.
    /// @param invoiceType The type of the invoice.
    /// @param version The version of the invoice implementation.
    /// @param implementation The address of the new implementation.
    event AddImplementation(
        bytes32 indexed invoiceType,
        uint256 version,
        address implementation
    );

    /// @notice Emitted when the resolution rate is updated.
    /// @param resolver The address of the resolver.
    /// @param resolutionRate The new resolution rate.
    /// @param details Additional details about the update.
    event UpdateResolutionRate(
        address indexed resolver,
        uint256 resolutionRate,
        bytes32 details
    );
}

File 14 of 14 : IWRAPPED.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.20;

/// @title IWRAPPED
/// @notice Interface for a canonical native token wrapper contract, typically used to wrap native blockchain tokens into ERC20 tokens.
interface IWRAPPED {
    /**
     * @notice Deposits native tokens into the contract and wraps them.
     * @dev This function is payable and should be called with a specific amount of native tokens to wrap.
     * The native tokens sent with the call will be wrapped and the corresponding wrapped token amount will be credited to the sender's address.
     */
    function deposit() external payable;
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_escrowFactory","type":"address"},{"internalType":"address","name":"_wrappedNativeToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"EscrowNotCreated","type":"error"},{"inputs":[],"name":"InvalidFundAmount","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"SafeERC20FailedOperation","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"escrow","type":"address"},{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EscrowCreated","type":"event"},{"inputs":[{"internalType":"address","name":"_provider","type":"address"},{"internalType":"uint256[]","name":"_milestoneAmounts","type":"uint256[]"},{"internalType":"bytes","name":"_escrowData","type":"bytes"},{"internalType":"bytes32","name":"_escrowType","type":"bytes32"},{"internalType":"uint256","name":"_fundAmount","type":"uint256"}],"name":"deployEscrow","outputs":[{"internalType":"address","name":"escrow","type":"address"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"escrowFactory","outputs":[{"internalType":"contract ISmartInvoiceFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wrappedNativeToken","outputs":[{"internalType":"contract IWRAPPED","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6080604052348015600f57600080fd5b50604051610769380380610769833981016040819052602c91607c565b6001600081905580546001600160a01b039384166001600160a01b0319918216179091556002805492909316911617905560aa565b80516001600160a01b0381168114607757600080fd5b919050565b60008060408385031215608e57600080fd5b6095836061565b915060a1602084016061565b90509250929050565b6106b0806100b96000396000f3fe6080604052600436106100345760003560e01c806317fcb39b14610039578063bdd1daaa14610075578063ecccfad814610095575b600080fd5b34801561004557600080fd5b50600254610059906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b34801561008157600080fd5b50600154610059906001600160a01b031681565b6100596100a33660046104ae565b60006100ad6102f5565b60015460405163fc2b2c5b60e01b81526001600160a01b039091169063fc2b2c5b906100e5908a908a908a908a908a906004016105ce565b6020604051808303816000875af1158015610104573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101289190610656565b90506001600160a01b0381166101515760405163394708ef60e01b815260040160405180910390fd5b6000816001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610191573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b59190610656565b6002549091506001600160a01b0380831691161480156101d55750600034115b1561027e578234146101fa5760405163213cf26b60e01b815260040160405180910390fd5b600260009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b15801561024a57600080fd5b505af115801561025e573d6000803e3d6000fd5b50610279935050506001600160a01b0383169050838561031f565b610293565b6102936001600160a01b038216338486610383565b806001600160a01b0316826001600160a01b03167f78da7430b15648a5954de6bf3f6dc65a9eb64c292537d89a2a9989fdd3679923856040516102d891815260200190565b60405180910390a3506102eb6001600055565b9695505050505050565b60026000540361031857604051633ee5aeb560e01b815260040160405180910390fd5b6002600055565b6040516001600160a01b0383811660248301526044820183905261037e91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506103c2565b505050565b6040516001600160a01b0384811660248301528381166044830152606482018390526103bc9186918216906323b872dd9060840161034c565b50505050565b600080602060008451602086016000885af1806103e5576040513d6000823e3d81fd5b50506000513d915081156103fd57806001141561040a565b6001600160a01b0384163b155b156103bc57604051635274afe760e01b81526001600160a01b038516600482015260240160405180910390fd5b6001600160a01b038116811461044c57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60008083601f84011261047757600080fd5b50813567ffffffffffffffff81111561048f57600080fd5b6020830191508360208285010111156104a757600080fd5b9250929050565b60008060008060008060a087890312156104c757600080fd5b86356104d281610437565b9550602087013567ffffffffffffffff8111156104ee57600080fd5b8701601f810189136104ff57600080fd5b803567ffffffffffffffff8111156105195761051961044f565b8060051b604051601f19603f830116810181811067ffffffffffffffff821117156105465761054661044f565b60405291825260208184018101929081018c84111561056457600080fd5b6020850194505b838510156105875784358082526020958601959093500161056b565b509750505050604087013567ffffffffffffffff8111156105a757600080fd5b6105b389828a01610465565b979a9699509760608101359660809091013595509350505050565b6001600160a01b03861681526080602080830182905286519183018290526000919087019060a0840190835b818110156106185783518352602093840193909201916001016105fa565b50508381036040850152858152858760208301376000602087830101526020601f19601f880116820101925050508260608301529695505050505050565b60006020828403121561066857600080fd5b815161067381610437565b939250505056fea2646970667358221220b76bf1e33c8bbcd9eddc88d3b77387ff42a8e62dc795c80e58206f394d15eb3364736f6c634300081a0033000000000000000000000000f9822818143948237a60a1a1cefc85d6f1b929df0000000000000000000000004200000000000000000000000000000000000006

Deployed Bytecode

0x6080604052600436106100345760003560e01c806317fcb39b14610039578063bdd1daaa14610075578063ecccfad814610095575b600080fd5b34801561004557600080fd5b50600254610059906001600160a01b031681565b6040516001600160a01b03909116815260200160405180910390f35b34801561008157600080fd5b50600154610059906001600160a01b031681565b6100596100a33660046104ae565b60006100ad6102f5565b60015460405163fc2b2c5b60e01b81526001600160a01b039091169063fc2b2c5b906100e5908a908a908a908a908a906004016105ce565b6020604051808303816000875af1158015610104573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101289190610656565b90506001600160a01b0381166101515760405163394708ef60e01b815260040160405180910390fd5b6000816001600160a01b031663fc0c546a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610191573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906101b59190610656565b6002549091506001600160a01b0380831691161480156101d55750600034115b1561027e578234146101fa5760405163213cf26b60e01b815260040160405180910390fd5b600260009054906101000a90046001600160a01b03166001600160a01b031663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b15801561024a57600080fd5b505af115801561025e573d6000803e3d6000fd5b50610279935050506001600160a01b0383169050838561031f565b610293565b6102936001600160a01b038216338486610383565b806001600160a01b0316826001600160a01b03167f78da7430b15648a5954de6bf3f6dc65a9eb64c292537d89a2a9989fdd3679923856040516102d891815260200190565b60405180910390a3506102eb6001600055565b9695505050505050565b60026000540361031857604051633ee5aeb560e01b815260040160405180910390fd5b6002600055565b6040516001600160a01b0383811660248301526044820183905261037e91859182169063a9059cbb906064015b604051602081830303815290604052915060e01b6020820180516001600160e01b0383818316178352505050506103c2565b505050565b6040516001600160a01b0384811660248301528381166044830152606482018390526103bc9186918216906323b872dd9060840161034c565b50505050565b600080602060008451602086016000885af1806103e5576040513d6000823e3d81fd5b50506000513d915081156103fd57806001141561040a565b6001600160a01b0384163b155b156103bc57604051635274afe760e01b81526001600160a01b038516600482015260240160405180910390fd5b6001600160a01b038116811461044c57600080fd5b50565b634e487b7160e01b600052604160045260246000fd5b60008083601f84011261047757600080fd5b50813567ffffffffffffffff81111561048f57600080fd5b6020830191508360208285010111156104a757600080fd5b9250929050565b60008060008060008060a087890312156104c757600080fd5b86356104d281610437565b9550602087013567ffffffffffffffff8111156104ee57600080fd5b8701601f810189136104ff57600080fd5b803567ffffffffffffffff8111156105195761051961044f565b8060051b604051601f19603f830116810181811067ffffffffffffffff821117156105465761054661044f565b60405291825260208184018101929081018c84111561056457600080fd5b6020850194505b838510156105875784358082526020958601959093500161056b565b509750505050604087013567ffffffffffffffff8111156105a757600080fd5b6105b389828a01610465565b979a9699509760608101359660809091013595509350505050565b6001600160a01b03861681526080602080830182905286519183018290526000919087019060a0840190835b818110156106185783518352602093840193909201916001016105fa565b50508381036040850152858152858760208301376000602087830101526020601f19601f880116820101925050508260608301529695505050505050565b60006020828403121561066857600080fd5b815161067381610437565b939250505056fea2646970667358221220b76bf1e33c8bbcd9eddc88d3b77387ff42a8e62dc795c80e58206f394d15eb3364736f6c634300081a0033

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

000000000000000000000000f9822818143948237a60a1a1cefc85d6f1b929df0000000000000000000000004200000000000000000000000000000000000006

-----Decoded View---------------
Arg [0] : _escrowFactory (address): 0xF9822818143948237A60A1a1CEFC85D6F1b929Df
Arg [1] : _wrappedNativeToken (address): 0x4200000000000000000000000000000000000006

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000f9822818143948237a60a1a1cefc85d6f1b929df
Arg [1] : 0000000000000000000000004200000000000000000000000000000000000006


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
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.