ETH Price: $3,386.03 (+1.38%)
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Token Holdings

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0xf5639f6d07b4bf28e05c06f1c7356b0fd6454e880af1eabd47128880cd007aae Bridge With Perm...(pending)2025-01-01 19:46:025 hrs ago1735760762IN
0xDf9Fa2b4...0ED37020F
0.0003398791 ETH(Pending)(Pending)
Bridge With Perm...215333292025-01-02 0:54:2336 mins ago1735779263IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.0086634432.03701113
Bridge With Perm...215255962024-12-31 23:00:3526 hrs ago1735686035IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001359025.02562607
Bridge With Perm...215247272024-12-31 20:06:2329 hrs ago1735675583IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001388745.13549563
Bridge With Perm...215179732024-12-30 21:27:232 days ago1735594043IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001832377.23413027
Rescue Funds215149732024-12-30 11:24:352 days ago1735557875IN
0xDf9Fa2b4...0ED37020F
0 ETH0.00025894.01019159
Bridge With Perm...215148322024-12-30 10:56:232 days ago1735556183IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.00134844.9
Bridge With Perm...215145382024-12-30 9:56:592 days ago1735552619IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001013284
Bridge With Perm...215102842024-12-29 19:41:353 days ago1735501295IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001355985.35311679
Bridge With Perm...215088552024-12-29 14:54:473 days ago1735484087IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.002030117.50725916
Bridge With Perm...215075832024-12-29 10:38:353 days ago1735468715IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.000918563.39680808
Bridge With Perm...215073412024-12-29 9:49:593 days ago1735465799IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.000864213.1402305
Bridge With Perm...215072112024-12-29 9:23:593 days ago1735464239IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001027553.8
Bridge With Perm...215042112024-12-28 23:21:594 days ago1735428119IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001032623.81877504
Bridge With Perm...215031722024-12-28 19:52:474 days ago1735415567IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001550725.73449233
Bridge With Perm...215027722024-12-28 18:31:594 days ago1735410719IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001703496.3
Bridge With Perm...215012652024-12-28 13:29:114 days ago1735392551IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001730086.39861422
Bridge With Perm...215001682024-12-28 9:48:354 days ago1735379315IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001225454.45304342
Bridge With Perm...214972882024-12-28 0:10:355 days ago1735344635IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001216944.5
Bridge With Perm...214971932024-12-27 23:51:235 days ago1735343483IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.001201654.44347936
Bridge With Perm...214902882024-12-27 0:42:236 days ago1735260143IN
0xDf9Fa2b4...0ED37020F
0.00033987 ETH0.00126384.67327574
Bridge With Perm...214836682024-12-26 2:30:476 days ago1735180247IN
0xDf9Fa2b4...0ED37020F
0.00022005 ETH0.001351415.2358572
Bridge With Perm...214831982024-12-26 0:55:237 days ago1735174523IN
0xDf9Fa2b4...0ED37020F
0.00021921 ETH0.001289064.76731854
Bridge With Perm...214795232024-12-25 12:35:117 days ago1735130111IN
0xDf9Fa2b4...0ED37020F
0.00027672 ETH0.001068043.94939591
Bridge With Perm...214793482024-12-25 11:59:597 days ago1735127999IN
0xDf9Fa2b4...0ED37020F
0.00027672 ETH0.001106264.09108894
View all transactions

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block
From
To
215333292025-01-02 0:54:2336 mins ago1735779263
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215255962024-12-31 23:00:3526 hrs ago1735686035
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215247272024-12-31 20:06:2329 hrs ago1735675583
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215179732024-12-30 21:27:232 days ago1735594043
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215148322024-12-30 10:56:232 days ago1735556183
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215145382024-12-30 9:56:592 days ago1735552619
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215102842024-12-29 19:41:353 days ago1735501295
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215088552024-12-29 14:54:473 days ago1735484087
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215075832024-12-29 10:38:353 days ago1735468715
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215073412024-12-29 9:49:593 days ago1735465799
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215072112024-12-29 9:23:593 days ago1735464239
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215042112024-12-28 23:21:594 days ago1735428119
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215031722024-12-28 19:52:474 days ago1735415567
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215027722024-12-28 18:31:594 days ago1735410719
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215012652024-12-28 13:29:114 days ago1735392551
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
215001682024-12-28 9:48:354 days ago1735379315
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
214972882024-12-28 0:10:355 days ago1735344635
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
214971932024-12-27 23:51:235 days ago1735343483
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
214902882024-12-27 0:42:236 days ago1735260143
0xDf9Fa2b4...0ED37020F
0.00033987 ETH
214836682024-12-26 2:30:476 days ago1735180247
0xDf9Fa2b4...0ED37020F
0.00022005 ETH
214831982024-12-26 0:55:237 days ago1735174523
0xDf9Fa2b4...0ED37020F
0.00021921 ETH
214795232024-12-25 12:35:117 days ago1735130111
0xDf9Fa2b4...0ED37020F
0.00027672 ETH
214793482024-12-25 11:59:597 days ago1735127999
0xDf9Fa2b4...0ED37020F
0.00027672 ETH
214793272024-12-25 11:55:477 days ago1735127747
0xDf9Fa2b4...0ED37020F
0.00028026 ETH
214780922024-12-25 7:47:477 days ago1735112867
0xDf9Fa2b4...0ED37020F
0.00027882 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
Vault

Compiler Version
v0.8.13+commit.abaa5c0e

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion
File 1 of 16 : Vault.sol
pragma solidity 0.8.13;

import "./Base.sol";
import "../interfaces/IConnector.sol";
import "lib/solmate/src/tokens/ERC20.sol";

/**
 * @title SuperToken
 * @notice A contract which enables bridging a token to its sibling chains.
 * @dev This contract implements ISuperTokenOrVault to support message bridging through IMessageBridge compliant contracts.
 */
contract Vault is Base {
    using SafeTransferLib for ERC20;

    // /**
    //  * @notice constructor for creating a new SuperTokenVault.
    //  * @param token_ token contract address which is to be bridged.
    //  */

    constructor(address token_) Base(token_) {
        bridgeType = token_ == ETH_ADDRESS ? NATIVE_VAULT : ERC20_VAULT;
    }

    /**
     * @notice Bridges tokens between chains.
     * @dev This function allows bridging tokens between different chains.
     * @param receiver_ The address to receive the bridged tokens.
     * @param amount_ The amount of tokens to bridge.
     * @param msgGasLimit_ The gas limit for the execution of the bridging process.
     * @param connector_ The address of the connector contract responsible for the bridge.
     * @param execPayload_ The payload for executing the bridging process on the connector.
     * @param options_ Additional options for the bridging process.
     */
    function bridge(
        address receiver_,
        uint256 amount_,
        uint256 msgGasLimit_,
        address connector_,
        bytes calldata execPayload_,
        bytes calldata options_
    ) public payable nonReentrant {
        (
            TransferInfo memory transferInfo,
            bytes memory postHookData
        ) = _beforeBridge(
                connector_,
                TransferInfo(receiver_, amount_, execPayload_)
            );

        _receiveTokens(transferInfo.amount);

        _afterBridge(
            msgGasLimit_,
            connector_,
            options_,
            postHookData,
            transferInfo
        );
    }

    /**
     * @notice Bridges tokens between chains using permit.
     * @param receiver_  The address to receive the bridged tokens.
     * @param amount_  The amount of tokens to bridge.
     * @param msgGasLimit_  The gas limit for the execution of the bridging process.
     * @param connector_  The address of the connector contract responsible for the bridge.
     * @param execPayload_  The payload for executing the bridging process on the connector.
     * @param options_  Additional options for the bridging process.
     * @param deadline_  The deadline for the permit signature.
     * @param v_  The recovery id of the permit signature.
     * @param r_  The r value of the permit signature.
     * @param s_  The s value of the permit signature.
     */
    function bridgeWithPermit(
        address receiver_,
        uint256 amount_,
        uint256 msgGasLimit_,
        address connector_,
        bytes calldata execPayload_,
        bytes calldata options_,
        uint256 deadline_,
        uint8 v_,
        bytes32 r_,
        bytes32 s_
    ) external payable {
        ERC20(token).permit(
            msg.sender,
            address(this),
            amount_,
            deadline_,
            v_,
            r_,
            s_
        );
        bridge(
            receiver_,
            amount_,
            msgGasLimit_,
            connector_,
            execPayload_,
            options_
        );
    }

    /**
     * @notice Receives inbound tokens from another chain.
     * @dev This function is used to receive tokens from another chain.
     * @param siblingChainSlug_ The identifier of the sibling chain.
     * @param payload_ The payload containing the inbound tokens.
     */
    function receiveInbound(
        uint32 siblingChainSlug_,
        bytes memory payload_
    ) external payable override nonReentrant {
        (
            address receiver,
            uint256 unlockAmount,
            bytes32 messageId,
            bytes memory extraData
        ) = abi.decode(payload_, (address, uint256, bytes32, bytes));

        TransferInfo memory transferInfo = TransferInfo(
            receiver,
            unlockAmount,
            extraData
        );

        bytes memory postHookData;
        (postHookData, transferInfo) = _beforeMint(
            siblingChainSlug_,
            transferInfo
        );

        _transferTokens(transferInfo.receiver, transferInfo.amount);

        _afterMint(unlockAmount, messageId, postHookData, transferInfo);
    }

    /**
     * @notice Retry a failed transaction.
     * @dev This function allows retrying a failed transaction sent through a connector.
     * @param connector_ The address of the connector contract responsible for the failed transaction.
     * @param messageId_ The unique identifier of the failed transaction.
     */
    function retry(
        address connector_,
        bytes32 messageId_
    ) external nonReentrant {
        (
            bytes memory postRetryHookData,
            TransferInfo memory transferInfo
        ) = _beforeRetry(connector_, messageId_);
        _transferTokens(transferInfo.receiver, transferInfo.amount);

        _afterRetry(connector_, messageId_, postRetryHookData);
    }

    function disperseRewards(
        address receiver_,
        uint256 amount_,
        address rewardToken_
    ) external onlyOwner {
        if (rewardToken_ == token)
            revert("Vault: reward token is same as token");
        ERC20(rewardToken_).safeTransfer(receiver_, amount_);
    }
    function _transferTokens(address receiver_, uint256 amount_) internal {
        if (amount_ == 0) return;
        if (address(token) == ETH_ADDRESS) {
            SafeTransferLib.safeTransferETH(receiver_, amount_);
        } else {
            ERC20(token).safeTransfer(receiver_, amount_);
        }
    }

    function _receiveTokens(uint256 amount_) internal {
        if (amount_ == 0 || address(token) == ETH_ADDRESS) return;
        ERC20(token).safeTransferFrom(msg.sender, address(this), amount_);
    }
}

File 2 of 16 : Base.sol
pragma solidity 0.8.13;

import {IMintableERC20} from "../interfaces/IMintableERC20.sol";
import {IConnector} from "../interfaces/IConnector.sol";
import "lib/solmate/src/utils/SafeTransferLib.sol";
import "../interfaces/IHook.sol";
import "../common/Errors.sol";
import "lib/solmate/src/utils/ReentrancyGuard.sol";
import "../interfaces/IBridge.sol";
import "../utils/RescueBase.sol";
import "../common/Constants.sol";

