POL Price: $0.208423 (-0.94%)
 

Overview

POL Balance

Polygon PoS Chain LogoPolygon PoS Chain LogoPolygon PoS Chain Logo0 POL

POL Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Transfer Ownersh...624215862024-09-29 13:27:08175 days ago1727616428IN
0xC4ad1c6f...cF79Df9E1
0 POL0.0012824345.00087121

Parent Transaction Hash Block From To
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Delegate

Compiler Version
v0.8.23+commit.f704f362

Optimization Enabled:
Yes with 999999 runs

Other Settings:
paris EvmVersion
File 1 of 5 : Delegate.sol
// SPDX-License-Identifier: MIT

pragma solidity 0.8.23;

import "./interfaces/IDelegate.sol";
import "@airswap/swap-erc20/contracts/interfaces/ISwapERC20.sol";
import { Ownable } from "solady/src/auth/Ownable.sol";
import { SafeTransferLib } from "solady/src/utils/SafeTransferLib.sol";

/**
 * @title AirSwap: Delegated On-chain Trading Rules
 * @notice Supports ERC-20 tokens
 * @dev inherits IDelegate, Ownable; uses SafeTransferLib
 */
contract Delegate is IDelegate, Ownable {
  // The SwapERC20 contract to be used to execute orders
  ISwapERC20 public swapERC20Contract;

  // Mapping of senderWallet to senderToken to to signerToken to Rule
  mapping(address => mapping(address => mapping(address => Rule))) public rules;

  // Mapping of senderWallet to an authorized manager
  mapping(address => address) public authorized;

  /**
   * @notice Constructor
   * @param _swapERC20Contract address
   */
  constructor(address _swapERC20Contract) {
    _initializeOwner(msg.sender);
    swapERC20Contract = ISwapERC20(_swapERC20Contract);
  }

  /**
   * @notice Set a Rule
   * @param _senderWallet address Address of the sender wallet
   * @param _senderToken address ERC-20 token the sender would transfer
   * @param _senderAmount uint256 Maximum sender amount for the rule
   * @param _signerToken address ERC-20 token the signer would transfer
   * @param _signerAmount uint256 Maximum signer amount for the rule
   * @param _expiry uint256 Expiry in seconds since 1 January 1970
   */
  function setRule(
    address _senderWallet,
    address _senderToken,
    uint256 _senderAmount,
    address _signerToken,
    uint256 _signerAmount,
    uint256 _expiry
  ) external {
    if (authorized[_senderWallet] != address(0)) {
      // If an authorized manager is set, message sender must be the manager
      if (msg.sender != authorized[_senderWallet]) revert SenderInvalid();
    } else {
      // Otherwise message sender must be the sender wallet
      if (msg.sender != _senderWallet) revert SenderInvalid();
    }

    // Set the rule. Overwrites an existing rule.
    rules[_senderWallet][_senderToken][_signerToken] = Rule(
      _senderWallet,
      _senderToken,
      _senderAmount,
      0,
      _signerToken,
      _signerAmount,
      _expiry
    );

    // Emit a SetRule event
    emit SetRule(
      _senderWallet,
      _senderToken,
      _senderAmount,
      _signerToken,
      _signerAmount,
      _expiry
    );
  }

  /**
   * @notice Unset a Rule
   * @param _senderWallet The address of the sender's wallet
   * @param _senderToken address ERC-20 token the sender would transfer
   * @param _signerToken address ERC-20 token the signer would transfer
   */
  function unsetRule(
    address _senderWallet,
    address _senderToken,
    address _signerToken
  ) external {
    if (authorized[_senderWallet] != address(0)) {
      // If an authorized manager is set, the message sender must be the manager
      if (msg.sender != authorized[_senderWallet]) revert SenderInvalid();
    } else {
      // Otherwise the message sender must be the sender wallet
      if (msg.sender != _senderWallet) revert SenderInvalid();
    }

    // Delete the rule
    delete rules[_senderWallet][_senderToken][_signerToken];

    // Emit an UnsetRule event
    emit UnsetRule(_senderWallet, _senderToken, _signerToken);
  }

  /**
   * @notice Perform an atomic ERC-20 swap
   * @dev Forwards to underlying SwapERC20 contract
   * @param _senderWallet address Wallet to receive sender proceeds
   * @param _nonce uint256 Unique and should be sequential
   * @param _expiry uint256 Expiry in seconds since 1 January 1970
   * @param _signerWallet address Wallet of the signer
   * @param _signerToken address ERC-20 token transferred from the signer
   * @param _signerAmount uint256 Amount transferred from the signer
   * @param _senderToken address ERC-20 token transferred from the sender
   * @param _senderAmount uint256 Amount transferred from the sender
   * @param _v uint8 "v" value of the ECDSA signature
   * @param _r bytes32 "r" value of the ECDSA signature
   * @param _s bytes32 "s" value of the ECDSA signature
   */
  function swap(
    address _senderWallet,
    uint256 _nonce,
    uint256 _expiry,
    address _signerWallet,
    address _signerToken,
    uint256 _signerAmount,
    address _senderToken,
    uint256 _senderAmount,
    uint8 _v,
    bytes32 _r,
    bytes32 _s
  ) external {
    Rule storage rule = rules[_senderWallet][_senderToken][_signerToken];
    // Ensure the signer amount is valid
    if (
      _signerAmount <
      (rule.signerAmount * (rule.senderAmount - rule.senderFilledAmount)) /
        rule.senderAmount
    ) {
      revert SignerAmountInvalid();
    }
    // Ensure the rule has not expired
    if (rule.expiry < block.timestamp) revert RuleExpired();

    // Ensure the sender amount is valid
    if (_senderAmount > (rule.senderAmount - rule.senderFilledAmount)) {
      revert SenderAmountInvalid();
    }

    // Transfer the sender token to this contract
    SafeTransferLib.safeTransferFrom(
      _senderToken,
      _senderWallet,
      address(this),
      _senderAmount
    );

    // Approve the SwapERC20 contract to transfer the sender token
    SafeTransferLib.safeApprove(
      _senderToken,
      address(swapERC20Contract),
      _senderAmount
    );

    // Execute the swap
    swapERC20Contract.swapLight(
      _nonce,
      _expiry,
      _signerWallet,
      _signerToken,
      _signerAmount,
      _senderToken,
      _senderAmount,
      _v,
      _r,
      _s
    );

    // Transfer the signer token to the sender wallet
    SafeTransferLib.safeTransfer(_signerToken, _senderWallet, _signerAmount);

    // Update the filled amount
    rules[_senderWallet][_senderToken][_signerToken]
      .senderFilledAmount += _senderAmount;

    // Emit a DelegateSwap event
    emit DelegateSwap(_nonce, _signerWallet);
  }

  /**
   * @notice Authorize a wallet to manage rules
   * @param _manager address Wallet of the manager to authorize
   * @dev Emits an Authorize event
   */
  function authorize(address _manager) external {
    if (_manager == address(0)) revert ManagerInvalid();
    authorized[msg.sender] = _manager;
    emit Authorize(_manager, msg.sender);
  }

  /**
   * @notice Revoke a manager
   * @dev Emits a Revoke event
   */
  function revoke() external {
    address _tmp = authorized[msg.sender];
    delete authorized[msg.sender];
    emit Revoke(_tmp, msg.sender);
  }

  /**
   * @notice Sets the SwapERC20 contract
   * @param _swapERC20Contract address
   */
  function setSwapERC20Contract(address _swapERC20Contract) external onlyOwner {
    if (_swapERC20Contract == address(0)) revert AddressInvalid();
    swapERC20Contract = ISwapERC20(_swapERC20Contract);
  }
}

