xDAI Price: $0.999998 (-0.01%)
Gas: 1 GWei

Contract

0xDdd11DC80A25563Cb416647821f3BC5Ad75fF1BA

Overview

xDAI Balance

Gnosis Chain LogoGnosis Chain LogoGnosis Chain Logo0 xDAI

xDAI Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To

There are no matching entries

1 Internal Transaction found.

Latest 1 internal transaction

Parent Transaction Hash Block From To
385430472025-02-13 14:46:4068 days ago1739458000  Contract Creation0 xDAI
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
TradingModule

Compiler Version
v0.8.28+commit.7893614a

Optimization Enabled:
Yes with 10000 runs

Other Settings:
cancun EvmVersion
File 1 of 17 : TradingModule.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.28;

import { Enum } from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";
import { Module } from "@gnosis-guild/zodiac/contracts/core/Module.sol";
import { Guardable } from "@gnosis-guild/zodiac/contracts/guard/Guardable.sol";
import { GPv2Order } from "cowprotocol/contracts/src/contracts/libraries/GPv2Order.sol";
import { GPv2Signing } from "cowprotocol/contracts/src/contracts/mixins/GPv2Signing.sol";

import { IAvatar } from "@gnosis-guild/zodiac/contracts/interfaces/IAvatar.sol";
import { IGuard } from "@gnosis-guild/zodiac/contracts/interfaces/IGuard.sol";

contract TradingModule is Module, Guardable {
    using GPv2Order for bytes;

    /// @notice Emitted when an order was successfully set
    event SetOrder(bytes indexed orderUid, bool indexed signed);

    /// @notice Thrown when the supplied order UID and order is mismatched
    error InvalidOrderUID();

    /// @notice Thrown when the transaction cannot execute
    error CannotExec();

    /// @notice Thrown when the trader address is the zero address
    error ZeroAddress();

    /// @notice Thrown when a trader is not allowed to set orders on behalf of the target
    error InvalidTrader();

    /// @notice GPv2Settlement address
    /// @dev Deterministically deployed
    address public constant GPV2_SETTLEMENT_ADDRESS = 0x9008D19f58AAbD9eD0D60971565AA8510560ab41;

    /// @notice Allowed trader addresses to place orders on behalf of the Safe
    mapping(address trader => bool allowed) internal allowedTraders;

    /// @notice GPv2Settlement domain separator
    bytes32 internal domainSeparator;

    constructor(address _owner, address _avatar, address _target) {
        bytes memory initParams = abi.encode(_owner, _avatar, _target);
        setUp(initParams);
    }

    function setUp(bytes memory initParams) public override initializer {
        (address _owner, address _avatar, address _target) = abi.decode(initParams, (address, address, address));

        __Ownable_init(msg.sender);

        setAvatar(_avatar);
        setTarget(_target);

        domainSeparator = GPv2Signing(GPV2_SETTLEMENT_ADDRESS).domainSeparator();

        transferOwnership(_owner);
    }

    /// @notice Sets the allowed trader address that can set orders on behalf of the target Safe
    /// @dev Only the owner can call this function
    /// @param trader The trader address to set
    /// @param allowed Allowed boolean
    function setAllowedTraders(address trader, bool allowed) external onlyOwner {
        require(trader != address(0), ZeroAddress());
        allowedTraders[trader] = allowed;
    }

    /// @notice A trader can set the tradeability of an off-chain pre-signed CoW Swap order
    /// @dev The following checks are made:
    ///      - orderUid is validated against the supplied order details
    ///      - trading on CoW Swap (calling GPv2Settlement.setPreSignature)
    ///      - buy and sell tokens are on the token allowlist
    /// @param orderUid The orderUid obtained from the order book api
    /// @param order The order details sent to the order book api
    /// @param signed Whether the order should be tradeable
    function setOrder(bytes memory orderUid, GPv2Order.Data memory order, bool signed) external {
        require(allowedTraders[msg.sender] == true, InvalidTrader());
        bytes memory uid = new bytes(GPv2Order.UID_LENGTH);
        uid.packOrderUidParams(GPv2Order.hash(order, domainSeparator), owner(), order.validTo);
        require(keccak256(orderUid) == keccak256(uid), InvalidOrderUID());

        bytes memory txData = abi.encodeCall(GPv2Signing.setPreSignature, (orderUid, signed));
        bytes memory data = abi.encode(txData, address(order.sellToken), address(order.buyToken));

        require(exec(GPV2_SETTLEMENT_ADDRESS, 0, data, Enum.Operation.Call), CannotExec());

        emit SetOrder(orderUid, signed);
    }

    /// @notice Executes the transaction from module with the guard checks
    function exec(
        address to,
        uint256 value,
        bytes memory data,
        Enum.Operation operation
    )
        internal
        override
        returns (bool)
    {
        IGuard(guard).checkTransaction(to, value, data, operation, 0, 0, 0, address(0), payable(0), "", msg.sender);

        (bytes memory txData,,) = abi.decode(data, (bytes, address, address));

        return IAvatar(target).execTransactionFromModule(to, value, txData, operation);
    }
}

File 2 of 17 : Enum.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

/// @title Enum - Collection of enums
/// @author Richard Meissner - <[email protected]>
contract Enum {
    enum Operation {Call, DelegateCall}
}

File 3 of 17 : Module.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";

import {FactoryFriendly} from "../factory/FactoryFriendly.sol";
import {IAvatar} from "../interfaces/IAvatar.sol";

/// @title Module Interface - A contract that can pass messages to a Module Manager contract if enabled by that contract.
abstract contract Module is FactoryFriendly {
  /// @dev Address that will ultimately execute function calls.
  address public avatar;
  /// @dev Address that this module will pass transactions to.
  address public target;

  /// @dev Emitted each time the avatar is set.
  event AvatarSet(address indexed previousAvatar, address indexed newAvatar);
  /// @dev Emitted each time the Target is set.
  event TargetSet(address indexed previousTarget, address indexed newTarget);

  /// @dev Sets the avatar to a new avatar (`newAvatar`).
  /// @notice Can only be called by the current owner.
  function setAvatar(address _avatar) public onlyOwner {
    address previousAvatar = avatar;
    avatar = _avatar;
    emit AvatarSet(previousAvatar, _avatar);
  }

  /// @dev Sets the target to a new target (`newTarget`).
  /// @notice Can only be called by the current owner.
  function setTarget(address _target) public onlyOwner {
    address previousTarget = target;
    target = _target;
    emit TargetSet(previousTarget, _target);
  }

  /// @dev Passes a transaction to be executed by the avatar.
  /// @notice Can only be called by this contract.
  /// @param to Destination address of module transaction.
  /// @param value Ether value of module transaction.
  /// @param data Data payload of module transaction.
  /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.
  function exec(
    address to,
    uint256 value,
    bytes memory data,
    Enum.Operation operation
  ) internal virtual returns (bool success) {
    return
      IAvatar(target).execTransactionFromModule(to, value, data, operation);
  }

  /// @dev Passes a transaction to be executed by the target and returns data.
  /// @notice Can only be called by this contract.
  /// @param to Destination address of module transaction.
  /// @param value Ether value of module transaction.
  /// @param data Data payload of module transaction.
  /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.
  function execAndReturnData(
    address to,
    uint256 value,
    bytes memory data,
    Enum.Operation operation
  ) internal virtual returns (bool success, bytes memory returnData) {
    return
      IAvatar(target).execTransactionFromModuleReturnData(
        to,
        value,
        data,
        operation
      );
  }
}

File 4 of 17 : Guardable.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

import {BaseGuard} from "../guard/BaseGuard.sol";
import {IGuard} from "../interfaces/IGuard.sol";

/// @title Guardable - A contract that manages fallback calls made to this contract
contract Guardable is OwnableUpgradeable {
  address public guard;

  event ChangedGuard(address guard);

  /// `guard_` does not implement IERC165.
  error NotIERC165Compliant(address guard_);

  /// @dev Set a guard that checks transactions before execution.
  /// @param _guard The address of the guard to be used or the 0 address to disable the guard.
  function setGuard(address _guard) external onlyOwner {
    if (_guard != address(0)) {
      if (!BaseGuard(_guard).supportsInterface(type(IGuard).interfaceId))
        revert NotIERC165Compliant(_guard);
    }
    guard = _guard;
    emit ChangedGuard(guard);
  }

  function getGuard() external view returns (address _guard) {
    return guard;
  }
}

File 5 of 17 : GPv2Order.sol
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity >=0.7.6 <0.9.0;

import "../interfaces/IERC20.sol";