abstract contract Base is ReentrancyGuard, IBridge, RescueBase {
    address public immutable token;
    bytes32 public bridgeType;
    IHook public hook__;
    // message identifier => cache
    mapping(bytes32 => bytes) public identifierCache;

    // connector => cache
    mapping(address => bytes) public connectorCache;

    mapping(address => bool) public validConnectors;

    event ConnectorStatusUpdated(address connector, bool status);

    event HookUpdated(address newHook);

    event BridgingTokens(
        address connector,
        address sender,
        address receiver,
        uint256 amount,
        bytes32 messageId
    );
    event TokensBridged(
        address connecter,
        address receiver,
        uint256 amount,
        bytes32 messageId
    );
    constructor(address token_) AccessControl(msg.sender) {
        if (token_ != ETH_ADDRESS && token_.code.length == 0)
            revert InvalidTokenContract();
        token = token_;
        _grantRole(RESCUE_ROLE, msg.sender);
    }

    /**
     * @notice this function is used to update hook
     * @dev it can only be updated by owner
     * @dev should be carefully migrated as it can risk user funds
     * @param hook_ new hook address
     */
    function updateHook(
        address hook_,
        bool approve_
    ) external virtual onlyOwner {
        // remove the approval from the old hook
        if (token != ETH_ADDRESS) {
            if (ERC20(token).allowance(address(this), address(hook__)) > 0) {
                SafeTransferLib.safeApprove(ERC20(token), address(hook__), 0);
            }
            if (approve_) {
                SafeTransferLib.safeApprove(
                    ERC20(token),
                    hook_,
                    type(uint256).max
                );
            }
        }
        hook__ = IHook(hook_);

        emit HookUpdated(hook_);
    }

    function updateConnectorStatus(
        address[] calldata connectors,
        bool[] calldata statuses
    ) external onlyOwner {
        uint256 length = connectors.length;
        for (uint256 i; i < length; i++) {
            validConnectors[connectors[i]] = statuses[i];
            emit ConnectorStatusUpdated(connectors[i], statuses[i]);
        }
    }

    /**
     * @notice Executes pre-bridge operations before initiating a token bridge transfer.
     * @dev This internal function is called before initiating a token bridge transfer.
     * It validates the receiver address and the connector, and if a pre-hook contract is defined,
     * it executes the source pre-hook call.
     * @param connector_ The address of the connector responsible for the transfer.
     * @param transferInfo_ Information about the transfer.
     * @return transferInfo Information about the transfer after pre-bridge operations.
     * @return postHookData Data returned from the pre-hook call.
     * @dev Reverts with `ZeroAddressReceiver` if the receiver address is zero.
     * Reverts with `InvalidConnector` if the connector address is not valid.
     */
    function _beforeBridge(
        address connector_,
        TransferInfo memory transferInfo_
    )
        internal
        returns (TransferInfo memory transferInfo, bytes memory postHookData)
    {
        if (transferInfo_.receiver == address(0)) revert ZeroAddressReceiver();
        if (!validConnectors[connector_]) revert InvalidConnector();
        if (token == ETH_ADDRESS && msg.value < transferInfo_.amount)
            revert InsufficientMsgValue();

        if (address(hook__) != address(0)) {
            (transferInfo, postHookData) = hook__.srcPreHookCall(
                SrcPreHookCallParams(connector_, msg.sender, transferInfo_)
            );
        }
    }

    /**
     * @notice Executes post-bridge operations after completing a token bridge transfer.
     * @dev This internal function is called after completing a token bridge transfer.
     * It executes the source post-hook call if a hook contract is defined, calculates fees,
     * calls the outbound function of the connector, and emits an event for tokens withdrawn.
     * @param msgGasLimit_ The gas limit for the outbound call.
     * @param connector_ The address of the connector responsible for the transfer.
     * @param options_ Additional options for the outbound call.
     * @param postSrcHookData_ Data returned from the source post-hook call.
     * @param transferInfo_ Information about the transfer.
     * @dev Reverts with `MessageIdMisMatched` if the returned message ID does not match the expected message ID.
     */
    function _afterBridge(
        uint256 msgGasLimit_,
        address connector_,
        bytes memory options_,
        bytes memory postSrcHookData_,
        TransferInfo memory transferInfo_
    ) internal {
        TransferInfo memory transferInfo = transferInfo_;
        if (address(hook__) != address(0)) {
            transferInfo = hook__.srcPostHookCall(
                SrcPostHookCallParams(
                    connector_,
                    options_,
                    postSrcHookData_,
                    transferInfo_
                )
            );
        }

        uint256 fees = token == ETH_ADDRESS
            ? msg.value - transferInfo.amount
            : msg.value;

        bytes32 messageId = IConnector(connector_).getMessageId();
        bytes32 returnedMessageId = IConnector(connector_).outbound{
            value: fees
        }(
            msgGasLimit_,
            abi.encode(
                transferInfo.receiver,
                transferInfo.amount,
                messageId,
                transferInfo.data
            ),
            options_
        );
        if (returnedMessageId != messageId) revert MessageIdMisMatched();

        emit BridgingTokens(
            connector_,
            msg.sender,
            transferInfo.receiver,
            transferInfo.amount,
            messageId
        );
    }

    /**
     * @notice Executes pre-mint operations before minting tokens.
     * @dev This internal function is called before minting tokens.
     * It validates the caller as a valid connector, checks if the receiver is not this contract, the bridge contract,
     * or the token contract, and executes the destination pre-hook call if a hook contract is defined.
     * @param transferInfo_ Information about the transfer.
     * @return postHookData Data returned from the destination pre-hook call.
     * @return transferInfo Information about the transfer after pre-mint operations.
     * @dev Reverts with `InvalidConnector` if the caller is not a valid connector.
     * Reverts with `CannotTransferOrExecuteOnBridgeContracts` if the receiver is this contract, the bridge contract,
     * or the token contract.
     */
    function _beforeMint(
        uint32,
        TransferInfo memory transferInfo_
    )
        internal
        returns (bytes memory postHookData, TransferInfo memory transferInfo)
    {
        if (!validConnectors[msg.sender]) revert InvalidConnector();

        // no need of source check here, as if invalid caller, will revert with InvalidPoolId
        if (
            transferInfo_.receiver == address(this) ||
            // transferInfo_.receiver == address(bridge__) ||
            transferInfo_.receiver == token
        ) revert CannotTransferOrExecuteOnBridgeContracts();

        if (address(hook__) != address(0)) {
            (postHookData, transferInfo) = hook__.dstPreHookCall(
                DstPreHookCallParams(
                    msg.sender,
                    connectorCache[msg.sender],
                    transferInfo_
                )
            );
        }
    }

    /**
     * @notice Executes post-mint operations after minting tokens.
     * @dev This internal function is called after minting tokens.
     * It executes the destination post-hook call if a hook contract is defined and updates cache data.
     * @param messageId_ The unique identifier for the mint transaction.
     * @param postHookData_ Data returned from the destination pre-hook call.
     * @param transferInfo_ Information about the mint transaction.
     */
    function _afterMint(
        uint256,
        bytes32 messageId_,
        bytes memory postHookData_,
        TransferInfo memory transferInfo_
    ) internal {
        if (address(hook__) != address(0)) {
            CacheData memory cacheData = hook__.dstPostHookCall(
                DstPostHookCallParams(
                    msg.sender,
                    messageId_,
                    connectorCache[msg.sender],
                    postHookData_,
                    transferInfo_
                )
            );

            identifierCache[messageId_] = cacheData.identifierCache;
            connectorCache[msg.sender] = cacheData.connectorCache;
        }

        emit TokensBridged(
            msg.sender,
            transferInfo_.receiver,
            transferInfo_.amount,
            messageId_
        );
    }

    /**
     * @notice Executes pre-retry operations before retrying a failed transaction.
     * @dev This internal function is called before retrying a failed transaction.
     * It validates the connector, retrieves cache data for the given message ID,
     * and executes the pre-retry hook if defined.
     * @param connector_ The address of the connector responsible for the failed transaction.
     * @param messageId_ The unique identifier for the failed transaction.
     * @return postRetryHookData Data returned from the pre-retry hook call.
     * @return transferInfo Information about the transfer.
     * @dev Reverts with `InvalidConnector` if the connector is not valid.
     * Reverts with `NoPendingData` if there is no pending data for the given message ID.
     */
    function _beforeRetry(
        address connector_,
        bytes32 messageId_
    )
        internal
        returns (
            bytes memory postRetryHookData,
            TransferInfo memory transferInfo
        )
    {
        if (!validConnectors[connector_]) revert InvalidConnector();

        CacheData memory cacheData = CacheData(
            identifierCache[messageId_],
            connectorCache[connector_]
        );

        if (cacheData.identifierCache.length == 0) revert NoPendingData();
        (postRetryHookData, transferInfo) = hook__.preRetryHook(
            PreRetryHookCallParams(connector_, cacheData)
        );
    }

    /**
     * @notice Executes post-retry operations after retrying a failed transaction.
     * @dev This internal function is called after retrying a failed transaction.
     * It retrieves cache data for the given message ID, executes the post-retry hook if defined,
     * and updates cache data.
     * @param connector_ The address of the connector responsible for the failed transaction.
     * @param messageId_ The unique identifier for the failed transaction.
     * @param postRetryHookData Data returned from the pre-retry hook call.
     */
    function _afterRetry(
        address connector_,
        bytes32 messageId_,
        bytes memory postRetryHookData
    ) internal {
        CacheData memory cacheData = CacheData(
            identifierCache[messageId_],
            connectorCache[connector_]
        );

        (cacheData) = hook__.postRetryHook(
            PostRetryHookCallParams(
                connector_,
                messageId_,
                postRetryHookData,
                cacheData
            )
        );
        identifierCache[messageId_] = cacheData.identifierCache;
        connectorCache[connector_] = cacheData.connectorCache;
    }

    /**
     * @notice Retrieves the minimum fees required for a transaction from a connector.
     * @dev This function returns the minimum fees required for a transaction from the specified connector,
     * based on the provided message gas limit and payload size.
     * @param connector_ The address of the connector.
     * @param msgGasLimit_ The gas limit for the transaction.
     * @param payloadSize_ The size of the payload for the transaction.
     * @return totalFees The total minimum fees required for the transaction.
     */
    function getMinFees(
        address connector_,
        uint256 msgGasLimit_,
        uint256 payloadSize_
    ) external view returns (uint256 totalFees) {
        return IConnector(connector_).getMinFees(msgGasLimit_, payloadSize_);
    }
}

File 3 of 16 : Constants.sol
pragma solidity 0.8.13;

address constant ETH_ADDRESS = address(
    0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
);

bytes32 constant NORMAL_CONTROLLER = keccak256("NORMAL_CONTROLLER");
bytes32 constant FIAT_TOKEN_CONTROLLER = keccak256("FIAT_TOKEN_CONTROLLER");