File 2 of 5 : ISwapERC20.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.23;

interface ISwapERC20 {
  struct OrderERC20 {
    uint256 nonce; // Unique number per signatory per order
    uint256 expiry; // Expiry time (seconds since unix epoch)
    address signerWallet; // Party to the swap that sets terms
    address signerToken; // ERC20 token address transferred from signer
    uint256 signerAmount; // Amount of tokens transferred from signer
    address senderWallet; // Party to the swap that accepts terms
    address senderToken; // ERC20 token address transferred from sender
    uint256 senderAmount; // Amount of tokens transferred from sender
    uint8 v; // ECDSA
    bytes32 r;
    bytes32 s;
  }

  event SwapERC20(uint256 indexed nonce, address indexed signerWallet);

  event Cancel(uint256 indexed nonce, address indexed signerWallet);
  event Authorize(address indexed signer, address indexed signerWallet);
  event Revoke(address indexed signer, address indexed signerWallet);
  event SetProtocolFee(uint256 protocolFee);
  event SetProtocolFeeLight(uint256 protocolFeeLight);
  event SetProtocolFeeWallet(address indexed feeWallet);
  event SetBonusScale(uint256 bonusScale);
  event SetBonusMax(uint256 bonusMax);
  event SetStaking(address indexed staking);

  error MaxTooHigh();
  error NonceAlreadyUsed(uint256);
  error OrderExpired();
  error ProtocolFeeInvalid();
  error ProtocolFeeLightInvalid();
  error ProtocolFeeWalletInvalid();
  error ScaleTooHigh();
  error SignatoryInvalid();
  error SignatureInvalid();
  error StakingInvalid();
  error TransferFromFailed();