/// @title Gnosis Protocol v2 Order Library
/// @author Gnosis Developers
library GPv2Order {
    /// @dev The complete data for a Gnosis Protocol order. This struct contains
    /// all order parameters that are signed for submitting to GP.
    struct Data {
        IERC20 sellToken;
        IERC20 buyToken;
        address receiver;
        uint256 sellAmount;
        uint256 buyAmount;
        uint32 validTo;
        bytes32 appData;
        uint256 feeAmount;
        bytes32 kind;
        bool partiallyFillable;
        bytes32 sellTokenBalance;
        bytes32 buyTokenBalance;
    }

    /// @dev The order EIP-712 type hash for the [`GPv2Order.Data`] struct.
    ///
    /// This value is pre-computed from the following expression:
    /// ```
    /// keccak256(
    ///     "Order(" +
    ///         "address sellToken," +
    ///         "address buyToken," +
    ///         "address receiver," +
    ///         "uint256 sellAmount," +
    ///         "uint256 buyAmount," +
    ///         "uint32 validTo," +
    ///         "bytes32 appData," +
    ///         "uint256 feeAmount," +
    ///         "string kind," +
    ///         "bool partiallyFillable," +
    ///         "string sellTokenBalance," +
    ///         "string buyTokenBalance" +
    ///     ")"
    /// )
    /// ```
    bytes32 internal constant TYPE_HASH =
        hex"d5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e489";

    /// @dev The marker value for a sell order for computing the order struct
    /// hash. This allows the EIP-712 compatible wallets to display a
    /// descriptive string for the order kind (instead of 0 or 1).
    ///
    /// This value is pre-computed from the following expression:
    /// ```
    /// keccak256("sell")
    /// ```
    bytes32 internal constant KIND_SELL =
        hex"f3b277728b3fee749481eb3e0b3b48980dbbab78658fc419025cb16eee346775";

    /// @dev The OrderKind marker value for a buy order for computing the order
    /// struct hash.
    ///
    /// This value is pre-computed from the following expression:
    /// ```
    /// keccak256("buy")
    /// ```
    bytes32 internal constant KIND_BUY =
        hex"6ed88e868af0a1983e3886d5f3e95a2fafbd6c3450bc229e27342283dc429ccc";

    /// @dev The TokenBalance marker value for using direct ERC20 balances for
    /// computing the order struct hash.
    ///
    /// This value is pre-computed from the following expression:
    /// ```
    /// keccak256("erc20")
    /// ```
    bytes32 internal constant BALANCE_ERC20 =
        hex"5a28e9363bb942b639270062aa6bb295f434bcdfc42c97267bf003f272060dc9";

    /// @dev The TokenBalance marker value for using Balancer Vault external
    /// balances (in order to re-use Vault ERC20 approvals) for computing the
    /// order struct hash.
    ///
    /// This value is pre-computed from the following expression:
    /// ```
    /// keccak256("external")
    /// ```
    bytes32 internal constant BALANCE_EXTERNAL =
        hex"abee3b73373acd583a130924aad6dc38cfdc44ba0555ba94ce2ff63980ea0632";

    /// @dev The TokenBalance marker value for using Balancer Vault internal
    /// balances for computing the order struct hash.
    ///
    /// This value is pre-computed from the following expression:
    /// ```
    /// keccak256("internal")
    /// ```
    bytes32 internal constant BALANCE_INTERNAL =
        hex"4ac99ace14ee0a5ef932dc609df0943ab7ac16b7583634612f8dc35a4289a6ce";

    /// @dev Marker address used to indicate that the receiver of the trade
    /// proceeds should the owner of the order.
    ///
    /// This is chosen to be `address(0)` for gas efficiency as it is expected
    /// to be the most common case.
    address internal constant RECEIVER_SAME_AS_OWNER = address(0);

    /// @dev The byte length of an order unique identifier.
    uint256 internal constant UID_LENGTH = 56;

    /// @dev Returns the actual receiver for an order. This function checks
    /// whether or not the [`receiver`] field uses the marker value to indicate
    /// it is the same as the order owner.
    ///
    /// @return receiver The actual receiver of trade proceeds.
    function actualReceiver(
        Data memory order,
        address owner
    ) internal pure returns (address receiver) {
        if (order.receiver == RECEIVER_SAME_AS_OWNER) {
            receiver = owner;
        } else {
            receiver = order.receiver;
        }
    }

    /// @dev Return the EIP-712 signing hash for the specified order.
    ///
    /// @param order The order to compute the EIP-712 signing hash for.
    /// @param domainSeparator The EIP-712 domain separator to use.
    /// @return orderDigest The 32 byte EIP-712 struct hash.
    function hash(
        Data memory order,
        bytes32 domainSeparator
    ) internal pure returns (bytes32 orderDigest) {
        bytes32 structHash;

        // NOTE: Compute the EIP-712 order struct hash in place. As suggested
        // in the EIP proposal, noting that the order struct has 12 fields, and
        // prefixing the type hash `(1 + 12) * 32 = 416` bytes to hash.
        // <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#rationale-for-encodedata>
        // solhint-disable-next-line no-inline-assembly
        assembly {
            let dataStart := sub(order, 32)
            let temp := mload(dataStart)
            mstore(dataStart, TYPE_HASH)
            structHash := keccak256(dataStart, 416)
            mstore(dataStart, temp)
        }

        // NOTE: Now that we have the struct hash, compute the EIP-712 signing
        // hash using scratch memory past the free memory pointer. The signing
        // hash is computed from `"\x19\x01" || domainSeparator || structHash`.
        // <https://docs.soliditylang.org/en/v0.7.6/internals/layout_in_memory.html#layout-in-memory>
        // <https://github.com/ethereum/EIPs/blob/master/EIPS/eip-712.md#specification>
        // solhint-disable-next-line no-inline-assembly
        assembly {
            let freeMemoryPointer := mload(0x40)
            mstore(freeMemoryPointer, "\x19\x01")
            mstore(add(freeMemoryPointer, 2), domainSeparator)
            mstore(add(freeMemoryPointer, 34), structHash)
            orderDigest := keccak256(freeMemoryPointer, 66)
        }
    }

    /// @dev Packs order UID parameters into the specified memory location. The
    /// result is equivalent to `abi.encodePacked(...)` with the difference that
    /// it allows re-using the memory for packing the order UID.
    ///
    /// This function reverts if the order UID buffer is not the correct size.
    ///
    /// @param orderUid The buffer pack the order UID parameters into.
    /// @param orderDigest The EIP-712 struct digest derived from the order
    /// parameters.
    /// @param owner The address of the user who owns this order.
    /// @param validTo The epoch time at which the order will stop being valid.
    function packOrderUidParams(
        bytes memory orderUid,
        bytes32 orderDigest,
        address owner,
        uint32 validTo
    ) internal pure {
        require(orderUid.length == UID_LENGTH, "GPv2: uid buffer overflow");

        // NOTE: Write the order UID to the allocated memory buffer. The order
        // parameters are written to memory in **reverse order** as memory
        // operations write 32-bytes at a time and we want to use a packed
        // encoding. This means, for example, that after writing the value of
        // `owner` to bytes `20:52`, writing the `orderDigest` to bytes `0:32`
        // will **overwrite** bytes `20:32`. This is desirable as addresses are
        // only 20 bytes and `20:32` should be `0`s:
        //
        //        |           1111111111222222222233333333334444444444555555
        //   byte | 01234567890123456789012345678901234567890123456789012345
        // -------+---------------------------------------------------------
        //  field | [.........orderDigest..........][......owner.......][vT]
        // -------+---------------------------------------------------------
        // mstore |                         [000000000000000000000000000.vT]
        //        |                     [00000000000.......owner.......]
        //        | [.........orderDigest..........]
        //
        // Additionally, since Solidity `bytes memory` are length prefixed,
        // 32 needs to be added to all the offsets.
        //
        // solhint-disable-next-line no-inline-assembly
        assembly {
            mstore(add(orderUid, 56), validTo)
            mstore(add(orderUid, 52), owner)
            mstore(add(orderUid, 32), orderDigest)
        }
    }

    /// @dev Extracts specific order information from the standardized unique
    /// order id of the protocol.
    ///
    /// @param orderUid The unique identifier used to represent an order in
    /// the protocol. This uid is the packed concatenation of the order digest,
    /// the validTo order parameter and the address of the user who created the
    /// order. It is used by the user to interface with the contract directly,
    /// and not by calls that are triggered by the solvers.
    /// @return orderDigest The EIP-712 signing digest derived from the order
    /// parameters.
    /// @return owner The address of the user who owns this order.
    /// @return validTo The epoch time at which the order will stop being valid.
    function extractOrderUidParams(
        bytes calldata orderUid
    )
        internal
        pure
        returns (bytes32 orderDigest, address owner, uint32 validTo)
    {
        require(orderUid.length == UID_LENGTH, "GPv2: invalid uid");

        // Use assembly to efficiently decode packed calldata.
        // solhint-disable-next-line no-inline-assembly
        assembly {
            orderDigest := calldataload(orderUid.offset)
            owner := shr(96, calldataload(add(orderUid.offset, 32)))
            validTo := shr(224, calldataload(add(orderUid.offset, 52)))
        }
    }
}