bytes32 constant LIMIT_HOOK = keccak256("LIMIT_HOOK");
bytes32 constant LIMIT_EXECUTION_HOOK = keccak256("LIMIT_EXECUTION_HOOK");
bytes32 constant LIMIT_EXECUTION_YIELD_HOOK = keccak256(
    "LIMIT_EXECUTION_YIELD_HOOK"
);
bytes32 constant LIMIT_EXECUTION_YIELD_TOKEN_HOOK = keccak256(
    "LIMIT_EXECUTION_YIELD_TOKEN_HOOK"
);

bytes32 constant ERC20_VAULT = keccak256("ERC20_VAULT");
bytes32 constant NATIVE_VAULT = keccak256("NATIVE_VAULT");

File 4 of 16 : Errors.sol
pragma solidity 0.8.13;

error SiblingNotSupported();
error NotAuthorized();
error NotBridge();
error NotSocket();
error ConnectorUnavailable();
error InvalidPoolId();
error CannotTransferOrExecuteOnBridgeContracts();
error NoPendingData();
error MessageIdMisMatched();
error NotMessageBridge();
error InvalidSiblingChainSlug();
error InvalidTokenContract();
error InvalidExchangeRateContract();
error InvalidConnector();
error InvalidConnectorPoolId();
error ZeroAddressReceiver();
error ZeroAddress();
error ZeroAmount();
error DebtRatioTooHigh();
error NotEnoughAssets();
error VaultShutdown();
error InsufficientFunds();
error PermitDeadlineExpired();
error InvalidSigner();
error InsufficientMsgValue();

File 5 of 16 : Structs.sol
pragma solidity 0.8.13;

struct UpdateLimitParams {
    bool isMint;
    address connector;
    uint256 maxLimit;
    uint256 ratePerSecond;
}

struct SrcPreHookCallParams {
    address connector;
    address msgSender;
    TransferInfo transferInfo;
}

struct SrcPostHookCallParams {
    address connector;
    bytes options;
    bytes postSrcHookData;
    TransferInfo transferInfo;
}

struct DstPreHookCallParams {
    address connector;
    bytes connectorCache;
    TransferInfo transferInfo;
}

struct DstPostHookCallParams {
    address connector;
    bytes32 messageId;
    bytes connectorCache;
    bytes postHookData;
    TransferInfo transferInfo;
}

struct PreRetryHookCallParams {
    address connector;
    CacheData cacheData;
}

struct PostRetryHookCallParams {
    address connector;
    bytes32 messageId;
    bytes postRetryHookData;
    CacheData cacheData;
}

struct TransferInfo {
    address receiver;
    uint256 amount;
    bytes data;
}

struct CacheData {
    bytes identifierCache;
    bytes connectorCache;
}

struct LimitParams {
    uint256 lastUpdateTimestamp;
    uint256 ratePerSecond;
    uint256 maxLimit;
    uint256 lastUpdateLimit;
}

File 6 of 16 : IBridge.sol
pragma solidity ^0.8.3;

interface IBridge {
    function bridge(
        address receiver_,
        uint256 amount_,
        uint256 msgGasLimit_,
        address connector_,
        bytes calldata execPayload_,
        bytes calldata options_
    ) external payable;

    function receiveInbound(
        uint32 siblingChainSlug_,
        bytes memory payload_
    ) external payable;

    function retry(address connector_, bytes32 messageId_) external;
}

File 7 of 16 : IConnector.sol
pragma solidity ^0.8.13;

interface IConnector {
    function outbound(
        uint256 msgGasLimit_,
        bytes memory payload_,
        bytes memory options_
    ) external payable returns (bytes32 messageId_);

    function siblingChainSlug() external view returns (uint32);

    function getMinFees(
        uint256 msgGasLimit_,
        uint256 payloadSize_
    ) external view returns (uint256 totalFees);

    function getMessageId() external view returns (bytes32);
}

File 8 of 16 : IHook.sol
pragma solidity ^0.8.3;
import "../common/Structs.sol";

interface IHook {
    /**
     * @notice Executes pre-hook call for source underlyingAsset.
     * @dev This function is used to execute a pre-hook call for the source underlyingAsset before initiating a transfer.
     * @param params_ Parameters for the pre-hook call.
     * @return transferInfo Information about the transfer.
     * @return postSrcHookData returned from the pre-hook call.
     */
    function srcPreHookCall(
        SrcPreHookCallParams calldata params_
    )
        external
        returns (
            TransferInfo memory transferInfo,
            bytes memory postSrcHookData
        );

    function srcPostHookCall(
        SrcPostHookCallParams calldata params_
    ) external returns (TransferInfo memory transferInfo);

    /**
     * @notice Executes pre-hook call for destination underlyingAsset.
     * @dev This function is used to execute a pre-hook call for the destination underlyingAsset before initiating a transfer.
     * @param params_ Parameters for the pre-hook call.
     */
    function dstPreHookCall(
        DstPreHookCallParams calldata params_
    )
        external
        returns (bytes memory postHookData, TransferInfo memory transferInfo);

    /**
     * @notice Executes post-hook call for destination underlyingAsset.
     * @dev This function is used to execute a post-hook call for the destination underlyingAsset after completing a transfer.
     * @param params_ Parameters for the post-hook call.
     * @return cacheData Cached data for the post-hook call.
     */
    function dstPostHookCall(
        DstPostHookCallParams calldata params_
    ) external returns (CacheData memory cacheData);

    /**
     * @notice Executes a pre-retry hook for a failed transaction.
     * @dev This function is used to execute a pre-retry hook for a failed transaction.
     * @param params_ Parameters for the pre-retry hook.
     * @return postRetryHookData Data from the post-retry hook.
     * @return transferInfo Information about the transfer.
     */
    function preRetryHook(
        PreRetryHookCallParams calldata params_
    )
        external
        returns (
            bytes memory postRetryHookData,
            TransferInfo memory transferInfo
        );

    /**
     * @notice Executes a post-retry hook for a failed transaction.
     * @dev This function is used to execute a post-retry hook for a failed transaction.
     * @param params_ Parameters for the post-retry hook.
     * @return cacheData Cached data for the post-retry hook.
     */
    function postRetryHook(
        PostRetryHookCallParams calldata params_
    ) external returns (CacheData memory cacheData);
}

File 9 of 16 : IMintableERC20.sol
pragma solidity 0.8.13;

interface IMintableERC20 {
    function mint(address receiver_, uint256 amount_) external;

    function burn(address burner_, uint256 amount_) external;
}

File 10 of 16 : RescueFundsLib.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.13;

import "lib/solmate/src/utils/SafeTransferLib.sol";
import "lib/solmate/src/tokens/ERC20.sol";

error ZeroAddress();

/**
 * @title RescueFundsLib
 * @dev A library that provides a function to rescue funds from a contract.
 */

library RescueFundsLib {
    /**
     * @dev The address used to identify ETH.
     */
    address public constant ETH_ADDRESS =
        address(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);

    /**
     * @dev thrown when the given token address don't have any code
     */
    error InvalidTokenAddress();

    /**
     * @dev Rescues funds from a contract.
     * @param token_ The address of the token contract.
     * @param rescueTo_ The address of the user.
     * @param amount_ The amount of tokens to be rescued.
     */
    function rescueFunds(
        address token_,
        address rescueTo_,
        uint256 amount_
    ) internal {
        if (rescueTo_ == address(0)) revert ZeroAddress();

        if (token_ == ETH_ADDRESS) {
            SafeTransferLib.safeTransferETH(rescueTo_, amount_);
        } else {
            if (token_.code.length == 0) revert InvalidTokenAddress();
            SafeTransferLib.safeTransfer(ERC20(token_), rescueTo_, amount_);
        }
    }
}

File 11 of 16 : AccessControl.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.13;

import "./Ownable.sol";

/**
 * @title AccessControl
 * @dev This abstract contract implements access control mechanism based on roles.
 * Each role can have one or more addresses associated with it, which are granted
 * permission to execute functions with the onlyRole modifier.
 */
abstract contract AccessControl is Ownable {
    /**
     * @dev A mapping of roles to a mapping of addresses to boolean values indicating whether or not they have the role.
     */
    mapping(bytes32 => mapping(address => bool)) private _permits;

    /**
     * @dev Emitted when a role is granted to an address.
     */
    event RoleGranted(bytes32 indexed role, address indexed grantee);

    /**
     * @dev Emitted when a role is revoked from an address.
     */
    event RoleRevoked(bytes32 indexed role, address indexed revokee);

    /**
     * @dev Error message thrown when an address does not have permission to execute a function with onlyRole modifier.
     */
    error NoPermit(bytes32 role);

    /**
     * @dev Constructor that sets the owner of the contract.
     */
    constructor(address owner_) Ownable(owner_) {}

    /**
     * @dev Modifier that restricts access to addresses having roles
     * Throws an error if the caller do not have permit
     */
    modifier onlyRole(bytes32 role) {
        if (!_permits[role][msg.sender]) revert NoPermit(role);
        _;
    }

    /**
     * @dev Checks and reverts if an address do not have a specific role.
     * @param role_ The role to check.
     * @param address_ The address to check.
     */
    function _checkRole(bytes32 role_, address address_) internal virtual {
        if (!_hasRole(role_, address_)) revert NoPermit(role_);
    }

    /**
     * @dev Grants a role to a given address.
     * @param role_ The role to grant.
     * @param grantee_ The address to grant the role to.
     * Emits a RoleGranted event.
     * Can only be called by the owner of the contract.
     */
    function grantRole(
        bytes32 role_,
        address grantee_
    ) external virtual onlyOwner {
        _grantRole(role_, grantee_);
    }

    /**
     * @dev Revokes a role from a given address.
     * @param role_ The role to revoke.
     * @param revokee_ The address to revoke the role from.
     * Emits a RoleRevoked event.
     * Can only be called by the owner of the contract.
     */
    function revokeRole(
        bytes32 role_,
        address revokee_
    ) external virtual onlyOwner {
        _revokeRole(role_, revokee_);
    }

    /**
     * @dev Internal function to grant a role to a given address.
     * @param role_ The role to grant.
     * @param grantee_ The address to grant the role to.
     * Emits a RoleGranted event.
     */
    function _grantRole(bytes32 role_, address grantee_) internal {
        _permits[role_][grantee_] = true;
        emit RoleGranted(role_, grantee_);
    }

    /**
     * @dev Internal function to revoke a role from a given address.
     * @param role_ The role to revoke.
     * @param revokee_ The address to revoke the role from.
     * Emits a RoleRevoked event.
     */
    function _revokeRole(bytes32 role_, address revokee_) internal {
        _permits[role_][revokee_] = false;
        emit RoleRevoked(role_, revokee_);
    }

    /**
     * @dev Checks whether an address has a specific role.
     * @param role_ The role to check.
     * @param address_ The address to check.
     * @return A boolean value indicating whether or not the address has the role.
     */
    function hasRole(
        bytes32 role_,
        address address_
    ) external view returns (bool) {
        return _hasRole(role_, address_);
    }

    function _hasRole(
        bytes32 role_,
        address address_
    ) internal view returns (bool) {
        return _permits[role_][address_];
    }
}

File 12 of 16 : Ownable.sol
// SPDX-License-Identifier: GPL-3.0-only
pragma solidity 0.8.13;