  function swap(
    address recipient,
    uint256 nonce,
    uint256 expiry,
    address signerWallet,
    address signerToken,
    uint256 signerAmount,
    address senderToken,
    uint256 senderAmount,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external;

  function swapAnySender(
    address recipient,
    uint256 nonce,
    uint256 expiry,
    address signerWallet,
    address signerToken,
    uint256 signerAmount,
    address senderToken,
    uint256 senderAmount,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external;

  function swapLight(
    uint256 nonce,
    uint256 expiry,
    address signerWallet,
    address signerToken,
    uint256 signerAmount,
    address senderToken,
    uint256 senderAmount,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external;

  function authorize(address sender) external;

  function revoke() external;

  function cancel(uint256[] calldata nonces) external;

  function check(
    address senderWallet,
    uint256 nonce,
    uint256 expiry,
    address signerWallet,
    address signerToken,
    uint256 signerAmount,
    address senderToken,
    uint256 senderAmount,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external view returns (bytes32[] memory);

  function nonceUsed(address, uint256) external view returns (bool);

  function authorized(address) external view returns (address);

  function calculateProtocolFee(
    address,
    uint256
  ) external view returns (uint256);
}

File 3 of 5 : IDelegate.sol
// SPDX-License-Identifier: MIT

import "@airswap/swap-erc20/contracts/interfaces/ISwapERC20.sol";

pragma solidity 0.8.23;

interface IDelegate {
  struct Rule {
    address senderWallet;
    address senderToken;
    uint256 senderAmount;
    uint256 senderFilledAmount;
    address signerToken;
    uint256 signerAmount;
    uint256 expiry;
  }

  event Authorize(address signatory, address signer);
  event DelegateSwap(uint256 nonce, address signerWallet);
  event Revoke(address tmp, address signer);

  event SetRule(
    address senderWallet,
    address senderToken,
    uint256 senderAmount,
    address signerToken,
    uint256 signerAmount,
    uint256 expiry
  );

  event UnsetRule(
    address senderWallet,
    address senderToken,
    address signerToken
  );

  error AddressInvalid();
  error RuleExpired();
  error SenderAmountInvalid();
  error SignerAmountInvalid();
  error SenderInvalid();
  error ManagerInvalid();
  error TransferFromFailed();

  function setRule(
    address senderWallet,
    address senderToken,
    uint256 senderAmount,
    address signerToken,
    uint256 signerAmount,
    uint256 expiry
  ) external;

  function swap(
    address senderWallet,
    uint256 nonce,
    uint256 expiry,
    address signerWallet,
    address signerToken,
    uint256 signerAmount,
    address senderToken,
    uint256 senderAmount,
    uint8 v,
    bytes32 r,
    bytes32 s
  ) external;

  function unsetRule(
    address senderWallet,
    address senderToken,
    address signerToken
  ) external;

  function authorize(address manager) external;

  function revoke() external;

  function setSwapERC20Contract(address _swapERC20Contract) external;
}

File 4 of 5 : Ownable.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Simple single owner authorization mixin.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/auth/Ownable.sol)
///
/// @dev Note:
/// This implementation does NOT auto-initialize the owner to `msg.sender`.
/// You MUST call the `_initializeOwner` in the constructor / initializer.
///
/// While the ownable portion follows
/// [EIP-173](https://eips.ethereum.org/EIPS/eip-173) for compatibility,
/// the nomenclature for the 2-step ownership handover may be unique to this codebase.
abstract contract Ownable {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The caller is not authorized to call the function.
    error Unauthorized();

    /// @dev The `newOwner` cannot be the zero address.
    error NewOwnerIsZeroAddress();

    /// @dev The `pendingOwner` does not have a valid handover request.
    error NoHandoverRequest();

    /// @dev Cannot double-initialize.
    error AlreadyInitialized();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                           EVENTS                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ownership is transferred from `oldOwner` to `newOwner`.
    /// This event is intentionally kept the same as OpenZeppelin's Ownable to be
    /// compatible with indexers and [EIP-173](https://eips.ethereum.org/EIPS/eip-173),
    /// despite it not being as lightweight as a single argument event.
    event OwnershipTransferred(address indexed oldOwner, address indexed newOwner);

    /// @dev An ownership handover to `pendingOwner` has been requested.
    event OwnershipHandoverRequested(address indexed pendingOwner);

    /// @dev The ownership handover to `pendingOwner` has been canceled.
    event OwnershipHandoverCanceled(address indexed pendingOwner);

    /// @dev `keccak256(bytes("OwnershipTransferred(address,address)"))`.
    uint256 private constant _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE =
        0x8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0;

    /// @dev `keccak256(bytes("OwnershipHandoverRequested(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE =
        0xdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d;

    /// @dev `keccak256(bytes("OwnershipHandoverCanceled(address)"))`.
    uint256 private constant _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE =
        0xfa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                          STORAGE                           */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The owner slot is given by:
    /// `bytes32(~uint256(uint32(bytes4(keccak256("_OWNER_SLOT_NOT")))))`.
    /// It is intentionally chosen to be a high value
    /// to avoid collision with lower slots.
    /// The choice of manual storage layout is to enable compatibility
    /// with both regular and upgradeable contracts.
    bytes32 internal constant _OWNER_SLOT =
        0xffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927;

    /// The ownership handover slot of `newOwner` is given by:
    /// ```
    ///     mstore(0x00, or(shl(96, user), _HANDOVER_SLOT_SEED))
    ///     let handoverSlot := keccak256(0x00, 0x20)
    /// ```
    /// It stores the expiry timestamp of the two-step ownership handover.
    uint256 private constant _HANDOVER_SLOT_SEED = 0x389a75e1;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                     INTERNAL FUNCTIONS                     */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Override to return true to make `_initializeOwner` prevent double-initialization.
    function _guardInitializeOwner() internal pure virtual returns (bool guard) {}

    /// @dev Initializes the owner directly without authorization guard.
    /// This function must be called upon initialization,
    /// regardless of whether the contract is upgradeable or not.
    /// This is to enable generalization to both regular and upgradeable contracts,
    /// and to save gas in case the initial owner is not the caller.
    /// For performance reasons, this function will not check if there
    /// is an existing owner.
    function _initializeOwner(address newOwner) internal virtual {
        if (_guardInitializeOwner()) {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                if sload(ownerSlot) {
                    mstore(0x00, 0x0dc149f0) // `AlreadyInitialized()`.
                    revert(0x1c, 0x04)
                }
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Store the new value.
                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
            }
        } else {
            /// @solidity memory-safe-assembly
            assembly {
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Store the new value.
                sstore(_OWNER_SLOT, newOwner)
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, 0, newOwner)
            }
        }
    }

    /// @dev Sets the owner directly without authorization guard.
    function _setOwner(address newOwner) internal virtual {
        if (_guardInitializeOwner()) {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
                // Store the new value.
                sstore(ownerSlot, or(newOwner, shl(255, iszero(newOwner))))
            }
        } else {
            /// @solidity memory-safe-assembly
            assembly {
                let ownerSlot := _OWNER_SLOT
                // Clean the upper 96 bits.
                newOwner := shr(96, shl(96, newOwner))
                // Emit the {OwnershipTransferred} event.
                log3(0, 0, _OWNERSHIP_TRANSFERRED_EVENT_SIGNATURE, sload(ownerSlot), newOwner)
                // Store the new value.
                sstore(ownerSlot, newOwner)
            }
        }
    }