File 6 of 17 : GPv2Signing.sol
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity >=0.7.6 <0.9.0;

import "../interfaces/GPv2EIP1271.sol";
import "../libraries/GPv2Order.sol";
import "../libraries/GPv2Trade.sol";

/// @title Gnosis Protocol v2 Signing Library.
/// @author Gnosis Developers
abstract contract GPv2Signing {
    using GPv2Order for GPv2Order.Data;
    using GPv2Order for bytes;

    /// @dev Recovered trade data containing the extracted order and the
    /// recovered owner address.
    struct RecoveredOrder {
        GPv2Order.Data data;
        bytes uid;
        address owner;
        address receiver;
    }

    /// @dev Signing scheme used for recovery.
    enum Scheme {
        Eip712,
        EthSign,
        Eip1271,
        PreSign
    }

    /// @dev The EIP-712 domain type hash used for computing the domain
    /// separator.
    bytes32 private constant DOMAIN_TYPE_HASH =
        keccak256(
            "EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"
        );

    /// @dev The EIP-712 domain name used for computing the domain separator.
    bytes32 private constant DOMAIN_NAME = keccak256("Gnosis Protocol");

    /// @dev The EIP-712 domain version used for computing the domain separator.
    bytes32 private constant DOMAIN_VERSION = keccak256("v2");

    /// @dev Marker value indicating an order is pre-signed.
    uint256 private constant PRE_SIGNED =
        uint256(keccak256("GPv2Signing.Scheme.PreSign"));

    /// @dev The domain separator used for signing orders that gets mixed in
    /// making signatures for different domains incompatible. This domain
    /// separator is computed following the EIP-712 standard and has replay
    /// protection mixed in so that signed orders are only valid for specific
    /// GPv2 contracts.
    bytes32 public immutable domainSeparator;

    /// @dev Storage indicating whether or not an order has been signed by a
    /// particular address.
    mapping(bytes => uint256) public preSignature;

    /// @dev Event that is emitted when an account either pre-signs an order or
    /// revokes an existing pre-signature.
    event PreSignature(address indexed owner, bytes orderUid, bool signed);

    constructor() {
        // NOTE: Currently, the only way to get the chain ID in solidity is
        // using assembly.
        uint256 chainId;
        // solhint-disable-next-line no-inline-assembly
        assembly {
            chainId := chainid()
        }

        domainSeparator = keccak256(
            abi.encode(
                DOMAIN_TYPE_HASH,
                DOMAIN_NAME,
                DOMAIN_VERSION,
                chainId,
                address(this)
            )
        );
    }

    /// @dev Sets a presignature for the specified order UID.
    ///
    /// @param orderUid The unique identifier of the order to pre-sign.
    /// @param signed True to set the order as tradable with pre-sign, false to
    /// false to unset it.
    function setPreSignature(bytes calldata orderUid, bool signed) external {
        (, address owner, ) = orderUid.extractOrderUidParams();
        require(owner == msg.sender, "GPv2: cannot presign order");
        if (signed) {
            preSignature[orderUid] = PRE_SIGNED;
        } else {
            preSignature[orderUid] = 0;
        }
        emit PreSignature(owner, orderUid, signed);
    }

    /// @dev Returns an empty recovered order with a pre-allocated buffer for
    /// packing the unique identifier.
    ///
    /// @return recoveredOrder The empty recovered order data.
    function allocateRecoveredOrder()
        internal
        pure
        returns (RecoveredOrder memory recoveredOrder)
    {
        recoveredOrder.uid = new bytes(GPv2Order.UID_LENGTH);
    }

    /// @dev Extracts order data and recovers the signer from the specified
    /// trade.
    ///
    /// @param recoveredOrder Memory location used for writing the recovered order data.
    /// @param tokens The list of tokens included in the settlement. The token
    /// indices in the trade parameters map to tokens in this array.
    /// @param trade The trade data to recover the order data from.
    function recoverOrderFromTrade(
        RecoveredOrder memory recoveredOrder,
        IERC20[] calldata tokens,
        GPv2Trade.Data calldata trade
    ) internal view {
        GPv2Order.Data memory order = recoveredOrder.data;

        Scheme signingScheme = GPv2Trade.extractOrder(trade, tokens, order);
        (bytes32 orderDigest, address owner) = recoverOrderSigner(
            order,
            signingScheme,
            trade.signature
        );

        recoveredOrder.uid.packOrderUidParams(
            orderDigest,
            owner,
            order.validTo
        );
        recoveredOrder.owner = owner;
        recoveredOrder.receiver = order.actualReceiver(owner);
    }

    /// @dev The length of any signature from an externally owned account.
    uint256 private constant ECDSA_SIGNATURE_LENGTH = 65;

    /// @dev Recovers an order's signer from the specified order and signature.
    ///
    /// @param order The order to recover a signature for.
    /// @param signingScheme The signing scheme.
    /// @param signature The signature bytes.
    /// @return orderDigest The computed order hash.
    /// @return owner The recovered address from the specified signature.
    function recoverOrderSigner(
        GPv2Order.Data memory order,
        Scheme signingScheme,
        bytes calldata signature
    ) internal view returns (bytes32 orderDigest, address owner) {
        orderDigest = order.hash(domainSeparator);
        if (signingScheme == Scheme.Eip712) {
            owner = recoverEip712Signer(orderDigest, signature);
        } else if (signingScheme == Scheme.EthSign) {
            owner = recoverEthsignSigner(orderDigest, signature);
        } else if (signingScheme == Scheme.Eip1271) {
            owner = recoverEip1271Signer(orderDigest, signature);
        } else {
            // signingScheme == Scheme.PreSign
            owner = recoverPreSigner(orderDigest, signature, order.validTo);
        }
    }

    /// @dev Perform an ECDSA recover for the specified message and calldata
    /// signature.
    ///
    /// The signature is encoded by tighyly packing the following struct:
    /// ```
    /// struct EncodedSignature {
    ///     bytes32 r;
    ///     bytes32 s;
    ///     uint8 v;
    /// }
    /// ```
    ///
    /// @param message The signed message.
    /// @param encodedSignature The encoded signature.
    function ecdsaRecover(
        bytes32 message,
        bytes calldata encodedSignature
    ) internal pure returns (address signer) {
        require(
            encodedSignature.length == ECDSA_SIGNATURE_LENGTH,
            "GPv2: malformed ecdsa signature"
        );

        bytes32 r;
        bytes32 s;
        uint8 v;

        // NOTE: Use assembly to efficiently decode signature data.
        // solhint-disable-next-line no-inline-assembly
        assembly {
            // r = uint256(encodedSignature[0:32])
            r := calldataload(encodedSignature.offset)
            // s = uint256(encodedSignature[32:64])
            s := calldataload(add(encodedSignature.offset, 32))
            // v = uint8(encodedSignature[64])
            v := shr(248, calldataload(add(encodedSignature.offset, 64)))
        }

        signer = ecrecover(message, v, r, s);
        require(signer != address(0), "GPv2: invalid ecdsa signature");
    }

    /// @dev Decodes signature bytes originating from an EIP-712-encoded
    /// signature.
    ///
    /// EIP-712 signs typed data. The specifications are described in the
    /// related EIP (<https://eips.ethereum.org/EIPS/eip-712>).
    ///
    /// EIP-712 signatures are encoded as standard ECDSA signatures as described
    /// in the corresponding decoding function [`ecdsaRecover`].
    ///
    /// @param orderDigest The EIP-712 signing digest derived from the order
    /// parameters.
    /// @param encodedSignature Calldata pointing to tightly packed signature
    /// bytes.
    /// @return owner The address of the signer.
    function recoverEip712Signer(
        bytes32 orderDigest,
        bytes calldata encodedSignature
    ) internal pure returns (address owner) {
        owner = ecdsaRecover(orderDigest, encodedSignature);
    }

    /// @dev Decodes signature bytes originating from the output of the eth_sign
    /// RPC call.
    ///
    /// The specifications are described in the Ethereum documentation
    /// (<https://eth.wiki/json-rpc/API#eth_sign>).
    ///
    /// eth_sign signatures are encoded as standard ECDSA signatures as
    /// described in the corresponding decoding function
    /// [`ecdsaRecover`].
    ///
    /// @param orderDigest The EIP-712 signing digest derived from the order
    /// parameters.
    /// @param encodedSignature Calldata pointing to tightly packed signature
    /// bytes.
    /// @return owner The address of the signer.
    function recoverEthsignSigner(
        bytes32 orderDigest,
        bytes calldata encodedSignature
    ) internal pure returns (address owner) {
        // The signed message is encoded as:
        // `"\x19Ethereum Signed Message:\n" || length || data`, where
        // the length is a constant (32 bytes) and the data is defined as:
        // `orderDigest`.
        bytes32 ethsignDigest = keccak256(
            abi.encodePacked("\x19Ethereum Signed Message:\n32", orderDigest)
        );

        owner = ecdsaRecover(ethsignDigest, encodedSignature);
    }

    /// @dev Verifies the input calldata as an EIP-1271 contract signature and
    /// returns the address of the signer.
    ///
    /// The encoded signature tightly packs the following struct:
    ///
    /// ```
    /// struct EncodedEip1271Signature {
    ///     address owner;
    ///     bytes signature;
    /// }
    /// ```
    ///
    /// This function enforces that the encoded data stores enough bytes to
    /// cover the full length of the decoded signature.
    ///
    /// @param encodedSignature The encoded EIP-1271 signature.
    /// @param orderDigest The EIP-712 signing digest derived from the order
    /// parameters.
    /// @return owner The address of the signer.
    function recoverEip1271Signer(
        bytes32 orderDigest,
        bytes calldata encodedSignature
    ) internal view returns (address owner) {
        // NOTE: Use assembly to read the verifier address from the encoded
        // signature bytes.
        // solhint-disable-next-line no-inline-assembly
        assembly {
            // owner = address(encodedSignature[0:20])
            owner := shr(96, calldataload(encodedSignature.offset))
        }

        // NOTE: Configure prettier to ignore the following line as it causes
        // a panic in the Solidity plugin.
        // prettier-ignore
        bytes calldata signature = encodedSignature[20:];

        require(
            EIP1271Verifier(owner).isValidSignature(orderDigest, signature) ==
                GPv2EIP1271.MAGICVALUE,
            "GPv2: invalid eip1271 signature"
        );
    }

    /// @dev Verifies the order has been pre-signed. The signature is the
    /// address of the signer of the order.
    ///
    /// @param orderDigest The EIP-712 signing digest derived from the order
    /// parameters.
    /// @param encodedSignature The pre-sign signature reprenting the order UID.
    /// @param validTo The order expiry timestamp.
    /// @return owner The address of the signer.
    function recoverPreSigner(
        bytes32 orderDigest,
        bytes calldata encodedSignature,
        uint32 validTo
    ) internal view returns (address owner) {
        require(encodedSignature.length == 20, "GPv2: malformed presignature");
        // NOTE: Use assembly to read the owner address from the encoded
        // signature bytes.
        // solhint-disable-next-line no-inline-assembly
        assembly {
            // owner = address(encodedSignature[0:20])
            owner := shr(96, calldataload(encodedSignature.offset))
        }

        bytes memory orderUid = new bytes(GPv2Order.UID_LENGTH);
        orderUid.packOrderUidParams(orderDigest, owner, validTo);

        require(
            preSignature[orderUid] == PRE_SIGNED,
            "GPv2: order not presigned"
        );
    }
}