/**
 * @title Ownable
 * @dev The Ownable contract provides a simple way to manage ownership of a contract
 * and allows for ownership to be transferred to a nominated address.
 */
abstract contract Ownable {
    address private _owner;
    address private _nominee;

    event OwnerNominated(address indexed nominee);
    event OwnerClaimed(address indexed claimer);

    error OnlyOwner();
    error OnlyNominee();

    /**
     * @dev Sets the contract's owner to the address that is passed to the constructor.
     */
    constructor(address owner_) {
        _claimOwner(owner_);
    }

    /**
     * @dev Modifier that restricts access to only the contract's owner.
     * Throws an error if the caller is not the owner.
     */
    modifier onlyOwner() {
        if (msg.sender != _owner) revert OnlyOwner();
        _;
    }

    /**
     * @dev Returns the current owner of the contract.
     */
    function owner() external view returns (address) {
        return _owner;
    }

    /**
     * @dev Returns the current nominee for ownership of the contract.
     */
    function nominee() external view returns (address) {
        return _nominee;
    }

    /**
     * @dev Allows the current owner to nominate a new owner for the contract.
     * Throws an error if the caller is not the owner.
     * Emits an `OwnerNominated` event with the address of the nominee.
     */
    function nominateOwner(address nominee_) external {
        if (msg.sender != _owner) revert OnlyOwner();
        _nominee = nominee_;
        emit OwnerNominated(_nominee);
    }

    /**
     * @dev Allows the nominated owner to claim ownership of the contract.
     * Throws an error if the caller is not the nominee.
     * Sets the nominated owner as the new owner of the contract.
     * Emits an `OwnerClaimed` event with the address of the new owner.
     */
    function claimOwner() external {
        if (msg.sender != _nominee) revert OnlyNominee();
        _claimOwner(msg.sender);
    }

    /**
     * @dev Internal function that sets the owner of the contract to the specified address
     * and sets the nominee to address(0).
     */
    function _claimOwner(address claimer_) internal {
        _owner = claimer_;
        _nominee = address(0);
        emit OwnerClaimed(claimer_);
    }
}

File 13 of 16 : RescueBase.sol
// SPDX-License-Identifier: MIT
pragma solidity 0.8.13;
import {RescueFundsLib} from "../libraries/RescueFundsLib.sol";
import {AccessControl} from "./AccessControl.sol";

/**
 * @title Base contract for super token and vault
 * @notice It contains relevant execution payload storages.
 * @dev This contract implements Socket's IPlug to enable message bridging and IMessageBridge
 * to support any type of message bridge.
 */
abstract contract RescueBase is AccessControl {
    bytes32 constant RESCUE_ROLE = keccak256("RESCUE_ROLE");

    /**
     * @notice Rescues funds from the contract if they are locked by mistake.
     * @param token_ The address of the token contract.
     * @param rescueTo_ The address where rescued tokens need to be sent.
     * @param amount_ The amount of tokens to be rescued.
     */
    function rescueFunds(
        address token_,
        address rescueTo_,
        uint256 amount_
    ) external onlyRole(RESCUE_ROLE) {
        RescueFundsLib.rescueFunds(token_, rescueTo_, amount_);
    }
}

File 14 of 16 : ERC20.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Modern and gas efficient ERC20 + EIP-2612 implementation.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol)
/// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol)
/// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it.
abstract contract ERC20 {
    /*//////////////////////////////////////////////////////////////
                                 EVENTS
    //////////////////////////////////////////////////////////////*/

    event Transfer(address indexed from, address indexed to, uint256 amount);

    event Approval(address indexed owner, address indexed spender, uint256 amount);

    /*//////////////////////////////////////////////////////////////
                            METADATA STORAGE
    //////////////////////////////////////////////////////////////*/

    string public name;

    string public symbol;

    uint8 public immutable decimals;

    /*//////////////////////////////////////////////////////////////
                              ERC20 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 public totalSupply;

    mapping(address => uint256) public balanceOf;

    mapping(address => mapping(address => uint256)) public allowance;

    /*//////////////////////////////////////////////////////////////
                            EIP-2612 STORAGE
    //////////////////////////////////////////////////////////////*/

    uint256 internal immutable INITIAL_CHAIN_ID;

    bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR;

    mapping(address => uint256) public nonces;

    /*//////////////////////////////////////////////////////////////
                               CONSTRUCTOR
    //////////////////////////////////////////////////////////////*/

    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals
    ) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;

        INITIAL_CHAIN_ID = block.chainid;
        INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator();
    }

    /*//////////////////////////////////////////////////////////////
                               ERC20 LOGIC
    //////////////////////////////////////////////////////////////*/

    function approve(address spender, uint256 amount) public virtual returns (bool) {
        allowance[msg.sender][spender] = amount;

        emit Approval(msg.sender, spender, amount);

        return true;
    }

    function transfer(address to, uint256 amount) public virtual returns (bool) {
        balanceOf[msg.sender] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(msg.sender, to, amount);

        return true;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals.

        if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount;

        balanceOf[from] -= amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(from, to, amount);

        return true;
    }

    /*//////////////////////////////////////////////////////////////
                             EIP-2612 LOGIC
    //////////////////////////////////////////////////////////////*/

    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED");

        // Unchecked because the only math done is incrementing
        // the owner's nonce which cannot realistically overflow.
        unchecked {
            address recoveredAddress = ecrecover(
                keccak256(
                    abi.encodePacked(
                        "\x19\x01",
                        DOMAIN_SEPARATOR(),
                        keccak256(
                            abi.encode(
                                keccak256(
                                    "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)"
                                ),
                                owner,
                                spender,
                                value,
                                nonces[owner]++,
                                deadline
                            )
                        )
                    )
                ),
                v,
                r,
                s
            );

            require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER");

            allowance[recoveredAddress][spender] = value;
        }

        emit Approval(owner, spender, value);
    }

    function DOMAIN_SEPARATOR() public view virtual returns (bytes32) {
        return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator();
    }

    function computeDomainSeparator() internal view virtual returns (bytes32) {
        return
            keccak256(
                abi.encode(
                    keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                    keccak256(bytes(name)),
                    keccak256("1"),
                    block.chainid,
                    address(this)
                )
            );
    }

    /*//////////////////////////////////////////////////////////////
                        INTERNAL MINT/BURN LOGIC
    //////////////////////////////////////////////////////////////*/

    function _mint(address to, uint256 amount) internal virtual {
        totalSupply += amount;

        // Cannot overflow because the sum of all user
        // balances can't exceed the max uint256 value.
        unchecked {
            balanceOf[to] += amount;
        }

        emit Transfer(address(0), to, amount);
    }

    function _burn(address from, uint256 amount) internal virtual {
        balanceOf[from] -= amount;

        // Cannot underflow because a user's balance
        // will never be larger than the total supply.
        unchecked {
            totalSupply -= amount;
        }

        emit Transfer(from, address(0), amount);
    }
}

File 15 of 16 : ReentrancyGuard.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

/// @notice Gas optimized reentrancy protection for smart contracts.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/ReentrancyGuard.sol)
/// @author Modified from OpenZeppelin (https://github.com/OpenZeppelin/openzeppelin-contracts/blob/master/contracts/security/ReentrancyGuard.sol)
abstract contract ReentrancyGuard {
    uint256 private locked = 1;

    modifier nonReentrant() virtual {
        require(locked == 1, "REENTRANCY");

        locked = 2;

        _;

        locked = 1;
    }
}

File 16 of 16 : SafeTransferLib.sol
// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;

import {ERC20} from "../tokens/ERC20.sol";