    /// @dev Throws if the sender is not the owner.
    function _checkOwner() internal view virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // If the caller is not the stored owner, revert.
            if iszero(eq(caller(), sload(_OWNER_SLOT))) {
                mstore(0x00, 0x82b42900) // `Unauthorized()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Returns how long a two-step ownership handover is valid for in seconds.
    /// Override to return a different value if needed.
    /// Made internal to conserve bytecode. Wrap it in a public function if needed.
    function _ownershipHandoverValidFor() internal view virtual returns (uint64) {
        return 48 * 3600;
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                  PUBLIC UPDATE FUNCTIONS                   */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Allows the owner to transfer the ownership to `newOwner`.
    function transferOwnership(address newOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(shl(96, newOwner)) {
                mstore(0x00, 0x7448fbae) // `NewOwnerIsZeroAddress()`.
                revert(0x1c, 0x04)
            }
        }
        _setOwner(newOwner);
    }

    /// @dev Allows the owner to renounce their ownership.
    function renounceOwnership() public payable virtual onlyOwner {
        _setOwner(address(0));
    }

    /// @dev Request a two-step ownership handover to the caller.
    /// The request will automatically expire in 48 hours (172800 seconds) by default.
    function requestOwnershipHandover() public payable virtual {
        unchecked {
            uint256 expires = block.timestamp + _ownershipHandoverValidFor();
            /// @solidity memory-safe-assembly
            assembly {
                // Compute and set the handover slot to `expires`.
                mstore(0x0c, _HANDOVER_SLOT_SEED)
                mstore(0x00, caller())
                sstore(keccak256(0x0c, 0x20), expires)
                // Emit the {OwnershipHandoverRequested} event.
                log2(0, 0, _OWNERSHIP_HANDOVER_REQUESTED_EVENT_SIGNATURE, caller())
            }
        }
    }

    /// @dev Cancels the two-step ownership handover to the caller, if any.
    function cancelOwnershipHandover() public payable virtual {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, caller())
            sstore(keccak256(0x0c, 0x20), 0)
            // Emit the {OwnershipHandoverCanceled} event.
            log2(0, 0, _OWNERSHIP_HANDOVER_CANCELED_EVENT_SIGNATURE, caller())
        }
    }

    /// @dev Allows the owner to complete the two-step ownership handover to `pendingOwner`.
    /// Reverts if there is no existing ownership handover requested by `pendingOwner`.
    function completeOwnershipHandover(address pendingOwner) public payable virtual onlyOwner {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute and set the handover slot to 0.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            let handoverSlot := keccak256(0x0c, 0x20)
            // If the handover does not exist, or has expired.
            if gt(timestamp(), sload(handoverSlot)) {
                mstore(0x00, 0x6f5e8818) // `NoHandoverRequest()`.
                revert(0x1c, 0x04)
            }
            // Set the handover slot to 0.
            sstore(handoverSlot, 0)
        }
        _setOwner(pendingOwner);
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                   PUBLIC READ FUNCTIONS                    */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Returns the owner of the contract.
    function owner() public view virtual returns (address result) {
        /// @solidity memory-safe-assembly
        assembly {
            result := sload(_OWNER_SLOT)
        }
    }

    /// @dev Returns the expiry timestamp for the two-step ownership handover to `pendingOwner`.
    function ownershipHandoverExpiresAt(address pendingOwner)
        public
        view
        virtual
        returns (uint256 result)
    {
        /// @solidity memory-safe-assembly
        assembly {
            // Compute the handover slot.
            mstore(0x0c, _HANDOVER_SLOT_SEED)
            mstore(0x00, pendingOwner)
            // Load the handover slot.
            result := sload(keccak256(0x0c, 0x20))
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         MODIFIERS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Marks a function as only callable by the owner.
    modifier onlyOwner() virtual {
        _checkOwner();
        _;
    }
}

File 5 of 5 : SafeTransferLib.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solady (https://github.com/vectorized/solady/blob/main/src/utils/SafeTransferLib.sol)
/// @author Modified from Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
///
/// @dev Note:
/// - For ETH transfers, please use `forceSafeTransferETH` for DoS protection.
/// - For ERC20s, this implementation won't check that a token has code,
///   responsibility is delegated to the caller.
library SafeTransferLib {
    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       CUSTOM ERRORS                        */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev The ETH transfer has failed.
    error ETHTransferFailed();

    /// @dev The ERC20 `transferFrom` has failed.
    error TransferFromFailed();

    /// @dev The ERC20 `transfer` has failed.
    error TransferFailed();

    /// @dev The ERC20 `approve` has failed.
    error ApproveFailed();

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                         CONSTANTS                          */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Suggested gas stipend for contract receiving ETH that disallows any storage writes.
    uint256 internal constant GAS_STIPEND_NO_STORAGE_WRITES = 2300;

    /// @dev Suggested gas stipend for contract receiving ETH to perform a few
    /// storage reads and writes, but low enough to prevent griefing.
    uint256 internal constant GAS_STIPEND_NO_GRIEF = 100000;

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                       ETH OPERATIONS                       */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    // If the ETH transfer MUST succeed with a reasonable gas budget, use the force variants.
    //
    // The regular variants:
    // - Forwards all remaining gas to the target.
    // - Reverts if the target reverts.
    // - Reverts if the current contract has insufficient balance.
    //
    // The force variants:
    // - Forwards with an optional gas stipend
    //   (defaults to `GAS_STIPEND_NO_GRIEF`, which is sufficient for most cases).
    // - If the target reverts, or if the gas stipend is exhausted,
    //   creates a temporary contract to force send the ETH via `SELFDESTRUCT`.
    //   Future compatible with `SENDALL`: https://eips.ethereum.org/EIPS/eip-4758.
    // - Reverts if the current contract has insufficient balance.
    //
    // The try variants:
    // - Forwards with a mandatory gas stipend.
    // - Instead of reverting, returns whether the transfer succeeded.

    /// @dev Sends `amount` (in wei) ETH to `to`.
    function safeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gas(), to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`.
    function safeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // Transfer all the ETH and check if it succeeded or not.
            if iszero(call(gas(), to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function forceSafeTransferETH(address to, uint256 amount, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function forceSafeTransferAllETH(address to, uint256 gasStipend) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if iszero(call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends `amount` (in wei) ETH to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferETH(address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            if lt(selfbalance(), amount) {
                mstore(0x00, 0xb12d13eb) // `ETHTransferFailed()`.
                revert(0x1c, 0x04)
            }
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, amount, codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(amount, 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Force sends all the ETH in the current contract to `to`, with `GAS_STIPEND_NO_GRIEF`.
    function forceSafeTransferAllETH(address to) internal {
        /// @solidity memory-safe-assembly
        assembly {
            // forgefmt: disable-next-item
            if iszero(call(GAS_STIPEND_NO_GRIEF, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)) {
                mstore(0x00, to) // Store the address in scratch space.
                mstore8(0x0b, 0x73) // Opcode `PUSH20`.
                mstore8(0x20, 0xff) // Opcode `SELFDESTRUCT`.
                if iszero(create(selfbalance(), 0x0b, 0x16)) { revert(codesize(), codesize()) } // For gas estimation.
            }
        }
    }

    /// @dev Sends `amount` (in wei) ETH to `to`, with a `gasStipend`.
    function trySafeTransferETH(address to, uint256 amount, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, amount, codesize(), 0x00, codesize(), 0x00)
        }
    }

    /// @dev Sends all the ETH in the current contract to `to`, with a `gasStipend`.
    function trySafeTransferAllETH(address to, uint256 gasStipend)
        internal
        returns (bool success)
    {
        /// @solidity memory-safe-assembly
        assembly {
            success := call(gasStipend, to, selfbalance(), codesize(), 0x00, codesize(), 0x00)
        }
    }

    /*´:°•.°+.*•´.*:˚.°*.˚•´.°:°•.°•.*•´.*:˚.°*.˚•´.°:°•.°+.*•´.*:*/
    /*                      ERC20 OPERATIONS                      */
    /*.•°:°.´+˚.*°.˚:*.´•*.+°.•°:´*.´•*.•°.•°:°.´:•˚°.*°.˚:*.´+°.•*/

    /// @dev Sends `amount` of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have at least `amount` approved for
    /// the current contract to manage.
    function safeTransferFrom(address token, address from, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x60, amount) // Store the `amount` argument.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x23b872dd000000000000000000000000) // `transferFrom(address,address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends all of ERC20 `token` from `from` to `to`.
    /// Reverts upon failure.
    ///
    /// The `from` account must have their entire balance approved for
    /// the current contract to manage.
    function safeTransferAllFrom(address token, address from, address to)
        internal
        returns (uint256 amount)
    {
        /// @solidity memory-safe-assembly
        assembly {
            let m := mload(0x40) // Cache the free memory pointer.
            mstore(0x40, to) // Store the `to` argument.
            mstore(0x2c, shl(96, from)) // Store the `from` argument.
            mstore(0x0c, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x60, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x00, 0x23b872dd) // `transferFrom(address,address,uint256)`.
            amount := mload(0x60) // The `amount` is already at 0x60. We'll need to return it.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x1c, 0x64, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x7939f424) // `TransferFromFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x60, 0) // Restore the zero slot to zero.
            mstore(0x40, m) // Restore the free memory pointer.
        }
    }

    /// @dev Sends `amount` of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransfer(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sends all of ERC20 `token` from the current contract to `to`.
    /// Reverts upon failure.
    function safeTransferAll(address token, address to) internal returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, 0x70a08231) // Store the function selector of `balanceOf(address)`.
            mstore(0x20, address()) // Store the address of the current contract.
            // Read the balance, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                    staticcall(gas(), token, 0x1c, 0x24, 0x34, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x14, to) // Store the `to` argument.
            amount := mload(0x34) // The `amount` is already at 0x34. We'll need to return it.
            mstore(0x00, 0xa9059cbb000000000000000000000000) // `transfer(address,uint256)`.
            // Perform the transfer, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x90b8ec18) // `TransferFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// Reverts upon failure.
    function safeApprove(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, reverting upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                revert(0x1c, 0x04)
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Sets `amount` of ERC20 `token` for `to` to manage on behalf of the current contract.
    /// If the initial attempt to approve fails, attempts to reset the approved amount to zero,
    /// then retries the approval again (some tokens, e.g. USDT, requires this).
    /// Reverts upon failure.
    function safeApproveWithRetry(address token, address to, uint256 amount) internal {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, to) // Store the `to` argument.
            mstore(0x34, amount) // Store the `amount` argument.
            mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
            // Perform the approval, retrying upon failure.
            if iszero(
                and( // The arguments of `and` are evaluated from right to left.
                    or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                    call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                )
            ) {
                mstore(0x34, 0) // Store 0 for the `amount`.
                mstore(0x00, 0x095ea7b3000000000000000000000000) // `approve(address,uint256)`.
                pop(call(gas(), token, 0, 0x10, 0x44, codesize(), 0x00)) // Reset the approval.
                mstore(0x34, amount) // Store back the original `amount`.
                // Retry the approval, reverting upon failure.
                if iszero(
                    and(
                        or(eq(mload(0x00), 1), iszero(returndatasize())), // Returned 1 or nothing.
                        call(gas(), token, 0, 0x10, 0x44, 0x00, 0x20)
                    )
                ) {
                    mstore(0x00, 0x3e3f8f73) // `ApproveFailed()`.
                    revert(0x1c, 0x04)
                }
            }
            mstore(0x34, 0) // Restore the part of the free memory pointer that was overwritten.
        }
    }

    /// @dev Returns the amount of ERC20 `token` owned by `account`.
    /// Returns zero if the `token` does not exist.
    function balanceOf(address token, address account) internal view returns (uint256 amount) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x14, account) // Store the `account` argument.
            mstore(0x00, 0x70a08231000000000000000000000000) // `balanceOf(address)`.
            amount :=
                mul(
                    mload(0x20),
                    and( // The arguments of `and` are evaluated from right to left.
                        gt(returndatasize(), 0x1f), // At least 32 bytes returned.
                        staticcall(gas(), token, 0x10, 0x24, 0x20, 0x20)
                    )
                )
        }
    }
}

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