File 7 of 17 : IAvatar.sol
// SPDX-License-Identifier: LGPL-3.0-only

/// @title Zodiac Avatar - A contract that manages modules that can execute transactions via this contract.
pragma solidity >=0.7.0 <0.9.0;

import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";

interface IAvatar {
  event EnabledModule(address module);
  event DisabledModule(address module);
  event ExecutionFromModuleSuccess(address indexed module);
  event ExecutionFromModuleFailure(address indexed module);

  /// @dev Enables a module on the avatar.
  /// @notice Can only be called by the avatar.
  /// @notice Modules should be stored as a linked list.
  /// @notice Must emit EnabledModule(address module) if successful.
  /// @param module Module to be enabled.
  function enableModule(address module) external;

  /// @dev Disables a module on the avatar.
  /// @notice Can only be called by the avatar.
  /// @notice Must emit DisabledModule(address module) if successful.
  /// @param prevModule Address that pointed to the module to be removed in the linked list
  /// @param module Module to be removed.
  function disableModule(address prevModule, address module) external;

  /// @dev Allows a Module to execute a transaction.
  /// @notice Can only be called by an enabled module.
  /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.
  /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.
  /// @param to Destination address of module transaction.
  /// @param value Ether value of module transaction.
  /// @param data Data payload of module transaction.
  /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.
  function execTransactionFromModule(
    address to,
    uint256 value,
    bytes memory data,
    Enum.Operation operation
  ) external returns (bool success);

  /// @dev Allows a Module to execute a transaction and return data
  /// @notice Can only be called by an enabled module.
  /// @notice Must emit ExecutionFromModuleSuccess(address module) if successful.
  /// @notice Must emit ExecutionFromModuleFailure(address module) if unsuccessful.
  /// @param to Destination address of module transaction.
  /// @param value Ether value of module transaction.
  /// @param data Data payload of module transaction.
  /// @param operation Operation type of module transaction: 0 == call, 1 == delegate call.
  function execTransactionFromModuleReturnData(
    address to,
    uint256 value,
    bytes memory data,
    Enum.Operation operation
  ) external returns (bool success, bytes memory returnData);

  /// @dev Returns if an module is enabled
  /// @return True if the module is enabled
  function isModuleEnabled(address module) external view returns (bool);

  /// @dev Returns array of modules.
  /// @param start Start of the page.
  /// @param pageSize Maximum number of modules that should be returned.
  /// @return array Array of modules.
  /// @return next Start of the next page.
  function getModulesPaginated(
    address start,
    uint256 pageSize
  ) external view returns (address[] memory array, address next);
}

File 8 of 17 : IGuard.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";

interface IGuard {
  function checkTransaction(
    address to,
    uint256 value,
    bytes memory data,
    Enum.Operation operation,
    uint256 safeTxGas,
    uint256 baseGas,
    uint256 gasPrice,
    address gasToken,
    address payable refundReceiver,
    bytes memory signatures,
    address msgSender
  ) external;

  function checkAfterExecution(bytes32 txHash, bool success) external;
}

File 9 of 17 : FactoryFriendly.sol
// SPDX-License-Identifier: LGPL-3.0-only

/// @title Zodiac FactoryFriendly - A contract that allows other contracts to be initializable and pass bytes as arguments to define contract state
pragma solidity >=0.7.0 <0.9.0;

import {OwnableUpgradeable} from "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";

abstract contract FactoryFriendly is OwnableUpgradeable {
  function setUp(bytes memory initializeParams) public virtual;
}

File 10 of 17 : OwnableUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;

import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";

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

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;

    function _getOwnableStorage() private pure returns (OwnableStorage storage $) {
        assembly {
            $.slot := OwnableStorageLocation
        }
    }

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

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

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    function __Ownable_init(address initialOwner) internal onlyInitializing {
        __Ownable_init_unchained(initialOwner);
    }

    function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

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

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

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

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

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

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

File 11 of 17 : BaseGuard.sol
// SPDX-License-Identifier: LGPL-3.0-only
pragma solidity >=0.7.0 <0.9.0;

import {Enum} from "@gnosis.pm/safe-contracts/contracts/common/Enum.sol";
import {IERC165} from "@openzeppelin/contracts/utils/introspection/IERC165.sol";

import {IGuard} from "../interfaces/IGuard.sol";

abstract contract BaseGuard is IERC165 {
  function supportsInterface(
    bytes4 interfaceId
  ) external pure override returns (bool) {
    return
      interfaceId == type(IGuard).interfaceId || // 0xe6d7a83a
      interfaceId == type(IERC165).interfaceId; // 0x01ffc9a7
  }

  /// @dev Module transactions only use the first four parameters: to, value, data, and operation.
  /// Module.sol hardcodes the remaining parameters as 0 since they are not used for module transactions.
  /// @notice This interface is used to maintain compatibilty with Gnosis Safe transaction guards.
  function checkTransaction(
    address to,
    uint256 value,
    bytes memory data,
    Enum.Operation operation,
    uint256 safeTxGas,
    uint256 baseGas,
    uint256 gasPrice,
    address gasToken,
    address payable refundReceiver,
    bytes memory signatures,
    address msgSender
  ) external virtual;

  function checkAfterExecution(bytes32 txHash, bool success) external virtual;
}