/// @notice Safe ETH and ERC20 transfer library that gracefully handles missing return values.
/// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/utils/SafeTransferLib.sol)
/// @dev Use with caution! Some functions in this library knowingly create dirty bits at the destination of the free memory pointer.
/// @dev Note that none of the functions in this library check that a token has code at all! That responsibility is delegated to the caller.
library SafeTransferLib {
    /*//////////////////////////////////////////////////////////////
                             ETH OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferETH(address to, uint256 amount) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Transfer the ETH and store if it succeeded or not.
            success := call(gas(), to, amount, 0, 0, 0, 0)
        }

        require(success, "ETH_TRANSFER_FAILED");
    }

    /*//////////////////////////////////////////////////////////////
                            ERC20 OPERATIONS
    //////////////////////////////////////////////////////////////*/

    function safeTransferFrom(
        ERC20 token,
        address from,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x23b872dd00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(from, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "from" argument.
            mstore(add(freeMemoryPointer, 36), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 68), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 100 because the length of our calldata totals up like so: 4 + 32 * 3.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 100, 0, 32)
            )
        }

        require(success, "TRANSFER_FROM_FAILED");
    }

    function safeTransfer(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0xa9059cbb00000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "TRANSFER_FAILED");
    }

    function safeApprove(
        ERC20 token,
        address to,
        uint256 amount
    ) internal {
        bool success;

        /// @solidity memory-safe-assembly
        assembly {
            // Get a pointer to some free memory.
            let freeMemoryPointer := mload(0x40)

            // Write the abi-encoded calldata into memory, beginning with the function selector.
            mstore(freeMemoryPointer, 0x095ea7b300000000000000000000000000000000000000000000000000000000)
            mstore(add(freeMemoryPointer, 4), and(to, 0xffffffffffffffffffffffffffffffffffffffff)) // Append and mask the "to" argument.
            mstore(add(freeMemoryPointer, 36), amount) // Append the "amount" argument. Masking not required as it's a full 32 byte type.

            success := and(
                // Set success to whether the call reverted, if not we check it either
                // returned exactly 1 (can't just be non-zero data), or had no return data.
                or(and(eq(mload(0), 1), gt(returndatasize(), 31)), iszero(returndatasize())),
                // We use 68 because the length of our calldata totals up like so: 4 + 32 * 2.
                // We use 0 and 32 to copy up to 32 bytes of return data into the scratch space.
                // Counterintuitively, this call must be positioned second to the or() call in the
                // surrounding and() call or else returndatasize() will be zero during the computation.
                call(gas(), token, 0, freeMemoryPointer, 68, 0, 32)
            )
        }

        require(success, "APPROVE_FAILED");
    }
}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"token_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"CannotTransferOrExecuteOnBridgeContracts","type":"error"},{"inputs":[],"name":"InsufficientMsgValue","type":"error"},{"inputs":[],"name":"InvalidConnector","type":"error"},{"inputs":[],"name":"InvalidTokenAddress","type":"error"},{"inputs":[],"name":"InvalidTokenContract","type":"error"},{"inputs":[],"name":"MessageIdMisMatched","type":"error"},{"inputs":[],"name":"NoPendingData","type":"error"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"NoPermit","type":"error"},{"inputs":[],"name":"OnlyNominee","type":"error"},{"inputs":[],"name":"OnlyOwner","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroAddressReceiver","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"connector","type":"address"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"messageId","type":"bytes32"}],"name":"BridgingTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"connector","type":"address"},{"indexed":false,"internalType":"bool","name":"status","type":"bool"}],"name":"ConnectorStatusUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newHook","type":"address"}],"name":"HookUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"}],"name":"OwnerClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"nominee","type":"address"}],"name":"OwnerNominated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"grantee","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"revokee","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"connecter","type":"address"},{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes32","name":"messageId","type":"bytes32"}],"name":"TokensBridged","type":"event"},{"inputs":[{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint256","name":"msgGasLimit_","type":"uint256"},{"internalType":"address","name":"connector_","type":"address"},{"internalType":"bytes","name":"execPayload_","type":"bytes"},{"internalType":"bytes","name":"options_","type":"bytes"}],"name":"bridge","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"bridgeType","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"uint256","name":"msgGasLimit_","type":"uint256"},{"internalType":"address","name":"connector_","type":"address"},{"internalType":"bytes","name":"execPayload_","type":"bytes"},{"internalType":"bytes","name":"options_","type":"bytes"},{"internalType":"uint256","name":"deadline_","type":"uint256"},{"internalType":"uint8","name":"v_","type":"uint8"},{"internalType":"bytes32","name":"r_","type":"bytes32"},{"internalType":"bytes32","name":"s_","type":"bytes32"}],"name":"bridgeWithPermit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"claimOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"connectorCache","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"address","name":"rewardToken_","type":"address"}],"name":"disperseRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"connector_","type":"address"},{"internalType":"uint256","name":"msgGasLimit_","type":"uint256"},{"internalType":"uint256","name":"payloadSize_","type":"uint256"}],"name":"getMinFees","outputs":[{"internalType":"uint256","name":"totalFees","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"grantee_","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"address_","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hook__","outputs":[{"internalType":"contract IHook","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"identifierCache","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"nominee_","type":"address"}],"name":"nominateOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nominee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"siblingChainSlug_","type":"uint32"},{"internalType":"bytes","name":"payload_","type":"bytes"}],"name":"receiveInbound","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"token_","type":"address"},{"internalType":"address","name":"rescueTo_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"rescueFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"connector_","type":"address"},{"internalType":"bytes32","name":"messageId_","type":"bytes32"}],"name":"retry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role_","type":"bytes32"},{"internalType":"address","name":"revokee_","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"token","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"connectors","type":"address[]"},{"internalType":"bool[]","name":"statuses","type":"bool[]"}],"name":"updateConnectorStatus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"hook_","type":"address"},{"internalType":"bool","name":"approve_","type":"bool"}],"name":"updateHook","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"validConnectors","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60a060405260016000553480156200001657600080fd5b5060405162003a3138038062003a318339810160408190526200003991620001ff565b803380620000478162000150565b50506001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee148015906200007f57506001600160a01b0381163b155b156200009e57604051630a6f7ecd60e21b815260040160405180910390fd5b6001600160a01b038116608052620000d77fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f2925333620001a4565b506001600160a01b03811673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1462000124577f9faa379a8f7762447354a00c30bda6b12f39577783c03b588d3fd75b4e2a587662000146565b7fc13765c06de89a4f07f9e99bf054a9e770fad3efc97eaf120e84faa2f5b76af35b6004555062000231565b600180546001600160a01b0383166001600160a01b031991821681179092556002805490911690556040517ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8790600090a250565b60008281526003602090815260408083206001600160a01b0385168085529252808320805460ff1916600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6000602082840312156200021257600080fd5b81516001600160a01b03811681146200022a57600080fd5b9392505050565b608051613789620002a860003960008181610456015281816104eb01528181610c2e01528181610cce01528181610d4801528181610d9001528181610ebe015281816114a30152818161163e015281816116ac015281816117db01528181611b9201528181611dbe0152611e1c01526137896000f3fe6080604052600436106101755760003560e01c80638da5cb5b116100cb578063d547741f1161007f578063f290aafa11610059578063f290aafa14610424578063fc0c546a14610444578063fc3a7b981461047857600080fd5b8063d547741f146103b4578063e272ad3f146103d4578063e9ee1eaf146103f457600080fd5b80639dc7b023116100b05780639dc7b02314610361578063aad48d8014610381578063b23d5436146103a157600080fd5b80638da5cb5b1461030657806391d148541461033157600080fd5b8063405e720a1161012d5780636ccae054116101075780636ccae054146102a657806370bab2c0146102c6578063873ea755146102f357600080fd5b8063405e720a146102465780634b0a8854146102595780635b94db271461028657600080fd5b80632421e1551161015e5780632421e155146101ed5780632f2ff15d146102115780633bd1adec1461023157600080fd5b8063074729891461017a57806320f99c0a1461019c575b600080fd5b34801561018657600080fd5b5061019a6101953660046129bf565b610498565b005b3480156101a857600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101f957600080fd5b5061020360045481565b6040519081526020016101e4565b34801561021d57600080fd5b5061019a61022c366004612a01565b6105ee565b34801561023d57600080fd5b5061019a61064d565b61019a610254366004612a73565b6106a9565b34801561026557600080fd5b50610279610274366004612b1b565b6107f5565b6040516101e49190612bae565b34801561029257600080fd5b5061019a6102a1366004612b1b565b61088f565b3480156102b257600080fd5b5061019a6102c1366004612bc1565b61094f565b3480156102d257600080fd5b506005546101c39073ffffffffffffffffffffffffffffffffffffffff1681565b61019a610301366004612cc6565b6109ed565b34801561031257600080fd5b5060015473ffffffffffffffffffffffffffffffffffffffff166101c3565b34801561033d57600080fd5b5061035161034c366004612a01565b610af6565b60405190151581526020016101e4565b34801561036d57600080fd5b5061019a61037c366004612d62565b610b31565b34801561038d57600080fd5b5061019a61039c366004612d9e565b610bdb565b61019a6103af366004612de4565b610e50565b3480156103c057600080fd5b5061019a6103cf366004612a01565b610f38565b3480156103e057600080fd5b5061019a6103ef366004612f04565b610f93565b34801561040057600080fd5b5061035161040f366004612b1b565b60086020526000908152604090205460ff1681565b34801561043057600080fd5b5061027961043f366004612f70565b61114d565b34801561045057600080fd5b506101c37f000000000000000000000000000000000000000000000000000000000000000081565b34801561048457600080fd5b50610203610493366004612f89565b611166565b60015473ffffffffffffffffffffffffffffffffffffffff1633146104e9576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036105c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f5661756c743a2072657761726420746f6b656e2069732073616d65206173207460448201527f6f6b656e0000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6105e973ffffffffffffffffffffffffffffffffffffffff82168484611207565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461063f576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61064982826112d6565b5050565b60025473ffffffffffffffffffffffffffffffffffffffff16331461069e576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106a73361135c565b565b600054600114610715576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016105bf565b600260008190555060008061078e8760405180606001604052808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c815260200189898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509152506113d5565b9150915061079f8260200151611634565b6107e4888886868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508792508891506116d79050565b505060016000555050505050505050565b6007602052600090815260409020805461080e90612fbe565b80601f016020809104026020016040519081016040528092919081815260200182805461083a90612fbe565b80156108875780601f1061085c57610100808354040283529160200191610887565b820191906000526020600020905b81548152906001019060200180831161086a57829003601f168201915b505050505081565b60015473ffffffffffffffffffffffffffffffffffffffff1633146108e0576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b3360009081527f271b3e2292ab6fd3ff496cd98d6d375af02f11568a701741f48bba7789f13a7060205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff166109dc576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024016105bf565b6109e7848484611a1c565b50505050565b600054600114610a59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016105bf565b600260008190555060008060008084806020019051810190610a7b9190613056565b9350935093509350600060405180606001604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018381525090506060610ac48883611b0c565b80516020820151919450919250610adb9190611d8f565b610ae785858385611e43565b50506001600055505050505050565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b9392505050565b600054600114610b9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016105bf565b6002600090815580610baf848461207f565b91509150610bc581600001518260200151611d8f565b610bd0848484612387565b505060016000555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c2c576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14610dd6576005546040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91821660248201526000917f0000000000000000000000000000000000000000000000000000000000000000169063dd62ed3e90604401602060405180830381865afa158015610d15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3991906130bb565b1115610d8557600554610d85907f00000000000000000000000000000000000000000000000000000000000000009073ffffffffffffffffffffffffffffffffffffffff166000612642565b8015610dd657610dd67f0000000000000000000000000000000000000000000000000000000000000000837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612642565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040519081527fe816c20840d998c8612f9b624b91687a80510eeb293cb09f7637379f6d73342d9060200160405180910390a15050565b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018c90526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063d505accf9060e401600060405180830381600087803b158015610f0257600080fd5b505af1158015610f16573d6000803e3d6000fd5b50505050610f2a8c8c8c8c8c8c8c8c6106a9565b505050505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f89576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106498282612711565b60015473ffffffffffffffffffffffffffffffffffffffff163314610fe4576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260005b8181101561114557838382818110611002576110026130d4565b90506020020160208101906110179190613103565b6008600088888581811061102d5761102d6130d4565b90506020020160208101906110429190612b1b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790557f857309f1a328784e9fc9749624be5d32fd8e7afab58e7fe9a218dd613a37f15c8686838181106110c8576110c86130d4565b90506020020160208101906110dd9190612b1b565b8585848181106110ef576110ef6130d4565b90506020020160208101906111049190613103565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835290151560208301520160405180910390a18061113d8161314d565b915050610fe8565b505050505050565b6006602052600090815260409020805461080e90612fbe565b6040517f666758ca000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260009073ffffffffffffffffffffffffffffffffffffffff85169063666758ca90604401602060405180830381865afa1580156111db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ff91906130bb565b949350505050565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016105bf565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6001805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff000000000000000000000000000000000000000091821681179092556002805490911690556040517ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8790600090a250565b60408051606080820183526000808352602083015291810191909152815160609073ffffffffffffffffffffffffffffffffffffffff16611442576040517f96bbcf1e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526008602052604090205460ff166114a1576040517f5b0a758300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1480156114fd5750826020015134105b15611534576040517f78f38f7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff161561162d576005546040805160608101825273ffffffffffffffffffffffffffffffffffffffff878116825233602083015281830187905291517ff59ad990000000000000000000000000000000000000000000000000000000008152919092169163f59ad990916115c291906004016131c4565b6000604051808303816000875af11580156115e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526116279190810190613292565b90925090505b9250929050565b80158061168a57507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b156116925750565b6116d473ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084612794565b50565b600554819073ffffffffffffffffffffffffffffffffffffffff16156117d7576005546040805160808101825273ffffffffffffffffffffffffffffffffffffffff8881168252602082018890528183018790526060820186905291517f62811bf200000000000000000000000000000000000000000000000000000000815291909216916362811bf29161176f91906004016132f6565b6000604051808303816000875af115801561178e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526117d49190810190613395565b90505b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14611830573461183f565b602082015161183f90346133ca565b905060008673ffffffffffffffffffffffffffffffffffffffff166374fa24a66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561188e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b291906130bb565b905060008773ffffffffffffffffffffffffffffffffffffffff1663ac0710cb848b87600001518860200151878a604001516040516020016118f794939291906133e1565b6040516020818303038152906040528b6040518563ffffffff1660e01b815260040161192593929190613426565b60206040518083038185885af1158015611943573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061196891906130bb565b90508181146119a3576040517f7b7bbbe000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83516020808601516040805173ffffffffffffffffffffffffffffffffffffffff8d811682523394820194909452929093168284015260608201526080810184905290517fc74a00177d2c63e6eead5ea7936974ad9d0121f86140723b8909f8ec9662cc619181900360a00190a1505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611a69576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff841601611ab0576105e9828261287f565b8273ffffffffffffffffffffffffffffffffffffffff163b600003611b01576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105e9838383611207565b6040805160608181018352600080835260208301529181018290523360009081526008602052604090205460ff16611b70576040517f5b0a758300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825173ffffffffffffffffffffffffffffffffffffffff16301480611be457507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16145b15611c1b576040517f285c601600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff161561162d576005546040805160608101825233808252600090815260076020908152929020805473ffffffffffffffffffffffffffffffffffffffff9094169363cf36b9179383019190611c8790612fbe565b80601f0160208091040260200160405190810160405280929190818152602001828054611cb390612fbe565b8015611d005780601f10611cd557610100808354040283529160200191611d00565b820191906000526020600020905b815481529060010190602001808311611ce357829003601f168201915b50505050508152602001868152506040518263ffffffff1660e01b8152600401611d2a9190613451565b6000604051808303816000875af1158015611d49573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261162791908101906134c8565b80600003611d9b575050565b7fffffffffffffffffffffffff11111111111111111111111111111111111111127f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1601611e0257610649828261287f565b61064973ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000168383611207565b60055473ffffffffffffffffffffffffffffffffffffffff1615612015576005546040805160a0810182523380825260208083018890526000918252600790528281208054919473ffffffffffffffffffffffffffffffffffffffff169363dd19fe3893929083019190611eb690612fbe565b80601f0160208091040260200160405190810160405280929190818152602001828054611ee290612fbe565b8015611f2f5780601f10611f0457610100808354040283529160200191611f2f565b820191906000526020600020905b815481529060010190602001808311611f1257829003601f168201915b50505050508152602001868152602001858152506040518263ffffffff1660e01b8152600401611f5f9190613522565b6000604051808303816000875af1158015611f7e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611fc491908101906135c2565b805160008681526006602090815260409091208251939450611fec93909291909101906128f4565b5060208082015133600090815260078352604090208151612012939192909101906128f4565b50505b80516020808301516040805133815273ffffffffffffffffffffffffffffffffffffffff909416928401929092528282015260608201859052517f9afd47907e25028cdaca89d193518c302bbb128617d5a992c5abd458155265939181900360800190a150505050565b60408051606081810183526000808352602083015291810182905273ffffffffffffffffffffffffffffffffffffffff841660009081526008602052604090205460ff166120f9576040517f5b0a758300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008581526006602052918220805482919061211d90612fbe565b80601f016020809104026020016040519081016040528092919081815260200182805461214990612fbe565b80156121965780601f1061216b57610100808354040283529160200191612196565b820191906000526020600020905b81548152906001019060200180831161217957829003601f168201915b50505050508152602001600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546121ea90612fbe565b80601f016020809104026020016040519081016040528092919081815260200182805461221690612fbe565b80156122635780601f1061223857610100808354040283529160200191612263565b820191906000526020600020905b81548152906001019060200180831161224657829003601f168201915b505050505081525090508060000151516000036122ac576040517fd3d38f6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055460408051808201825273ffffffffffffffffffffffffffffffffffffffff88811682526020820185905291517f7afb99530000000000000000000000000000000000000000000000000000000081529190921691637afb9953916123169190600401613697565b6000604051808303816000875af1158015612335573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261237b91908101906134c8565b90969095509350505050565b6040805180820182526000848152600660205291822080548291906123ab90612fbe565b80601f01602080910402602001604051908101604052809291908181526020018280546123d790612fbe565b80156124245780601f106123f957610100808354040283529160200191612424565b820191906000526020600020905b81548152906001019060200180831161240757829003601f168201915b50505050508152602001600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805461247890612fbe565b80601f01602080910402602001604051908101604052809291908181526020018280546124a490612fbe565b80156124f15780601f106124c6576101008083540402835291602001916124f1565b820191906000526020600020905b8154815290600101906020018083116124d457829003601f168201915b5050509190925250506005546040805160808101825273ffffffffffffffffffffffffffffffffffffffff8881168252602082018890528183018790526060820185905291517f1306ac3b000000000000000000000000000000000000000000000000000000008152939450911691631306ac3b91612572916004016136d2565b6000604051808303816000875af1158015612591573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526125d791908101906135c2565b8051600085815260066020908152604090912082519394506125ff93909291909101906128f4565b5060208082015173ffffffffffffffffffffffffffffffffffffffff861660009081526007835260409020815161263b939192909101906128f4565b5050505050565b60006040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f415050524f56455f4641494c454400000000000000000000000000000000000060448201526064016105bf565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b60006040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015273ffffffffffffffffffffffffffffffffffffffff841660248201528260448201526020600060648360008a5af13d15601f3d116001600051141617169150508061263b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c454400000000000000000000000060448201526064016105bf565b600080600080600085875af19050806105e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016105bf565b82805461290090612fbe565b90600052602060002090601f0160209004810192826129225760008555612968565b82601f1061293b57805160ff1916838001178555612968565b82800160010185558215612968579182015b8281111561296857825182559160200191906001019061294d565b50612974929150612978565b5090565b5b808211156129745760008155600101612979565b73ffffffffffffffffffffffffffffffffffffffff811681146116d457600080fd5b80356129ba8161298d565b919050565b6000806000606084860312156129d457600080fd5b83356129df8161298d565b92506020840135915060408401356129f68161298d565b809150509250925092565b60008060408385031215612a1457600080fd5b823591506020830135612a268161298d565b809150509250929050565b60008083601f840112612a4357600080fd5b50813567ffffffffffffffff811115612a5b57600080fd5b60208301915083602082850101111561162d57600080fd5b60008060008060008060008060c0898b031215612a8f57600080fd5b8835612a9a8161298d565b975060208901359650604089013595506060890135612ab88161298d565b9450608089013567ffffffffffffffff80821115612ad557600080fd5b612ae18c838d01612a31565b909650945060a08b0135915080821115612afa57600080fd5b50612b078b828c01612a31565b999c989b5096995094979396929594505050565b600060208284031215612b2d57600080fd5b8135610b2a8161298d565b60005b83811015612b53578181015183820152602001612b3b565b838111156109e75750506000910152565b60008151808452612b7c816020860160208601612b38565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b2a6020830184612b64565b600080600060608486031215612bd657600080fd5b8335612be18161298d565b92506020840135612bf18161298d565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612c7857612c78612c02565b604052919050565b600067ffffffffffffffff821115612c9a57612c9a612c02565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60008060408385031215612cd957600080fd5b823563ffffffff81168114612ced57600080fd5b9150602083013567ffffffffffffffff811115612d0957600080fd5b8301601f81018513612d1a57600080fd5b8035612d2d612d2882612c80565b612c31565b818152866020838501011115612d4257600080fd5b816020840160208301376000602083830101528093505050509250929050565b60008060408385031215612d7557600080fd5b8235612d808161298d565b946020939093013593505050565b803580151581146129ba57600080fd5b60008060408385031215612db157600080fd5b8235612dbc8161298d565b9150612dca60208401612d8e565b90509250929050565b803560ff811681146129ba57600080fd5b6000806000806000806000806000806000806101408d8f031215612e0757600080fd5b612e108d6129af565b9b5060208d01359a5060408d01359950612e2c60608e016129af565b985067ffffffffffffffff60808e01351115612e4757600080fd5b612e578e60808f01358f01612a31565b909850965067ffffffffffffffff60a08e01351115612e7557600080fd5b612e858e60a08f01358f01612a31565b909650945060c08d01359350612e9d60e08e01612dd3565b92506101008d013591506101208d013590509295989b509295989b509295989b565b60008083601f840112612ed157600080fd5b50813567ffffffffffffffff811115612ee957600080fd5b6020830191508360208260051b850101111561162d57600080fd5b60008060008060408587031215612f1a57600080fd5b843567ffffffffffffffff80821115612f3257600080fd5b612f3e88838901612ebf565b90965094506020870135915080821115612f5757600080fd5b50612f6487828801612ebf565b95989497509550505050565b600060208284031215612f8257600080fd5b5035919050565b600080600060608486031215612f9e57600080fd5b8335612fa98161298d565b95602085013595506040909401359392505050565b600181811c90821680612fd257607f821691505b60208210810361300b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261302257600080fd5b8151613030612d2882612c80565b81815284602083860101111561304557600080fd5b6111ff826020830160208701612b38565b6000806000806080858703121561306c57600080fd5b84516130778161298d565b809450506020850151925060408501519150606085015167ffffffffffffffff8111156130a357600080fd5b6130af87828801613011565b91505092959194509250565b6000602082840312156130cd57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561311557600080fd5b610b2a82612d8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361317e5761317e61311e565b5060010190565b73ffffffffffffffffffffffffffffffffffffffff81511682526020810151602083015260006040820151606060408501526111ff6060850182612b64565b60208152600073ffffffffffffffffffffffffffffffffffffffff8084511660208401528060208501511660408401525060408301516060808401526111ff6080840182613185565b60006060828403121561321f57600080fd5b6040516060810167ffffffffffffffff828210818311171561324357613243612c02565b81604052829350845191506132578261298d565b81835260208501516020840152604085015191508082111561327857600080fd5b5061328585828601613011565b6040830152505092915050565b600080604083850312156132a557600080fd5b825167ffffffffffffffff808211156132bd57600080fd5b6132c98683870161320d565b935060208501519150808211156132df57600080fd5b506132ec85828601613011565b9150509250929050565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516080604084015261333260a0840182612b64565b905060408401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08085840301606086015261336e8383612b64565b925060608601519150808584030160808601525061338c8282613185565b95945050505050565b6000602082840312156133a757600080fd5b815167ffffffffffffffff8111156133be57600080fd5b6111ff8482850161320d565b6000828210156133dc576133dc61311e565b500390565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015282604082015260806060820152600061341c6080830184612b64565b9695505050505050565b83815260606020820152600061343f6060830185612b64565b828103604084015261341c8185612b64565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516060604084015261348d6080840182612b64565b905060408401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301606085015261338c8282613185565b600080604083850312156134db57600080fd5b825167ffffffffffffffff808211156134f357600080fd5b6134ff86838701613011565b9350602085015191508082111561351557600080fd5b506132ec8582860161320d565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152602082015160408201526000604083015160a0606084015261356860c0840182612b64565b905060608401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808584030160808601526135a48383612b64565b925060808601519150808584030160a08601525061338c8282613185565b6000602082840312156135d457600080fd5b815167ffffffffffffffff808211156135ec57600080fd5b908301906040828603121561360057600080fd5b60405160408101818110838211171561361b5761361b612c02565b60405282518281111561362d57600080fd5b61363987828601613011565b82525060208301518281111561364e57600080fd5b61365a87828601613011565b60208301525095945050505050565b600081516040845261367e6040850182612b64565b90506020830151848203602086015261338c8282612b64565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516040808401526111ff6060840182613669565b6020815273ffffffffffffffffffffffffffffffffffffffff825116602082015260208201516040820152600060408301516080606084015261371860a0840182612b64565b905060608401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301608085015261338c828261366956fea26469706673582212208e34317c0cf2a659ddbbbc529df47658c8c9164f4b3d9552505eb1457560312e64736f6c634300080d003300000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc0