Contract Security Audit

Contract ABI

API
[{"inputs":[{"internalType":"address","name":"_swapERC20Contract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AddressInvalid","type":"error"},{"inputs":[],"name":"AlreadyInitialized","type":"error"},{"inputs":[],"name":"ManagerInvalid","type":"error"},{"inputs":[],"name":"NewOwnerIsZeroAddress","type":"error"},{"inputs":[],"name":"NoHandoverRequest","type":"error"},{"inputs":[],"name":"RuleExpired","type":"error"},{"inputs":[],"name":"SenderAmountInvalid","type":"error"},{"inputs":[],"name":"SenderInvalid","type":"error"},{"inputs":[],"name":"SignerAmountInvalid","type":"error"},{"inputs":[],"name":"TransferFromFailed","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"signatory","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"Authorize","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nonce","type":"uint256"},{"indexed":false,"internalType":"address","name":"signerWallet","type":"address"}],"name":"DelegateSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipHandoverRequested","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oldOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"tmp","type":"address"},{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"Revoke","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"senderWallet","type":"address"},{"indexed":false,"internalType":"address","name":"senderToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"senderAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"signerToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"signerAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"expiry","type":"uint256"}],"name":"SetRule","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"senderWallet","type":"address"},{"indexed":false,"internalType":"address","name":"senderToken","type":"address"},{"indexed":false,"internalType":"address","name":"signerToken","type":"address"}],"name":"UnsetRule","type":"event"},{"inputs":[{"internalType":"address","name":"_manager","type":"address"}],"name":"authorize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"authorized","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"completeOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"result","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pendingOwner","type":"address"}],"name":"ownershipHandoverExpiresAt","outputs":[{"internalType":"uint256","name":"result","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"requestOwnershipHandover","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"revoke","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"rules","outputs":[{"internalType":"address","name":"senderWallet","type":"address"},{"internalType":"address","name":"senderToken","type":"address"},{"internalType":"uint256","name":"senderAmount","type":"uint256"},{"internalType":"uint256","name":"senderFilledAmount","type":"uint256"},{"internalType":"address","name":"signerToken","type":"address"},{"internalType":"uint256","name":"signerAmount","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_senderWallet","type":"address"},{"internalType":"address","name":"_senderToken","type":"address"},{"internalType":"uint256","name":"_senderAmount","type":"uint256"},{"internalType":"address","name":"_signerToken","type":"address"},{"internalType":"uint256","name":"_signerAmount","type":"uint256"},{"internalType":"uint256","name":"_expiry","type":"uint256"}],"name":"setRule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_swapERC20Contract","type":"address"}],"name":"setSwapERC20Contract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_senderWallet","type":"address"},{"internalType":"uint256","name":"_nonce","type":"uint256"},{"internalType":"uint256","name":"_expiry","type":"uint256"},{"internalType":"address","name":"_signerWallet","type":"address"},{"internalType":"address","name":"_signerToken","type":"address"},{"internalType":"uint256","name":"_signerAmount","type":"uint256"},{"internalType":"address","name":"_senderToken","type":"address"},{"internalType":"uint256","name":"_senderAmount","type":"uint256"},{"internalType":"uint8","name":"_v","type":"uint8"},{"internalType":"bytes32","name":"_r","type":"bytes32"},{"internalType":"bytes32","name":"_s","type":"bytes32"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapERC20Contract","outputs":[{"internalType":"contract ISwapERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_senderWallet","type":"address"},{"internalType":"address","name":"_senderToken","type":"address"},{"internalType":"address","name":"_signerToken","type":"address"}],"name":"unsetRule","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405234801561001057600080fd5b506040516112ac3803806112ac83398101604081905261002f91610099565b6100383361005d565b600080546001600160a01b0319166001600160a01b03929092169190911790556100c9565b6001600160a01b0316638b78c6d8198190558060007f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e08180a350565b6000602082840312156100ab57600080fd5b81516001600160a01b03811681146100c257600080fd5b9392505050565b6111d4806100d86000396000f3fe6080604052600436106100f35760003560e01c8063b6549f751161008a578063d30008c311610059578063d30008c314610349578063f04e283e14610369578063f2fde38b1461037c578063fee81cf41461038f57600080fd5b8063b6549f75146102a4578063b6a5d7de146102b9578063b9181611146102d9578063cda25cf01461031c57600080fd5b8063715018a6116100c6578063715018a61461014a5780638da5cb5b1461015257806398956069146101ac578063ab92efcc146101cc57600080fd5b806325692962146100f85780634f41492a1461010257806354710ef81461012257806354d1f13d14610142575b600080fd5b6101006103d0565b005b34801561010e57600080fd5b5061010061011d366004610f81565b610420565b34801561012e57600080fd5b5061010061013d366004610fa3565b6104bc565b61010061070d565b610100610749565b34801561015e57600080fd5b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927545b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101b857600080fd5b506101006101c7366004611002565b61075d565b3480156101d857600080fd5b506102506101e73660046110ae565b6001602081815260009485526040808620825293855283852090529083529120805491810154600282015460038301546004840154600585015460069095015473ffffffffffffffffffffffffffffffffffffffff968716969485169593949293919092169187565b6040805173ffffffffffffffffffffffffffffffffffffffff988916815296881660208801528601949094526060850192909252909316608083015260a082019290925260c081019190915260e0016101a3565b3480156102b057600080fd5b50610100610a43565b3480156102c557600080fd5b506101006102d4366004610f81565b610ad2565b3480156102e557600080fd5b506101826102f4366004610f81565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b34801561032857600080fd5b506000546101829073ffffffffffffffffffffffffffffffffffffffff1681565b34801561035557600080fd5b506101006103643660046110ae565b610ba7565b610100610377366004610f81565b610d64565b61010061038a366004610f81565b610da4565b34801561039b57600080fd5b506103c26103aa366004610f81565b63389a75e1600c908152600091909152602090205490565b6040519081526020016101a3565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b610428610dcb565b73ffffffffffffffffffffffffffffffffffffffff8116610475576040517fa2f98bc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff868116600090815260026020526040902054161561054e5773ffffffffffffffffffffffffffffffffffffffff868116600090815260026020526040902054163314610549576040517fa7202ef600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61059d565b3373ffffffffffffffffffffffffffffffffffffffff87161461059d576040517fa7202ef600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e08101825273ffffffffffffffffffffffffffffffffffffffff80891680835288821660208085018281528587018b81526000606088018181528c881660808a0181815260a08b018e815260c08c018e815299855260018089528d86209986529888528c852092855291909652918a9020985189549089167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216178a55935195890180549689169685169690961790955590516002880155925160038701559051600486018054919095169116179092559051600583015551600690910155517fd3f505973293e83a9a1d2ef697e7231a63d6ca30cb4d81d1e40fed7ba6b72352906106fd9088908890889088908890889073ffffffffffffffffffffffffffffffffffffffff96871681529486166020860152604085019390935293166060830152608082019290925260a081019190915260c00190565b60405180910390a1505050505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b610751610dcb565b61075b6000610e01565b565b73ffffffffffffffffffffffffffffffffffffffff808c16600090815260016020908152604080832089851684528252808320938b16835292905220600281015460038201546107ad9082611120565b82600501546107bc9190611139565b6107c69190611150565b8710156107ff576040517faa7751c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b428160060154101561083d576040517f212ee34000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806003015481600201546108519190611120565b85111561088a576040517fce518e5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610896868d3088610e67565b6000546108bb90879073ffffffffffffffffffffffffffffffffffffffff1687610ec4565b6000546040517f46e4480d000000000000000000000000000000000000000000000000000000008152600481018d9052602481018c905273ffffffffffffffffffffffffffffffffffffffff8b811660448301528a81166064830152608482018a905288811660a483015260c4820188905260ff871660e483015261010482018690526101248201859052909116906346e4480d9061014401600060405180830381600087803b15801561096e57600080fd5b505af1158015610982573d6000803e3d6000fd5b50505050610991888d89610f13565b73ffffffffffffffffffffffffffffffffffffffff808d1660009081526001602090815260408083208a851684528252808320938c16835292905290812060030180548792906109e290849061118b565b9091555050604080518c815273ffffffffffffffffffffffffffffffffffffffff8b1660208201527fc2d98e54975bdbc02531f53389b2e9c591eafcb383243f05c883017260340ad8910160405180910390a1505050505050505050505050565b3360008181526002602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000008116909155825173ffffffffffffffffffffffffffffffffffffffff90911680825291810193909352917fd7426110292f20fe59e73ccf52124e0f5440a756507c91c7b0a6c50e1eb1a23a91015b60405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff8116610b1f576040517fc3a29bad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360008181526002602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86169081179091558251908152908101929092527f30468de898bda644e26bab66e5a2241a3aa6aaf527257f5ca54e0f65204ba14a9101610ac7565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600260205260409020541615610c395773ffffffffffffffffffffffffffffffffffffffff838116600090815260026020526040902054163314610c34576040517fa7202ef600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c88565b3373ffffffffffffffffffffffffffffffffffffffff841614610c88576040517fa7202ef600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff838116600081815260016020818152604080842088871680865290835281852096881680865296835281852080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116825594810180548616905560028101869055600381018690556004810180549095169094556005840185905560069093019390935582519384528301528101919091527f8a5de2720528dbd2e4fe17889175d99555344219a0e2ef60298dc68801f57c989060600160405180910390a1505050565b610d6c610dcb565b63389a75e1600c52806000526020600c208054421115610d9457636f5e88186000526004601cfd5b60009055610da181610e01565b50565b610dac610dcb565b8060601b610dc257637448fbae6000526004601cfd5b610da181610e01565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff7487392754331461075b576382b429006000526004601cfd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927805473ffffffffffffffffffffffffffffffffffffffff9092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b60405181606052826040528360601b602c526f23b872dd000000000000000000000000600c52602060006064601c6000895af13d156001600051141716610eb657637939f4246000526004601cfd5b600060605260405250505050565b81601452806034526f095ea7b300000000000000000000000060005260206000604460106000875af13d156001600051141716610f0957633e3f8f736000526004601cfd5b6000603452505050565b81601452806034526fa9059cbb00000000000000000000000060005260206000604460106000875af13d156001600051141716610f09576390b8ec186000526004601cfd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b919050565b600060208284031215610f9357600080fd5b610f9c82610f58565b9392505050565b60008060008060008060c08789031215610fbc57600080fd5b610fc587610f58565b9550610fd360208801610f58565b945060408701359350610fe860608801610f58565b92506080870135915060a087013590509295509295509295565b60008060008060008060008060008060006101608c8e03121561102457600080fd5b61102d8c610f58565b9a5060208c0135995060408c0135985061104960608d01610f58565b975061105760808d01610f58565b965060a08c0135955061106c60c08d01610f58565b945060e08c013593506101008c013560ff8116811461108a57600080fd5b809350506101208c013591506101408c013590509295989b509295989b9093969950565b6000806000606084860312156110c357600080fd5b6110cc84610f58565b92506110da60208501610f58565b91506110e860408501610f58565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115611133576111336110f1565b92915050565b8082028115828204841417611133576111336110f1565b600082611186577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820180821115611133576111336110f156fea2646970667358221220d8a6f05acd41534b0992ebd157a141fb478c41ef78596686d00f1e14241ed6bb64736f6c63430008170033000000000000000000000000d82e10b9a4107939e55fcca9b53a9ede6cf2fc46

Deployed Bytecode

0x6080604052600436106100f35760003560e01c8063b6549f751161008a578063d30008c311610059578063d30008c314610349578063f04e283e14610369578063f2fde38b1461037c578063fee81cf41461038f57600080fd5b8063b6549f75146102a4578063b6a5d7de146102b9578063b9181611146102d9578063cda25cf01461031c57600080fd5b8063715018a6116100c6578063715018a61461014a5780638da5cb5b1461015257806398956069146101ac578063ab92efcc146101cc57600080fd5b806325692962146100f85780634f41492a1461010257806354710ef81461012257806354d1f13d14610142575b600080fd5b6101006103d0565b005b34801561010e57600080fd5b5061010061011d366004610f81565b610420565b34801561012e57600080fd5b5061010061013d366004610fa3565b6104bc565b61010061070d565b610100610749565b34801561015e57600080fd5b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927545b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101b857600080fd5b506101006101c7366004611002565b61075d565b3480156101d857600080fd5b506102506101e73660046110ae565b6001602081815260009485526040808620825293855283852090529083529120805491810154600282015460038301546004840154600585015460069095015473ffffffffffffffffffffffffffffffffffffffff968716969485169593949293919092169187565b6040805173ffffffffffffffffffffffffffffffffffffffff988916815296881660208801528601949094526060850192909252909316608083015260a082019290925260c081019190915260e0016101a3565b3480156102b057600080fd5b50610100610a43565b3480156102c557600080fd5b506101006102d4366004610f81565b610ad2565b3480156102e557600080fd5b506101826102f4366004610f81565b60026020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b34801561032857600080fd5b506000546101829073ffffffffffffffffffffffffffffffffffffffff1681565b34801561035557600080fd5b506101006103643660046110ae565b610ba7565b610100610377366004610f81565b610d64565b61010061038a366004610f81565b610da4565b34801561039b57600080fd5b506103c26103aa366004610f81565b63389a75e1600c908152600091909152602090205490565b6040519081526020016101a3565b60006202a30067ffffffffffffffff164201905063389a75e1600c5233600052806020600c2055337fdbf36a107da19e49527a7176a1babf963b4b0ff8cde35ee35d6cd8f1f9ac7e1d600080a250565b610428610dcb565b73ffffffffffffffffffffffffffffffffffffffff8116610475576040517fa2f98bc000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b73ffffffffffffffffffffffffffffffffffffffff868116600090815260026020526040902054161561054e5773ffffffffffffffffffffffffffffffffffffffff868116600090815260026020526040902054163314610549576040517fa7202ef600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61059d565b3373ffffffffffffffffffffffffffffffffffffffff87161461059d576040517fa7202ef600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160e08101825273ffffffffffffffffffffffffffffffffffffffff80891680835288821660208085018281528587018b81526000606088018181528c881660808a0181815260a08b018e815260c08c018e815299855260018089528d86209986529888528c852092855291909652918a9020985189549089167fffffffffffffffffffffffff0000000000000000000000000000000000000000918216178a55935195890180549689169685169690961790955590516002880155925160038701559051600486018054919095169116179092559051600583015551600690910155517fd3f505973293e83a9a1d2ef697e7231a63d6ca30cb4d81d1e40fed7ba6b72352906106fd9088908890889088908890889073ffffffffffffffffffffffffffffffffffffffff96871681529486166020860152604085019390935293166060830152608082019290925260a081019190915260c00190565b60405180910390a1505050505050565b63389a75e1600c523360005260006020600c2055337ffa7b8eab7da67f412cc9575ed43464468f9bfbae89d1675917346ca6d8fe3c92600080a2565b610751610dcb565b61075b6000610e01565b565b73ffffffffffffffffffffffffffffffffffffffff808c16600090815260016020908152604080832089851684528252808320938b16835292905220600281015460038201546107ad9082611120565b82600501546107bc9190611139565b6107c69190611150565b8710156107ff576040517faa7751c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b428160060154101561083d576040517f212ee34000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b806003015481600201546108519190611120565b85111561088a576040517fce518e5e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610896868d3088610e67565b6000546108bb90879073ffffffffffffffffffffffffffffffffffffffff1687610ec4565b6000546040517f46e4480d000000000000000000000000000000000000000000000000000000008152600481018d9052602481018c905273ffffffffffffffffffffffffffffffffffffffff8b811660448301528a81166064830152608482018a905288811660a483015260c4820188905260ff871660e483015261010482018690526101248201859052909116906346e4480d9061014401600060405180830381600087803b15801561096e57600080fd5b505af1158015610982573d6000803e3d6000fd5b50505050610991888d89610f13565b73ffffffffffffffffffffffffffffffffffffffff808d1660009081526001602090815260408083208a851684528252808320938c16835292905290812060030180548792906109e290849061118b565b9091555050604080518c815273ffffffffffffffffffffffffffffffffffffffff8b1660208201527fc2d98e54975bdbc02531f53389b2e9c591eafcb383243f05c883017260340ad8910160405180910390a1505050505050505050505050565b3360008181526002602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000008116909155825173ffffffffffffffffffffffffffffffffffffffff90911680825291810193909352917fd7426110292f20fe59e73ccf52124e0f5440a756507c91c7b0a6c50e1eb1a23a91015b60405180910390a150565b73ffffffffffffffffffffffffffffffffffffffff8116610b1f576040517fc3a29bad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360008181526002602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86169081179091558251908152908101929092527f30468de898bda644e26bab66e5a2241a3aa6aaf527257f5ca54e0f65204ba14a9101610ac7565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600260205260409020541615610c395773ffffffffffffffffffffffffffffffffffffffff838116600090815260026020526040902054163314610c34576040517fa7202ef600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c88565b3373ffffffffffffffffffffffffffffffffffffffff841614610c88576040517fa7202ef600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff838116600081815260016020818152604080842088871680865290835281852096881680865296835281852080547fffffffffffffffffffffffff0000000000000000000000000000000000000000908116825594810180548616905560028101869055600381018690556004810180549095169094556005840185905560069093019390935582519384528301528101919091527f8a5de2720528dbd2e4fe17889175d99555344219a0e2ef60298dc68801f57c989060600160405180910390a1505050565b610d6c610dcb565b63389a75e1600c52806000526020600c208054421115610d9457636f5e88186000526004601cfd5b60009055610da181610e01565b50565b610dac610dcb565b8060601b610dc257637448fbae6000526004601cfd5b610da181610e01565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff7487392754331461075b576382b429006000526004601cfd5b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffff74873927805473ffffffffffffffffffffffffffffffffffffffff9092169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0600080a355565b60405181606052826040528360601b602c526f23b872dd000000000000000000000000600c52602060006064601c6000895af13d156001600051141716610eb657637939f4246000526004601cfd5b600060605260405250505050565b81601452806034526f095ea7b300000000000000000000000060005260206000604460106000875af13d156001600051141716610f0957633e3f8f736000526004601cfd5b6000603452505050565b81601452806034526fa9059cbb00000000000000000000000060005260206000604460106000875af13d156001600051141716610f09576390b8ec186000526004601cfd5b803573ffffffffffffffffffffffffffffffffffffffff81168114610f7c57600080fd5b919050565b600060208284031215610f9357600080fd5b610f9c82610f58565b9392505050565b60008060008060008060c08789031215610fbc57600080fd5b610fc587610f58565b9550610fd360208801610f58565b945060408701359350610fe860608801610f58565b92506080870135915060a087013590509295509295509295565b60008060008060008060008060008060006101608c8e03121561102457600080fd5b61102d8c610f58565b9a5060208c0135995060408c0135985061104960608d01610f58565b975061105760808d01610f58565b965060a08c0135955061106c60c08d01610f58565b945060e08c013593506101008c013560ff8116811461108a57600080fd5b809350506101208c013591506101408c013590509295989b509295989b9093969950565b6000806000606084860312156110c357600080fd5b6110cc84610f58565b92506110da60208501610f58565b91506110e860408501610f58565b90509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115611133576111336110f1565b92915050565b8082028115828204841417611133576111336110f1565b600082611186577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b80820180821115611133576111336110f156fea2646970667358221220d8a6f05acd41534b0992ebd157a141fb478c41ef78596686d00f1e14241ed6bb64736f6c63430008170033

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

000000000000000000000000d82e10b9a4107939e55fcca9b53a9ede6cf2fc46

-----Decoded View---------------
Arg [0] : _swapERC20Contract (address): 0xD82E10B9A4107939e55fCCa9B53A9ede6CF2fC46

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d82e10b9a4107939e55fcca9b53a9ede6cf2fc46


Block Transaction Gas Used Reward
view all blocks produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
[ 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.