File 12 of 17 : IERC20.sol
// SPDX-License-Identifier: MIT

// Vendored from OpenZeppelin contracts with minor modifications:
// - Modified Solidity version
// - Formatted code
// - Added `name`, `symbol` and `decimals` function declarations
// <https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.4.0/contracts/token/ERC20/IERC20.sol>

pragma solidity >=0.7.6 <0.9.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the number of decimals the token uses.
     */
    function decimals() external view returns (uint8);

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

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

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

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

    /**
     * @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
    );
}

File 13 of 17 : GPv2EIP1271.sol
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity >=0.7.6 <0.9.0;

library GPv2EIP1271 {
    /// @dev Value returned by a call to `isValidSignature` if the signature
    /// was verified successfully. The value is defined in EIP-1271 as:
    /// bytes4(keccak256("isValidSignature(bytes32,bytes)"))
    bytes4 internal constant MAGICVALUE = 0x1626ba7e;
}

/// @title EIP1271 Interface
/// @dev Standardized interface for an implementation of smart contract
/// signatures as described in EIP-1271. The code that follows is identical to
/// the code in the standard with the exception of formatting and syntax
/// changes to adapt the code to our Solidity version.
interface EIP1271Verifier {
    /// @dev Should return whether the signature provided is valid for the
    /// provided data
    /// @param _hash      Hash of the data to be signed
    /// @param _signature Signature byte array associated with _data
    ///
    /// MUST return the bytes4 magic value 0x1626ba7e when function passes.
    /// MUST NOT modify state (using STATICCALL for solc < 0.5, view modifier for
    /// solc > 0.5)
    /// MUST allow external calls
    ///
    function isValidSignature(
        bytes32 _hash,
        bytes memory _signature
    ) external view returns (bytes4 magicValue);
}

File 14 of 17 : GPv2Trade.sol
// SPDX-License-Identifier: LGPL-3.0-or-later
pragma solidity >=0.7.6 <0.9.0;

import "../interfaces/IERC20.sol";
import "../mixins/GPv2Signing.sol";
import "./GPv2Order.sol";

/// @title Gnosis Protocol v2 Trade Library.
/// @author Gnosis Developers
library GPv2Trade {
    using GPv2Order for GPv2Order.Data;
    using GPv2Order for bytes;

    /// @dev A struct representing a trade to be executed as part a batch
    /// settlement.
    struct Data {
        uint256 sellTokenIndex;
        uint256 buyTokenIndex;
        address receiver;
        uint256 sellAmount;
        uint256 buyAmount;
        uint32 validTo;
        bytes32 appData;
        uint256 feeAmount;
        uint256 flags;
        uint256 executedAmount;
        bytes signature;
    }

    /// @dev Extracts the order data and signing scheme for the specified trade.
    ///
    /// @param trade The trade.
    /// @param tokens The list of tokens included in the settlement. The token
    /// indices in the trade parameters map to tokens in this array.
    /// @param order The memory location to extract the order data to.
    function extractOrder(
        Data calldata trade,
        IERC20[] calldata tokens,
        GPv2Order.Data memory order
    ) internal pure returns (GPv2Signing.Scheme signingScheme) {
        order.sellToken = tokens[trade.sellTokenIndex];
        order.buyToken = tokens[trade.buyTokenIndex];
        order.receiver = trade.receiver;
        order.sellAmount = trade.sellAmount;
        order.buyAmount = trade.buyAmount;
        order.validTo = trade.validTo;
        order.appData = trade.appData;
        order.feeAmount = trade.feeAmount;
        (
            order.kind,
            order.partiallyFillable,
            order.sellTokenBalance,
            order.buyTokenBalance,
            signingScheme
        ) = extractFlags(trade.flags);
    }

    /// @dev Decodes trade flags.
    ///
    /// Trade flags are used to tightly encode information on how to decode
    /// an order. Examples that directly affect the structure of an order are
    /// the kind of order (either a sell or a buy order) as well as whether the
    /// order is partially fillable or if it is a "fill-or-kill" order. It also
    /// encodes the signature scheme used to validate the order. As the most
    /// likely values are fill-or-kill sell orders by an externally owned
    /// account, the flags are chosen such that `0x00` represents this kind of
    /// order. The flags byte uses the following format:
    ///
    /// ```
    /// bit | 31 ...   | 6 | 5 | 4 | 3 | 2 | 1 | 0 |
    /// ----+----------+-------+---+-------+---+---+
    ///     | reserved | *   * | * | *   * | * | * |
    ///                  |   |   |   |   |   |   |
    ///                  |   |   |   |   |   |   +---- order kind bit, 0 for a sell order
    ///                  |   |   |   |   |   |         and 1 for a buy order
    ///                  |   |   |   |   |   |
    ///                  |   |   |   |   |   +-------- order fill bit, 0 for fill-or-kill
    ///                  |   |   |   |   |             and 1 for a partially fillable order
    ///                  |   |   |   |   |
    ///                  |   |   |   +---+------------ use internal sell token balance bit:
    ///                  |   |   |                     0x: ERC20 token balance
    ///                  |   |   |                     10: external Balancer Vault balance
    ///                  |   |   |                     11: internal Balancer Vault balance
    ///                  |   |   |
    ///                  |   |   +-------------------- use buy token balance bit
    ///                  |   |                         0: ERC20 token balance
    ///                  |   |                         1: internal Balancer Vault balance
    ///                  |   |
    ///                  +---+------------------------ signature scheme bits:
    ///                                                00: EIP-712
    ///                                                01: eth_sign
    ///                                                10: EIP-1271
    ///                                                11: pre_sign
    /// ```
    function extractFlags(
        uint256 flags
    )
        internal
        pure
        returns (
            bytes32 kind,
            bool partiallyFillable,
            bytes32 sellTokenBalance,
            bytes32 buyTokenBalance,
            GPv2Signing.Scheme signingScheme
        )
    {
        if (flags & 0x01 == 0) {
            kind = GPv2Order.KIND_SELL;
        } else {
            kind = GPv2Order.KIND_BUY;
        }
        partiallyFillable = flags & 0x02 != 0;
        if (flags & 0x08 == 0) {
            sellTokenBalance = GPv2Order.BALANCE_ERC20;
        } else if (flags & 0x04 == 0) {
            sellTokenBalance = GPv2Order.BALANCE_EXTERNAL;
        } else {
            sellTokenBalance = GPv2Order.BALANCE_INTERNAL;
        }
        if (flags & 0x10 == 0) {
            buyTokenBalance = GPv2Order.BALANCE_ERC20;
        } else {
            buyTokenBalance = GPv2Order.BALANCE_INTERNAL;
        }

        // NOTE: Take advantage of the fact that Solidity will revert if the
        // following expression does not produce a valid enum value. This means
        // we check here that the leading reserved bits must be 0.
        signingScheme = GPv2Signing.Scheme(flags >> 5);
    }
}

File 15 of 17 : ContextUpgradeable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";

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

    function __Context_init_unchained() internal onlyInitializing {
    }
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

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

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

File 16 of 17 : Initializable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)

pragma solidity ^0.8.20;

/**
 * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
 * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
 * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
 * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
 *
 * The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
 * reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
 * case an upgrade adds a module that needs to be initialized.
 *
 * For example:
 *
 * [.hljs-theme-light.nopadding]
 * ```solidity
 * contract MyToken is ERC20Upgradeable {
 *     function initialize() initializer public {
 *         __ERC20_init("MyToken", "MTK");
 *     }
 * }
 *
 * contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
 *     function initializeV2() reinitializer(2) public {
 *         __ERC20Permit_init("MyToken");
 *     }
 * }
 * ```
 *
 * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
 * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
 *
 * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
 * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
 *
 * [CAUTION]
 * ====
 * Avoid leaving a contract uninitialized.
 *
 * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
 * contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
 * the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
 *
 * [.hljs-theme-light.nopadding]
 * ```
 * /// @custom:oz-upgrades-unsafe-allow constructor
 * constructor() {
 *     _disableInitializers();
 * }
 * ```
 * ====
 */