Deployed Bytecode

0x6080604052600436106101755760003560e01c80638da5cb5b116100cb578063d547741f1161007f578063f290aafa11610059578063f290aafa14610424578063fc0c546a14610444578063fc3a7b981461047857600080fd5b8063d547741f146103b4578063e272ad3f146103d4578063e9ee1eaf146103f457600080fd5b80639dc7b023116100b05780639dc7b02314610361578063aad48d8014610381578063b23d5436146103a157600080fd5b80638da5cb5b1461030657806391d148541461033157600080fd5b8063405e720a1161012d5780636ccae054116101075780636ccae054146102a657806370bab2c0146102c6578063873ea755146102f357600080fd5b8063405e720a146102465780634b0a8854146102595780635b94db271461028657600080fd5b80632421e1551161015e5780632421e155146101ed5780632f2ff15d146102115780633bd1adec1461023157600080fd5b8063074729891461017a57806320f99c0a1461019c575b600080fd5b34801561018657600080fd5b5061019a6101953660046129bf565b610498565b005b3480156101a857600080fd5b5060025473ffffffffffffffffffffffffffffffffffffffff165b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b3480156101f957600080fd5b5061020360045481565b6040519081526020016101e4565b34801561021d57600080fd5b5061019a61022c366004612a01565b6105ee565b34801561023d57600080fd5b5061019a61064d565b61019a610254366004612a73565b6106a9565b34801561026557600080fd5b50610279610274366004612b1b565b6107f5565b6040516101e49190612bae565b34801561029257600080fd5b5061019a6102a1366004612b1b565b61088f565b3480156102b257600080fd5b5061019a6102c1366004612bc1565b61094f565b3480156102d257600080fd5b506005546101c39073ffffffffffffffffffffffffffffffffffffffff1681565b61019a610301366004612cc6565b6109ed565b34801561031257600080fd5b5060015473ffffffffffffffffffffffffffffffffffffffff166101c3565b34801561033d57600080fd5b5061035161034c366004612a01565b610af6565b60405190151581526020016101e4565b34801561036d57600080fd5b5061019a61037c366004612d62565b610b31565b34801561038d57600080fd5b5061019a61039c366004612d9e565b610bdb565b61019a6103af366004612de4565b610e50565b3480156103c057600080fd5b5061019a6103cf366004612a01565b610f38565b3480156103e057600080fd5b5061019a6103ef366004612f04565b610f93565b34801561040057600080fd5b5061035161040f366004612b1b565b60086020526000908152604090205460ff1681565b34801561043057600080fd5b5061027961043f366004612f70565b61114d565b34801561045057600080fd5b506101c37f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc081565b34801561048457600080fd5b50610203610493366004612f89565b611166565b60015473ffffffffffffffffffffffffffffffffffffffff1633146104e9576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036105c8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f5661756c743a2072657761726420746f6b656e2069732073616d65206173207460448201527f6f6b656e0000000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6105e973ffffffffffffffffffffffffffffffffffffffff82168484611207565b505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461063f576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61064982826112d6565b5050565b60025473ffffffffffffffffffffffffffffffffffffffff16331461069e576040517f7c91ccdd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106a73361135c565b565b600054600114610715576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016105bf565b600260008190555060008061078e8760405180606001604052808d73ffffffffffffffffffffffffffffffffffffffff1681526020018c815260200189898080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050509152506113d5565b9150915061079f8260200151611634565b6107e4888886868080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152508792508891506116d79050565b505060016000555050505050505050565b6007602052600090815260409020805461080e90612fbe565b80601f016020809104026020016040519081016040528092919081815260200182805461083a90612fbe565b80156108875780601f1061085c57610100808354040283529160200191610887565b820191906000526020600020905b81548152906001019060200180831161086a57829003601f168201915b505050505081565b60015473ffffffffffffffffffffffffffffffffffffffff1633146108e0576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f906a1c6bd7e3091ea86693dd029a831c19049ce77f1dce2ce0bab1cacbabce2290600090a250565b3360009081527f271b3e2292ab6fd3ff496cd98d6d375af02f11568a701741f48bba7789f13a7060205260409020547fc4c453d647953c0fd35db5a34ee76e60fb4abc3a8fb891a25936b70b38f292539060ff166109dc576040517f962f6333000000000000000000000000000000000000000000000000000000008152600481018290526024016105bf565b6109e7848484611a1c565b50505050565b600054600114610a59576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016105bf565b600260008190555060008060008084806020019051810190610a7b9190613056565b9350935093509350600060405180606001604052808673ffffffffffffffffffffffffffffffffffffffff1681526020018581526020018381525090506060610ac48883611b0c565b80516020820151919450919250610adb9190611d8f565b610ae785858385611e43565b50506001600055505050505050565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915281205460ff165b9392505050565b600054600114610b9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600a60248201527f5245454e5452414e43590000000000000000000000000000000000000000000060448201526064016105bf565b6002600090815580610baf848461207f565b91509150610bc581600001518260200151611d8f565b610bd0848484612387565b505060016000555050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610c2c576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14610dd6576005546040517fdd62ed3e00000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff91821660248201526000917f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc0169063dd62ed3e90604401602060405180830381865afa158015610d15573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3991906130bb565b1115610d8557600554610d85907f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc09073ffffffffffffffffffffffffffffffffffffffff166000612642565b8015610dd657610dd67f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc0837fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff612642565b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040519081527fe816c20840d998c8612f9b624b91687a80510eeb293cb09f7637379f6d73342d9060200160405180910390a15050565b6040517fd505accf000000000000000000000000000000000000000000000000000000008152336004820152306024820152604481018c90526064810185905260ff8416608482015260a4810183905260c4810182905273ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc0169063d505accf9060e401600060405180830381600087803b158015610f0257600080fd5b505af1158015610f16573d6000803e3d6000fd5b50505050610f2a8c8c8c8c8c8c8c8c6106a9565b505050505050505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314610f89576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106498282612711565b60015473ffffffffffffffffffffffffffffffffffffffff163314610fe4576040517f5fc483c500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8260005b8181101561114557838382818110611002576110026130d4565b90506020020160208101906110179190613103565b6008600088888581811061102d5761102d6130d4565b90506020020160208101906110429190612b1b565b73ffffffffffffffffffffffffffffffffffffffff168152602081019190915260400160002080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169115159190911790557f857309f1a328784e9fc9749624be5d32fd8e7afab58e7fe9a218dd613a37f15c8686838181106110c8576110c86130d4565b90506020020160208101906110dd9190612b1b565b8585848181106110ef576110ef6130d4565b90506020020160208101906111049190613103565b6040805173ffffffffffffffffffffffffffffffffffffffff909316835290151560208301520160405180910390a18061113d8161314d565b915050610fe8565b505050505050565b6006602052600090815260409020805461080e90612fbe565b6040517f666758ca000000000000000000000000000000000000000000000000000000008152600481018390526024810182905260009073ffffffffffffffffffffffffffffffffffffffff85169063666758ca90604401602060405180830381865afa1580156111db573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111ff91906130bb565b949350505050565b60006040517fa9059cbb00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f5452414e534645525f4641494c4544000000000000000000000000000000000060448201526064016105bf565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600117905551909184917f2ae6a113c0ed5b78a53413ffbb7679881f11145ccfba4fb92e863dfcd5a1d2f39190a35050565b6001805473ffffffffffffffffffffffffffffffffffffffff83167fffffffffffffffffffffffff000000000000000000000000000000000000000091821681179092556002805490911690556040517ffbe19c9b601f5ee90b44c7390f3fa2319eba01762d34ee372aeafd59b25c7f8790600090a250565b60408051606080820183526000808352602083015291810191909152815160609073ffffffffffffffffffffffffffffffffffffffff16611442576040517f96bbcf1e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff841660009081526008602052604090205460ff166114a1576040517f5b0a758300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1480156114fd5750826020015134105b15611534576040517f78f38f7600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff161561162d576005546040805160608101825273ffffffffffffffffffffffffffffffffffffffff878116825233602083015281830187905291517ff59ad990000000000000000000000000000000000000000000000000000000008152919092169163f59ad990916115c291906004016131c4565b6000604051808303816000875af11580156115e1573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526116279190810190613292565b90925090505b9250929050565b80158061168a57507f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee145b156116925750565b6116d473ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc016333084612794565b50565b600554819073ffffffffffffffffffffffffffffffffffffffff16156117d7576005546040805160808101825273ffffffffffffffffffffffffffffffffffffffff8881168252602082018890528183018790526060820186905291517f62811bf200000000000000000000000000000000000000000000000000000000815291909216916362811bf29161176f91906004016132f6565b6000604051808303816000875af115801561178e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526117d49190810190613395565b90505b60007f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc073ffffffffffffffffffffffffffffffffffffffff1673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee14611830573461183f565b602082015161183f90346133ca565b905060008673ffffffffffffffffffffffffffffffffffffffff166374fa24a66040518163ffffffff1660e01b8152600401602060405180830381865afa15801561188e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118b291906130bb565b905060008773ffffffffffffffffffffffffffffffffffffffff1663ac0710cb848b87600001518860200151878a604001516040516020016118f794939291906133e1565b6040516020818303038152906040528b6040518563ffffffff1660e01b815260040161192593929190613426565b60206040518083038185885af1158015611943573d6000803e3d6000fd5b50505050506040513d601f19601f8201168201806040525081019061196891906130bb565b90508181146119a3576040517f7b7bbbe000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83516020808601516040805173ffffffffffffffffffffffffffffffffffffffff8d811682523394820194909452929093168284015260608201526080810184905290517fc74a00177d2c63e6eead5ea7936974ad9d0121f86140723b8909f8ec9662cc619181900360a00190a1505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8216611a69576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fffffffffffffffffffffffff111111111111111111111111111111111111111273ffffffffffffffffffffffffffffffffffffffff841601611ab0576105e9828261287f565b8273ffffffffffffffffffffffffffffffffffffffff163b600003611b01576040517f1eb00b0600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6105e9838383611207565b6040805160608181018352600080835260208301529181018290523360009081526008602052604090205460ff16611b70576040517f5b0a758300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b825173ffffffffffffffffffffffffffffffffffffffff16301480611be457507f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc073ffffffffffffffffffffffffffffffffffffffff16836000015173ffffffffffffffffffffffffffffffffffffffff16145b15611c1b576040517f285c601600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055473ffffffffffffffffffffffffffffffffffffffff161561162d576005546040805160608101825233808252600090815260076020908152929020805473ffffffffffffffffffffffffffffffffffffffff9094169363cf36b9179383019190611c8790612fbe565b80601f0160208091040260200160405190810160405280929190818152602001828054611cb390612fbe565b8015611d005780601f10611cd557610100808354040283529160200191611d00565b820191906000526020600020905b815481529060010190602001808311611ce357829003601f168201915b50505050508152602001868152506040518263ffffffff1660e01b8152600401611d2a9190613451565b6000604051808303816000875af1158015611d49573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261162791908101906134c8565b80600003611d9b575050565b7fffffffffffffffffffffffff11111111111111111111111111111111111111127f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc073ffffffffffffffffffffffffffffffffffffffff1601611e0257610649828261287f565b61064973ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc0168383611207565b60055473ffffffffffffffffffffffffffffffffffffffff1615612015576005546040805160a0810182523380825260208083018890526000918252600790528281208054919473ffffffffffffffffffffffffffffffffffffffff169363dd19fe3893929083019190611eb690612fbe565b80601f0160208091040260200160405190810160405280929190818152602001828054611ee290612fbe565b8015611f2f5780601f10611f0457610100808354040283529160200191611f2f565b820191906000526020600020905b815481529060010190602001808311611f1257829003601f168201915b50505050508152602001868152602001858152506040518263ffffffff1660e01b8152600401611f5f9190613522565b6000604051808303816000875af1158015611f7e573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611fc491908101906135c2565b805160008681526006602090815260409091208251939450611fec93909291909101906128f4565b5060208082015133600090815260078352604090208151612012939192909101906128f4565b50505b80516020808301516040805133815273ffffffffffffffffffffffffffffffffffffffff909416928401929092528282015260608201859052517f9afd47907e25028cdaca89d193518c302bbb128617d5a992c5abd458155265939181900360800190a150505050565b60408051606081810183526000808352602083015291810182905273ffffffffffffffffffffffffffffffffffffffff841660009081526008602052604090205460ff166120f9576040517f5b0a758300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60408051808201825260008581526006602052918220805482919061211d90612fbe565b80601f016020809104026020016040519081016040528092919081815260200182805461214990612fbe565b80156121965780601f1061216b57610100808354040283529160200191612196565b820191906000526020600020905b81548152906001019060200180831161217957829003601f168201915b50505050508152602001600760008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002080546121ea90612fbe565b80601f016020809104026020016040519081016040528092919081815260200182805461221690612fbe565b80156122635780601f1061223857610100808354040283529160200191612263565b820191906000526020600020905b81548152906001019060200180831161224657829003601f168201915b505050505081525090508060000151516000036122ac576040517fd3d38f6800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60055460408051808201825273ffffffffffffffffffffffffffffffffffffffff88811682526020820185905291517f7afb99530000000000000000000000000000000000000000000000000000000081529190921691637afb9953916123169190600401613697565b6000604051808303816000875af1158015612335573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261237b91908101906134c8565b90969095509350505050565b6040805180820182526000848152600660205291822080548291906123ab90612fbe565b80601f01602080910402602001604051908101604052809291908181526020018280546123d790612fbe565b80156124245780601f106123f957610100808354040283529160200191612424565b820191906000526020600020905b81548152906001019060200180831161240757829003601f168201915b50505050508152602001600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020805461247890612fbe565b80601f01602080910402602001604051908101604052809291908181526020018280546124a490612fbe565b80156124f15780601f106124c6576101008083540402835291602001916124f1565b820191906000526020600020905b8154815290600101906020018083116124d457829003601f168201915b5050509190925250506005546040805160808101825273ffffffffffffffffffffffffffffffffffffffff8881168252602082018890528183018790526060820185905291517f1306ac3b000000000000000000000000000000000000000000000000000000008152939450911691631306ac3b91612572916004016136d2565b6000604051808303816000875af1158015612591573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682016040526125d791908101906135c2565b8051600085815260066020908152604090912082519394506125ff93909291909101906128f4565b5060208082015173ffffffffffffffffffffffffffffffffffffffff861660009081526007835260409020815161263b939192909101906128f4565b5050505050565b60006040517f095ea7b300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff84166004820152826024820152602060006044836000895af13d15601f3d11600160005114161716915050806109e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f415050524f56455f4641494c454400000000000000000000000000000000000060448201526064016105bf565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551909184917f155aaafb6329a2098580462df33ec4b7441b19729b9601c5fc17ae1cf99a8a529190a35050565b60006040517f23b872dd00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8516600482015273ffffffffffffffffffffffffffffffffffffffff841660248201528260448201526020600060648360008a5af13d15601f3d116001600051141617169150508061263b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5452414e534645525f46524f4d5f4641494c454400000000000000000000000060448201526064016105bf565b600080600080600085875af19050806105e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601360248201527f4554485f5452414e534645525f4641494c45440000000000000000000000000060448201526064016105bf565b82805461290090612fbe565b90600052602060002090601f0160209004810192826129225760008555612968565b82601f1061293b57805160ff1916838001178555612968565b82800160010185558215612968579182015b8281111561296857825182559160200191906001019061294d565b50612974929150612978565b5090565b5b808211156129745760008155600101612979565b73ffffffffffffffffffffffffffffffffffffffff811681146116d457600080fd5b80356129ba8161298d565b919050565b6000806000606084860312156129d457600080fd5b83356129df8161298d565b92506020840135915060408401356129f68161298d565b809150509250925092565b60008060408385031215612a1457600080fd5b823591506020830135612a268161298d565b809150509250929050565b60008083601f840112612a4357600080fd5b50813567ffffffffffffffff811115612a5b57600080fd5b60208301915083602082850101111561162d57600080fd5b60008060008060008060008060c0898b031215612a8f57600080fd5b8835612a9a8161298d565b975060208901359650604089013595506060890135612ab88161298d565b9450608089013567ffffffffffffffff80821115612ad557600080fd5b612ae18c838d01612a31565b909650945060a08b0135915080821115612afa57600080fd5b50612b078b828c01612a31565b999c989b5096995094979396929594505050565b600060208284031215612b2d57600080fd5b8135610b2a8161298d565b60005b83811015612b53578181015183820152602001612b3b565b838111156109e75750506000910152565b60008151808452612b7c816020860160208601612b38565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000610b2a6020830184612b64565b600080600060608486031215612bd657600080fd5b8335612be18161298d565b92506020840135612bf18161298d565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612c7857612c78612c02565b604052919050565b600067ffffffffffffffff821115612c9a57612c9a612c02565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b60008060408385031215612cd957600080fd5b823563ffffffff81168114612ced57600080fd5b9150602083013567ffffffffffffffff811115612d0957600080fd5b8301601f81018513612d1a57600080fd5b8035612d2d612d2882612c80565b612c31565b818152866020838501011115612d4257600080fd5b816020840160208301376000602083830101528093505050509250929050565b60008060408385031215612d7557600080fd5b8235612d808161298d565b946020939093013593505050565b803580151581146129ba57600080fd5b60008060408385031215612db157600080fd5b8235612dbc8161298d565b9150612dca60208401612d8e565b90509250929050565b803560ff811681146129ba57600080fd5b6000806000806000806000806000806000806101408d8f031215612e0757600080fd5b612e108d6129af565b9b5060208d01359a5060408d01359950612e2c60608e016129af565b985067ffffffffffffffff60808e01351115612e4757600080fd5b612e578e60808f01358f01612a31565b909850965067ffffffffffffffff60a08e01351115612e7557600080fd5b612e858e60a08f01358f01612a31565b909650945060c08d01359350612e9d60e08e01612dd3565b92506101008d013591506101208d013590509295989b509295989b509295989b565b60008083601f840112612ed157600080fd5b50813567ffffffffffffffff811115612ee957600080fd5b6020830191508360208260051b850101111561162d57600080fd5b60008060008060408587031215612f1a57600080fd5b843567ffffffffffffffff80821115612f3257600080fd5b612f3e88838901612ebf565b90965094506020870135915080821115612f5757600080fd5b50612f6487828801612ebf565b95989497509550505050565b600060208284031215612f8257600080fd5b5035919050565b600080600060608486031215612f9e57600080fd5b8335612fa98161298d565b95602085013595506040909401359392505050565b600181811c90821680612fd257607f821691505b60208210810361300b577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600082601f83011261302257600080fd5b8151613030612d2882612c80565b81815284602083860101111561304557600080fd5b6111ff826020830160208701612b38565b6000806000806080858703121561306c57600080fd5b84516130778161298d565b809450506020850151925060408501519150606085015167ffffffffffffffff8111156130a357600080fd5b6130af87828801613011565b91505092959194509250565b6000602082840312156130cd57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561311557600080fd5b610b2a82612d8e565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361317e5761317e61311e565b5060010190565b73ffffffffffffffffffffffffffffffffffffffff81511682526020810151602083015260006040820151606060408501526111ff6060850182612b64565b60208152600073ffffffffffffffffffffffffffffffffffffffff8084511660208401528060208501511660408401525060408301516060808401526111ff6080840182613185565b60006060828403121561321f57600080fd5b6040516060810167ffffffffffffffff828210818311171561324357613243612c02565b81604052829350845191506132578261298d565b81835260208501516020840152604085015191508082111561327857600080fd5b5061328585828601613011565b6040830152505092915050565b600080604083850312156132a557600080fd5b825167ffffffffffffffff808211156132bd57600080fd5b6132c98683870161320d565b935060208501519150808211156132df57600080fd5b506132ec85828601613011565b9150509250929050565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516080604084015261333260a0840182612b64565b905060408401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08085840301606086015261336e8383612b64565b925060608601519150808584030160808601525061338c8282613185565b95945050505050565b6000602082840312156133a757600080fd5b815167ffffffffffffffff8111156133be57600080fd5b6111ff8482850161320d565b6000828210156133dc576133dc61311e565b500390565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015282604082015260806060820152600061341c6080830184612b64565b9695505050505050565b83815260606020820152600061343f6060830185612b64565b828103604084015261341c8185612b64565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516060604084015261348d6080840182612b64565b905060408401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301606085015261338c8282613185565b600080604083850312156134db57600080fd5b825167ffffffffffffffff808211156134f357600080fd5b6134ff86838701613011565b9350602085015191508082111561351557600080fd5b506132ec8582860161320d565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152602082015160408201526000604083015160a0606084015261356860c0840182612b64565b905060608401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0808584030160808601526135a48383612b64565b925060808601519150808584030160a08601525061338c8282613185565b6000602082840312156135d457600080fd5b815167ffffffffffffffff808211156135ec57600080fd5b908301906040828603121561360057600080fd5b60405160408101818110838211171561361b5761361b612c02565b60405282518281111561362d57600080fd5b61363987828601613011565b82525060208301518281111561364e57600080fd5b61365a87828601613011565b60208301525095945050505050565b600081516040845261367e6040850182612b64565b90506020830151848203602086015261338c8282612b64565b6020815273ffffffffffffffffffffffffffffffffffffffff8251166020820152600060208301516040808401526111ff6060840182613669565b6020815273ffffffffffffffffffffffffffffffffffffffff825116602082015260208201516040820152600060408301516080606084015261371860a0840182612b64565b905060608401517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe084830301608085015261338c828261366956fea26469706673582212208e34317c0cf2a659ddbbbc529df47658c8c9164f4b3d9552505eb1457560312e64736f6c634300080d0033

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

00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc0

-----Decoded View---------------
Arg [0] : token_ (address): 0x35D8949372D46B7a3D5A56006AE77B215fc69bC0

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 00000000000000000000000035d8949372d46b7a3d5a56006ae77b215fc69bc0


Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

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

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ 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.