abstract contract Initializable {
    /**
     * @dev Storage of the initializable contract.
     *
     * It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
     * when using with upgradeable contracts.
     *
     * @custom:storage-location erc7201:openzeppelin.storage.Initializable
     */
    struct InitializableStorage {
        /**
         * @dev Indicates that the contract has been initialized.
         */
        uint64 _initialized;
        /**
         * @dev Indicates that the contract is in the process of being initialized.
         */
        bool _initializing;
    }

    // keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
    bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;

    /**
     * @dev The contract is already initialized.
     */
    error InvalidInitialization();

    /**
     * @dev The contract is not initializing.
     */
    error NotInitializing();

    /**
     * @dev Triggered when the contract has been initialized or reinitialized.
     */
    event Initialized(uint64 version);

    /**
     * @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
     * `onlyInitializing` functions can be used to initialize parent contracts.
     *
     * Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
     * number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
     * production.
     *
     * Emits an {Initialized} event.
     */
    modifier initializer() {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        // Cache values to avoid duplicated sloads
        bool isTopLevelCall = !$._initializing;
        uint64 initialized = $._initialized;

        // Allowed calls:
        // - initialSetup: the contract is not in the initializing state and no previous version was
        //                 initialized
        // - construction: the contract is initialized at version 1 (no reininitialization) and the
        //                 current contract is just being deployed
        bool initialSetup = initialized == 0 && isTopLevelCall;
        bool construction = initialized == 1 && address(this).code.length == 0;

        if (!initialSetup && !construction) {
            revert InvalidInitialization();
        }
        $._initialized = 1;
        if (isTopLevelCall) {
            $._initializing = true;
        }
        _;
        if (isTopLevelCall) {
            $._initializing = false;
            emit Initialized(1);
        }
    }

    /**
     * @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
     * contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
     * used to initialize parent contracts.
     *
     * A reinitializer may be used after the original initialization step. This is essential to configure modules that
     * are added through upgrades and that require initialization.
     *
     * When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
     * cannot be nested. If one is invoked in the context of another, execution will revert.
     *
     * Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
     * a contract, executing them in the right order is up to the developer or operator.
     *
     * WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
     *
     * Emits an {Initialized} event.
     */
    modifier reinitializer(uint64 version) {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing || $._initialized >= version) {
            revert InvalidInitialization();
        }
        $._initialized = version;
        $._initializing = true;
        _;
        $._initializing = false;
        emit Initialized(version);
    }

    /**
     * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
     * {initializer} and {reinitializer} modifiers, directly or indirectly.
     */
    modifier onlyInitializing() {
        _checkInitializing();
        _;
    }

    /**
     * @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
     */
    function _checkInitializing() internal view virtual {
        if (!_isInitializing()) {
            revert NotInitializing();
        }
    }

    /**
     * @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
     * Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
     * to any version. It is recommended to use this to lock implementation contracts that are designed to be called
     * through proxies.
     *
     * Emits an {Initialized} event the first time it is successfully executed.
     */
    function _disableInitializers() internal virtual {
        // solhint-disable-next-line var-name-mixedcase
        InitializableStorage storage $ = _getInitializableStorage();

        if ($._initializing) {
            revert InvalidInitialization();
        }
        if ($._initialized != type(uint64).max) {
            $._initialized = type(uint64).max;
            emit Initialized(type(uint64).max);
        }
    }

    /**
     * @dev Returns the highest version that has been initialized. See {reinitializer}.
     */
    function _getInitializedVersion() internal view returns (uint64) {
        return _getInitializableStorage()._initialized;
    }

    /**
     * @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
     */
    function _isInitializing() internal view returns (bool) {
        return _getInitializableStorage()._initializing;
    }

    /**
     * @dev Returns a pointer to the storage namespace.
     */
    // solhint-disable-next-line var-name-mixedcase
    function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
        assembly {
            $.slot := INITIALIZABLE_STORAGE
        }
    }
}

File 17 of 17 : IERC165.sol
// 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);
}

Settings
{
  "remappings": [
    "forge-std/=node_modules/forge-std/src/",
    "@openzeppelin/contracts-upgradeable/=node_modules/@openzeppelin/contracts-upgradeable/",
    "@openzeppelin/contracts/=node_modules/@openzeppelin/contracts/",
    "@gnosis.pm/safe-contracts/=node_modules/@gnosis.pm/safe-contracts/",
    "@gnosis-guild/zodiac/=node_modules/@gnosis-guild/zodiac/",
    "solady/=node_modules/solady/",
    "cowprotocol/=node_modules/cowprotocol/"
  ],
  "optimizer": {
    "enabled": true,
    "runs": 10000
  },
  "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

API
[{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_avatar","type":"address"},{"internalType":"address","name":"_target","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CannotExec","type":"error"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"InvalidOrderUID","type":"error"},{"inputs":[],"name":"InvalidTrader","type":"error"},{"inputs":[{"internalType":"address","name":"guard_","type":"address"}],"name":"NotIERC165Compliant","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousAvatar","type":"address"},{"indexed":true,"internalType":"address","name":"newAvatar","type":"address"}],"name":"AvatarSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"guard","type":"address"}],"name":"ChangedGuard","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes","name":"orderUid","type":"bytes"},{"indexed":true,"internalType":"bool","name":"signed","type":"bool"}],"name":"SetOrder","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTarget","type":"address"},{"indexed":true,"internalType":"address","name":"newTarget","type":"address"}],"name":"TargetSet","type":"event"},{"inputs":[],"name":"GPV2_SETTLEMENT_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"avatar","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuard","outputs":[{"internalType":"address","name":"_guard","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guard","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"trader","type":"address"},{"internalType":"bool","name":"allowed","type":"bool"}],"name":"setAllowedTraders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_avatar","type":"address"}],"name":"setAvatar","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_guard","type":"address"}],"name":"setGuard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"orderUid","type":"bytes"},{"components":[{"internalType":"contract IERC20","name":"sellToken","type":"address"},{"internalType":"contract IERC20","name":"buyToken","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"sellAmount","type":"uint256"},{"internalType":"uint256","name":"buyAmount","type":"uint256"},{"internalType":"uint32","name":"validTo","type":"uint32"},{"internalType":"bytes32","name":"appData","type":"bytes32"},{"internalType":"uint256","name":"feeAmount","type":"uint256"},{"internalType":"bytes32","name":"kind","type":"bytes32"},{"internalType":"bool","name":"partiallyFillable","type":"bool"},{"internalType":"bytes32","name":"sellTokenBalance","type":"bytes32"},{"internalType":"bytes32","name":"buyTokenBalance","type":"bytes32"}],"internalType":"struct GPv2Order.Data","name":"order","type":"tuple"},{"internalType":"bool","name":"signed","type":"bool"}],"name":"setOrder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_target","type":"address"}],"name":"setTarget","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"initParams","type":"bytes"}],"name":"setUp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"target","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561000f575f5ffd5b5060405161195b38038061195b83398101604081905261002e9161042e565b604080516001600160a01b03858116602083015284811682840152831660608083019190915282518083039091018152608090910190915261006f81610078565b5050505061048f565b5f51602061193b5f395f51905f52805468010000000000000000810460ff1615906001600160401b03165f811580156100ae5750825b90505f826001600160401b031660011480156100c95750303b155b9050811580156100d7575080155b156100f55760405163f92ee8a960e01b815260040160405180910390fd5b84546001600160401b0319166001178555831561012357845460ff60401b1916680100000000000000001785555b5f5f5f8880602001905181019061013a919061042e565b9194509250905061014a3361022d565b61015382610241565b61015c81610298565b739008d19f58aabd9ed0d60971565aa8510560ab416001600160a01b031663f698da256040518163ffffffff1660e01b8152600401602060405180830381865afa1580156101ac573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906101d09190610478565b6004556101dc836102f1565b505050831561022557845460ff60401b19168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b610235610330565b61023e8161036d565b50565b610249610375565b5f80546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f52ae88b092de36f87fb43fe794eb1381023b9c1bce563a871154022c63dce3429190a35050565b6102a0610375565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f90cc2f570a6eb594b1580ea3e41247d2d73a55281889e86bd4ec2fc29c7e62d6905f90a35050565b6102f9610375565b6001600160a01b03811661032757604051631e4fbdf760e01b81525f60048201526024015b60405180910390fd5b61023e816103bd565b5f51602061193b5f395f51905f525468010000000000000000900460ff1661036b57604051631afcd79f60e31b815260040160405180910390fd5b565b6102f9610330565b336103945f51602061191b5f395f51905f52546001600160a01b031690565b6001600160a01b03161461036b5760405163118cdaa760e01b815233600482015260240161031e565b5f51602061191b5f395f51905f5280546001600160a01b031981166001600160a01b03848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b6001600160a01b038116811461023e575f5ffd5b5f5f5f60608486031215610440575f5ffd5b835161044b8161041a565b602085015190935061045c8161041a565b604085015190925061046d8161041a565b809150509250925092565b5f60208284031215610488575f5ffd5b5051919050565b61147f8061049c5f395ff3fe608060405234801561000f575f5ffd5b50600436106100e5575f3560e01c80638da5cb5b11610088578063d4b8399211610063578063d4b839921461021d578063e19a9dd91461023d578063e71d7f6114610250578063f2fde38b14610263575f5ffd5b80638da5cb5b146101af578063a4f9edbf146101ec578063c9106389146101ff575f5ffd5b80635aef7de6116100c35780635aef7de614610155578063715018a614610174578063776d1a011461017c5780637ceab3b11461018f575f5ffd5b8063086cfca8146100e957806333ebc632146100fe57806341513c1d14610111575b5f5ffd5b6100fc6100f7366004610eb5565b610276565b005b6100fc61010c366004610eef565b6102f2565b61012c739008d19f58aabd9ed0d60971565aa8510560ab4181565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b5f5461012c9073ffffffffffffffffffffffffffffffffffffffff1681565b6100fc61039c565b6100fc61018a366004610eb5565b6103af565b60025461012c9073ffffffffffffffffffffffffffffffffffffffff1681565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005473ffffffffffffffffffffffffffffffffffffffff1661012c565b6100fc6101fa366004611027565b61042d565b60025473ffffffffffffffffffffffffffffffffffffffff1661012c565b60015461012c9073ffffffffffffffffffffffffffffffffffffffff1681565b6100fc61024b366004610eb5565b61066a565b6100fc61025e366004611074565b610806565b6100fc610271366004610eb5565b610aae565b61027e610b11565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f52ae88b092de36f87fb43fe794eb1381023b9c1bce563a871154022c63dce3429190a35050565b6102fa610b11565b73ffffffffffffffffffffffffffffffffffffffff8216610347576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff919091165f90815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6103a4610b11565b6103ad5f610b9f565b565b6103b7610b11565b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f90cc2f570a6eb594b1580ea3e41247d2d73a55281889e86bd4ec2fc29c7e62d6905f90a35050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f811580156104775750825b90505f8267ffffffffffffffff1660011480156104935750303b155b9050811580156104a1575080155b156104d8576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156105395784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b5f5f5f888060200190518101906105509190611182565b92509250925061055f33610c34565b61056882610276565b610571816103af565b739008d19f58aabd9ed0d60971565aa8510560ab4173ffffffffffffffffffffffffffffffffffffffff1663f698da256040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ce573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105f291906111cc565b6004556105fe83610aae565b50505083156106625784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b610672610b11565b73ffffffffffffffffffffffffffffffffffffffff81161561078d576040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fe6d7a83a00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610716573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073a91906111e3565b61078d576040517fb16ea67e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa29060200160405180910390a150565b335f9081526003602052604090205460ff161515600114610853576040517ffb7595a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516038808252606082019092525f9160208201818036833701905050600454601f19850180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a0822091526040517f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260429020909150610930906109227f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005473ffffffffffffffffffffffffffffffffffffffff1690565b60a086015184929190610c45565b8080519060200120848051906020012014610977576040517f22fd4d1d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f848360405160240161098b92919061122c565b60408051601f19818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fec6cb13f0000000000000000000000000000000000000000000000000000000017905286518782015192519394505f936109ff93869390910161124f565b6040516020818303038152906040529050610a30739008d19f58aabd9ed0d60971565aa8510560ab415f835f610cc2565b610a66576040517f2570426300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83151586604051610a77919061128e565b604051908190038120907fd9a3d01ba00a83883cf5c59cd09596e6b5024427226f29b82f5e68d8a2219696905f90a3505050505050565b610ab6610b11565b73ffffffffffffffffffffffffffffffffffffffff8116610b05576040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081525f6004820152602401610784565b610b0e81610b9f565b50565b33610b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16146103ad576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610784565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b610c3c610e15565b610b0e81610e7c565b6038845114610cb0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f475076323a2075696420627566666572206f766572666c6f77000000000000006044820152606401610784565b60388401526034830152602090910152565b6002546040517f75f0bb520000000000000000000000000000000000000000000000000000000081525f9173ffffffffffffffffffffffffffffffffffffffff16906375f0bb5290610d2a9088908890889088908890819081908190819033906004016112dd565b5f604051808303815f87803b158015610d41575f5ffd5b505af1158015610d53573d5f5f3e3d5ffd5b505050505f83806020019051810190610d6c919061137d565b50506001546040517f468721a700000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff169063468721a790610dcb9089908990869089906004016113fd565b6020604051808303815f875af1158015610de7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e0b91906111e3565b9695505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff166103ad576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ab6610e15565b73ffffffffffffffffffffffffffffffffffffffff81168114610b0e575f5ffd5b8035610eb081610e84565b919050565b5f60208284031215610ec5575f5ffd5b8135610ed081610e84565b9392505050565b8015158114610b0e575f5ffd5b8035610eb081610ed7565b5f5f60408385031215610f00575f5ffd5b8235610f0b81610e84565b91506020830135610f1b81610ed7565b809150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051610180810167ffffffffffffffff81118282101715610f7757610f77610f26565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610fa657610fa6610f26565b604052919050565b5f67ffffffffffffffff821115610fc757610fc7610f26565b50601f01601f191660200190565b5f82601f830112610fe4575f5ffd5b8135610ff7610ff282610fae565b610f7d565b81815284602083860101111561100b575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215611037575f5ffd5b813567ffffffffffffffff81111561104d575f5ffd5b61105984828501610fd5565b949350505050565b803563ffffffff81168114610eb0575f5ffd5b5f5f5f8385036101c0811215611088575f5ffd5b843567ffffffffffffffff81111561109e575f5ffd5b6110aa87828801610fd5565b945050610180601f19820112156110bf575f5ffd5b506110c8610f53565b6110d460208601610ea5565b81526110e260408601610ea5565b60208201526110f360608601610ea5565b6040820152608085810135606083015260a08601359082015261111860c08601611061565b60a082015260e08581013560c083015261010080870135918301919091526101208601359082015261114d6101408601610ee4565b610120820152610160858101356101408301526101808601359082015291506111796101a08501610ee4565b90509250925092565b5f5f5f60608486031215611194575f5ffd5b835161119f81610e84565b60208501519093506111b081610e84565b60408501519092506111c181610e84565b809150509250925092565b5f602082840312156111dc575f5ffd5b5051919050565b5f602082840312156111f3575f5ffd5b8151610ed081610ed7565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b604081525f61123e60408301856111fe565b905082151560208301529392505050565b606081525f61126160608301866111fe565b73ffffffffffffffffffffffffffffffffffffffff94851660208401529290931660409091015292915050565b5f82518060208501845e5f920191825250919050565b600281106112d9577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b73ffffffffffffffffffffffffffffffffffffffff8b16815289602082015261016060408201525f61131361016083018b6111fe565b611320606084018b6112a4565b60808301989098525060a081019590955260c085019390935273ffffffffffffffffffffffffffffffffffffffff91821660e085015281166101008401528284036101208401525f84521661014090910152602001949350505050565b5f5f5f6060848603121561138f575f5ffd5b835167ffffffffffffffff8111156113a5575f5ffd5b8401601f810186136113b5575f5ffd5b80516113c3610ff282610fae565b8181528760208385010111156113d7575f5ffd5b8160208401602083015e5f6020838301015280955050505060208401516111b081610e84565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152608060408201525f61143160808301856111fe565b905061144060608301846112a4565b9594505050505056fea264697066735822122006b8d3b8abaaff36ebde3eca6385c34df9241725052a820e4017ac443484682064736f6c634300081c00339016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300f0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00000000000000000000000000043aa628bc477e91774149de5df3c33ac381916400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561000f575f5ffd5b50600436106100e5575f3560e01c80638da5cb5b11610088578063d4b8399211610063578063d4b839921461021d578063e19a9dd91461023d578063e71d7f6114610250578063f2fde38b14610263575f5ffd5b80638da5cb5b146101af578063a4f9edbf146101ec578063c9106389146101ff575f5ffd5b80635aef7de6116100c35780635aef7de614610155578063715018a614610174578063776d1a011461017c5780637ceab3b11461018f575f5ffd5b8063086cfca8146100e957806333ebc632146100fe57806341513c1d14610111575b5f5ffd5b6100fc6100f7366004610eb5565b610276565b005b6100fc61010c366004610eef565b6102f2565b61012c739008d19f58aabd9ed0d60971565aa8510560ab4181565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b5f5461012c9073ffffffffffffffffffffffffffffffffffffffff1681565b6100fc61039c565b6100fc61018a366004610eb5565b6103af565b60025461012c9073ffffffffffffffffffffffffffffffffffffffff1681565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005473ffffffffffffffffffffffffffffffffffffffff1661012c565b6100fc6101fa366004611027565b61042d565b60025473ffffffffffffffffffffffffffffffffffffffff1661012c565b60015461012c9073ffffffffffffffffffffffffffffffffffffffff1681565b6100fc61024b366004610eb5565b61066a565b6100fc61025e366004611074565b610806565b6100fc610271366004610eb5565b610aae565b61027e610b11565b5f805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f52ae88b092de36f87fb43fe794eb1381023b9c1bce563a871154022c63dce3429190a35050565b6102fa610b11565b73ffffffffffffffffffffffffffffffffffffffff8216610347576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff919091165f90815260036020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b6103a4610b11565b6103ad5f610b9f565b565b6103b7610b11565b6001805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f90cc2f570a6eb594b1580ea3e41247d2d73a55281889e86bd4ec2fc29c7e62d6905f90a35050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff165f811580156104775750825b90505f8267ffffffffffffffff1660011480156104935750303b155b9050811580156104a1575080155b156104d8576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156105395784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b5f5f5f888060200190518101906105509190611182565b92509250925061055f33610c34565b61056882610276565b610571816103af565b739008d19f58aabd9ed0d60971565aa8510560ab4173ffffffffffffffffffffffffffffffffffffffff1663f698da256040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105ce573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105f291906111cc565b6004556105fe83610aae565b50505083156106625784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b505050505050565b610672610b11565b73ffffffffffffffffffffffffffffffffffffffff81161561078d576040517f01ffc9a70000000000000000000000000000000000000000000000000000000081527fe6d7a83a00000000000000000000000000000000000000000000000000000000600482015273ffffffffffffffffffffffffffffffffffffffff8216906301ffc9a790602401602060405180830381865afa158015610716573d5f5f3e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061073a91906111e3565b61078d576040517fb16ea67e00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f1151116914515bc0891ff9047a6cb32cf902546f83066499bcf8ba33d2353fa29060200160405180910390a150565b335f9081526003602052604090205460ff161515600114610853576040517ffb7595a200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516038808252606082019092525f9160208201818036833701905050600454601f19850180517fd5a25ba2e97094ad7d83dc28a6572da797d6b3e7fc6663bd93efb789fc17e48982526101a0822091526040517f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260429020909150610930906109227f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005473ffffffffffffffffffffffffffffffffffffffff1690565b60a086015184929190610c45565b8080519060200120848051906020012014610977576040517f22fd4d1d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f848360405160240161098b92919061122c565b60408051601f19818403018152918152602080830180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fec6cb13f0000000000000000000000000000000000000000000000000000000017905286518782015192519394505f936109ff93869390910161124f565b6040516020818303038152906040529050610a30739008d19f58aabd9ed0d60971565aa8510560ab415f835f610cc2565b610a66576040517f2570426300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83151586604051610a77919061128e565b604051908190038120907fd9a3d01ba00a83883cf5c59cd09596e6b5024427226f29b82f5e68d8a2219696905f90a3505050505050565b610ab6610b11565b73ffffffffffffffffffffffffffffffffffffffff8116610b05576040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081525f6004820152602401610784565b610b0e81610b9f565b50565b33610b507f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff16146103ad576040517f118cdaa7000000000000000000000000000000000000000000000000000000008152336004820152602401610784565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0905f90a3505050565b610c3c610e15565b610b0e81610e7c565b6038845114610cb0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f475076323a2075696420627566666572206f766572666c6f77000000000000006044820152606401610784565b60388401526034830152602090910152565b6002546040517f75f0bb520000000000000000000000000000000000000000000000000000000081525f9173ffffffffffffffffffffffffffffffffffffffff16906375f0bb5290610d2a9088908890889088908890819081908190819033906004016112dd565b5f604051808303815f87803b158015610d41575f5ffd5b505af1158015610d53573d5f5f3e3d5ffd5b505050505f83806020019051810190610d6c919061137d565b50506001546040517f468721a700000000000000000000000000000000000000000000000000000000815291925073ffffffffffffffffffffffffffffffffffffffff169063468721a790610dcb9089908990869089906004016113fd565b6020604051808303815f875af1158015610de7573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e0b91906111e3565b9695505050505050565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a005468010000000000000000900460ff166103ad576040517fd7e6bcf800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610ab6610e15565b73ffffffffffffffffffffffffffffffffffffffff81168114610b0e575f5ffd5b8035610eb081610e84565b919050565b5f60208284031215610ec5575f5ffd5b8135610ed081610e84565b9392505050565b8015158114610b0e575f5ffd5b8035610eb081610ed7565b5f5f60408385031215610f00575f5ffd5b8235610f0b81610e84565b91506020830135610f1b81610ed7565b809150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b604051610180810167ffffffffffffffff81118282101715610f7757610f77610f26565b60405290565b604051601f8201601f1916810167ffffffffffffffff81118282101715610fa657610fa6610f26565b604052919050565b5f67ffffffffffffffff821115610fc757610fc7610f26565b50601f01601f191660200190565b5f82601f830112610fe4575f5ffd5b8135610ff7610ff282610fae565b610f7d565b81815284602083860101111561100b575f5ffd5b816020850160208301375f918101602001919091529392505050565b5f60208284031215611037575f5ffd5b813567ffffffffffffffff81111561104d575f5ffd5b61105984828501610fd5565b949350505050565b803563ffffffff81168114610eb0575f5ffd5b5f5f5f8385036101c0811215611088575f5ffd5b843567ffffffffffffffff81111561109e575f5ffd5b6110aa87828801610fd5565b945050610180601f19820112156110bf575f5ffd5b506110c8610f53565b6110d460208601610ea5565b81526110e260408601610ea5565b60208201526110f360608601610ea5565b6040820152608085810135606083015260a08601359082015261111860c08601611061565b60a082015260e08581013560c083015261010080870135918301919091526101208601359082015261114d6101408601610ee4565b610120820152610160858101356101408301526101808601359082015291506111796101a08501610ee4565b90509250925092565b5f5f5f60608486031215611194575f5ffd5b835161119f81610e84565b60208501519093506111b081610e84565b60408501519092506111c181610e84565b809150509250925092565b5f602082840312156111dc575f5ffd5b5051919050565b5f602082840312156111f3575f5ffd5b8151610ed081610ed7565b5f81518084528060208401602086015e5f602082860101526020601f19601f83011685010191505092915050565b604081525f61123e60408301856111fe565b905082151560208301529392505050565b606081525f61126160608301866111fe565b73ffffffffffffffffffffffffffffffffffffffff94851660208401529290931660409091015292915050565b5f82518060208501845e5f920191825250919050565b600281106112d9577f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b9052565b73ffffffffffffffffffffffffffffffffffffffff8b16815289602082015261016060408201525f61131361016083018b6111fe565b611320606084018b6112a4565b60808301989098525060a081019590955260c085019390935273ffffffffffffffffffffffffffffffffffffffff91821660e085015281166101008401528284036101208401525f84521661014090910152602001949350505050565b5f5f5f6060848603121561138f575f5ffd5b835167ffffffffffffffff8111156113a5575f5ffd5b8401601f810186136113b5575f5ffd5b80516113c3610ff282610fae565b8181528760208385010111156113d7575f5ffd5b8160208401602083015e5f6020838301015280955050505060208401516111b081610e84565b73ffffffffffffffffffffffffffffffffffffffff85168152836020820152608060408201525f61143160808301856111fe565b905061144060608301846112a4565b9594505050505056fea264697066735822122006b8d3b8abaaff36ebde3eca6385c34df9241725052a820e4017ac443484682064736f6c634300081c0033

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

000000000000000000000000043aa628bc477e91774149de5df3c33ac381916400000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _owner (address): 0x043Aa628bC477e91774149de5dF3c33ac3819164
Arg [1] : _avatar (address): 0x0000000000000000000000000000000000000000
Arg [2] : _target (address): 0x0000000000000000000000000000000000000000

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000043aa628bc477e91774149de5df3c33ac3819164
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000


Block Transaction Gas Used Reward
view all blocks validated

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
[ 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.