Contract 0x8D9170C9dbFcD3b8a4028c823E19DE5C55453c51 3

 
Txn Hash Method
Block
From
To
Value [Txn Fee]
0x7d6b403f4b5c0645872db7d9235794999f356012f95d689305341209c34fe18c0x60c06040513875622022-11-24 12:29:528 days 22 hrs ago0x40110d4b383804987cac1f5af016cb82d7f5b8d4 IN  Create: CBridgeProtocolV20 FTM0.574958304808
[ Download CSV Export 
Latest 1 internal transaction
Parent Txn Hash Block From To Value
0x7d6b403f4b5c0645872db7d9235794999f356012f95d689305341209c34fe18c513875622022-11-24 12:29:528 days 22 hrs ago 0x40110d4b383804987cac1f5af016cb82d7f5b8d4  Contract Creation0 FTM
[ Download CSV Export 
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
CBridgeProtocolV2

Compiler Version
v0.8.16+commit.07a7930e

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity Standard Json-Input format)

File 1 of 18 : draft-IERC20Permit.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)

/**
 * @dev xSwap modifications of original OpenZeppelin's {IERC20Permit} implementation:
 * - bump `pragma solidity` (`^0.8.0` -> `^0.8.16`)
 */

pragma solidity ^0.8.16;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

File 2 of 18 : IERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)

/**
 * @dev xSwap modifications of original OpenZeppelin's {IERC20} implementation:
 * - bump `pragma solidity` (`^0.8.0` -> `^0.8.16`)
 */

pragma solidity ^0.8.16;

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

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

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

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

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

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

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

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

File 3 of 18 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)

/**
 * @dev xSwap modifications of original OpenZeppelin's {Address} implementation:
 * - bump `pragma solidity` (`^0.8.1` -> `^0.8.16`)
 * - shortify `require` messages (`Address:` -> `AD:` + others to avoid length warnings)
 * - disable some `solhint` rules for the file
 */

/* solhint-disable avoid-low-level-calls */

pragma solidity ^0.8.16;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "AD: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "AD: unable to send value");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, "AD: low-level call fail");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "AD: low-level value call fail");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "AD: not enough balance for call");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "AD: low-level static call fail");
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "AD: low-level delegate call fail");
    }

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

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "AD: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

File 4 of 18 : SafeERC20.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC20/utils/SafeERC20.sol)

/**
 * @dev xSwap modifications of original OpenZeppelin's {SafeERC20} implementation:
 * - bump `pragma solidity` (`^0.8.0` -> `^0.8.16`)
 * - adjust OpenZeppelin's {IERC20}, {IERC20Permit}, {Address} imports (use `library` implementation)
 * - shortify `require` messages (`SafeERC20:` -> `SE:` + others to avoid length warnings)
 */

pragma solidity ^0.8.16;

import {IERC20} from "./IERC20.sol";
import {IERC20Permit} from "./draft-IERC20Permit.sol";
import {Address} from "./Address.sol";

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

    function safeTransfer(IERC20 token, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(IERC20 token, address spender, uint256 value) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require((value == 0) || (token.allowance(address(this), spender) == 0), "SE: approve from non-0 to non-0");
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
    }

    function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(oldAllowance >= value, "SE: decreased allowance below 0");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    function safePermit(
        IERC20Permit token,
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal {
        uint256 nonceBefore = token.nonces(owner);
        token.permit(owner, spender, value, deadline, v, r, s);
        uint256 nonceAfter = token.nonces(owner);
        require(nonceAfter == nonceBefore + 1, "SE: permit did not succeed");
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(data, "SE: low-level call failed");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SE: ERC20 operation failed");
        }
    }
}

File 5 of 18 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

/**
 * @dev xSwap modifications of original OpenZeppelin's {Strings} implementation:
 * - bump `pragma solidity` (`^0.8.0` -> `^0.8.16`)
 */

pragma solidity ^0.8.16;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

File 6 of 18 : ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)

/**
 * @dev xSwap modifications of original OpenZeppelin's {ECDSA} implementation:
 * - bump `pragma solidity` (`^0.8.0` -> `^0.8.16`)
 * - adjust OpenZeppelin's {Strings} import (use `library` implementation)
 * - shortify `require` messages (`ECDSA:` -> `EC:`)
 * - extract `decompress(bytes32 vs)` private function from `tryRecover(bytes32 hash, bytes32 r, bytes32 vs)`
 * - extract `tryDecompose(bytes memory signature)` private function from `tryRecover(bytes32 hash, bytes memory signature)`
 */

pragma solidity ^0.8.16;

import "./Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("EC: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("EC: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("EC: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("EC: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address signer, RecoverError err) {
        bytes32 r;
        bytes32 s;
        uint8 v;
        (r, s, v, err) = tryDecompose(signature);
        if (err == RecoverError.NoError) {
            (signer, err) = tryRecover(hash, v, r, s);
        }
    }

    /**
     * @dev Extracted from {ECDSA-tryRecover} (bytes32 hash, bytes memory signature) for xSwap needs
     */
    function tryDecompose(
        bytes memory signature
    ) internal pure returns (bytes32 r, bytes32 s, uint8 v, RecoverError err) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
        } else if (signature.length == 64) {
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            (s, v) = decompress(vs);
        } else {
            err = RecoverError.InvalidSignatureLength;
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError) {
        (bytes32 s, uint8 v) = decompress(vs);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Extracted from {ECDSA-tryRecover} (bytes32 hash, bytes32 r, bytes32 vs) for xSwap needs
     */
    function decompress(bytes32 vs) private pure returns (bytes32 s, uint8 v) {
        s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        v = uint8((uint256(vs) >> 255) + 27);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 7 of 18 : NativeClaimer.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.16;

library NativeClaimer {
    struct State {
        uint256 _valueClaimed;
    }

    function claimed(NativeClaimer.State memory claimer_) internal pure returns (uint256) {
        return claimer_._valueClaimed;
    }

    function unclaimed(NativeClaimer.State memory claimer_) internal view returns (uint256) {
        return msg.value - claimer_._valueClaimed;
    }

    function claim(NativeClaimer.State memory claimer_, uint256 value_) internal view {
        require(unclaimed(claimer_) >= value_, "NC: insufficient msg value");
        claimer_._valueClaimed += value_;
    }
}

File 8 of 18 : TokenHelper.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.16;

import {IERC20} from "../../lib/IERC20.sol";
import {IERC20Permit} from "../../lib/draft-IERC20Permit.sol";
import {SafeERC20} from "../../lib/SafeERC20.sol";
import {Address} from "../../lib/Address.sol";
import {ECDSA} from "../../lib/ECDSA.sol";

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

library TokenHelper {
    using SafeERC20 for IERC20;
    using SafeERC20 for IERC20Permit;
    using Address for address;
    using Address for address payable;
    using NativeClaimer for NativeClaimer.State;

    /**
     * @dev xSwap's native coin representation.
     */
    address public constant NATIVE_TOKEN = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;

    modifier whenNonZero(uint256 amount_) {
        if (amount_ == 0) {
            return;
        }
        _;
    }

    function isNative(address token_) internal pure returns (bool) {
        return token_ == NATIVE_TOKEN;
    }

    function balanceOf(
        address token_,
        address owner_,
        NativeClaimer.State memory claimer_
    ) internal view returns (uint256 balance) {
        if (isNative(token_)) {
            balance = _nativeBalanceOf(owner_, claimer_);
        } else {
            balance = IERC20(token_).balanceOf(owner_);
        }
    }

    function balanceOfThis(
        address token_,
        NativeClaimer.State memory claimer_
    ) internal view returns (uint256 balance) {
        balance = balanceOf(token_, _this(), claimer_);
    }

    function transferToThis(
        address token_,
        address from_,
        uint256 amount_,
        NativeClaimer.State memory claimer_
    ) internal whenNonZero(amount_) {
        if (isNative(token_)) {
            // We cannot claim native coins of an arbitrary "from_" address
            // like we do with ERC-20 allowance. So the only way to use native
            // is to pass via "value" with the contract call. The "from_" address
            // does not participate in such a scenario. The only thing we can do
            // is to restrict caller to be "from_" address only.
            require(from_ == _sender(), "TH: native allows sender only");
            claimer_.claim(amount_);
        } else {
            IERC20(token_).safeTransferFrom(from_, _this(), amount_);
        }
    }

    function transferFromThis(address token_, address to_, uint256 amount_) internal whenNonZero(amount_) {
        if (isNative(token_)) {
            _nativeTransferFromThis(to_, amount_);
        } else {
            IERC20(token_).safeTransfer(to_, amount_);
        }
    }

    function approveOfThis(
        address token_,
        address spender_,
        uint256 amount_
    ) internal whenNonZero(amount_) returns (uint256 sendValue) {
        if (isNative(token_)) {
            sendValue = amount_;
        } else {
            sendValue = 0;
            IERC20(token_).safeApprove(spender_, amount_);
        }
    }

    function revokeOfThis(address token_, address spender_) internal {
        if (!isNative(token_)) {
            IERC20(token_).safeApprove(spender_, 0);
        }
    }

    function _nativeBalanceOf(
        address owner_,
        NativeClaimer.State memory claimer_
    ) private view returns (uint256 balance) {
        if (owner_ == _sender()) {
            balance = claimer_.unclaimed();
        } else {
            balance = owner_.balance;
            if (owner_ == _this()) {
                balance -= claimer_.unclaimed();
            }
        }
    }

    function _nativeTransferFromThis(address to_, uint256 amount_) private whenNonZero(amount_) {
        payable(to_).sendValue(amount_);
    }

    function _this() private view returns (address) {
        return address(this);
    }

    function _sender() private view returns (address) {
        return msg.sender;
    }
}

File 9 of 18 : NativeReturnMods.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.16;

import {NativeClaimer} from "./NativeClaimer.sol";
import {TokenHelper} from "./TokenHelper.sol";

abstract contract NativeReturnMods {
    using NativeClaimer for NativeClaimer.State;

    modifier returnUnclaimedNative(NativeClaimer.State memory claimer_) {
        require(claimer_.claimed() == 0, "NR: claimer already in use");
        _;
        TokenHelper.transferFromThis(TokenHelper.NATIVE_TOKEN, msg.sender, claimer_.unclaimed());
    }
}

File 10 of 18 : Swap.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.16;

struct TokenCheck {
    address token;
    uint256 minAmount;
    uint256 maxAmount;
}

struct TokenUse {
    address protocol;
    uint256 chain;
    address account;
    uint256[] inIndices;
    TokenCheck[] outs;
    bytes args; // Example of reserved value: 0x44796E616D6963 ("Dynamic")
}

struct SwapStep {
    uint256 chain;
    address swapper;
    address account;
    bool useDelegate;
    uint256 nonce;
    uint256 deadline;
    TokenCheck[] ins;
    TokenCheck[] outs;
    TokenUse[] uses;
}

struct Swap {
    SwapStep[] steps;
}

struct StealthSwap {
    uint256 chain;
    address swapper;
    address account;
    bytes32[] stepHashes;
}

File 11 of 18 : StorageSlot.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)

/**
 * @dev xSwap modifications of original OpenZeppelin's {StorageSlot} implementation:
 * - bump `pragma solidity` (`^0.8.0` -> `^0.8.16`)
 */

pragma solidity ^0.8.16;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 *
 * _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }
}

File 12 of 18 : IAccountWhitelist.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.16;

interface IAccountWhitelist {
    event AccountAdded(address account);
    event AccountRemoved(address account);

    function getWhitelistedAccounts() external view returns (address[] memory);

    function isAccountWhitelisted(address account) external view returns (bool);

    function addAccountToWhitelist(address account) external;

    function removeAccountFromWhitelist(address account) external;
}

File 13 of 18 : IWithdrawable.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.16;

struct Withdraw {
    address token;
    uint256 amount;
    address to;
}

interface IWithdrawable {
    event Withdrawn(address token, uint256 amount, address to);

    function withdraw(Withdraw[] calldata withdraws) external;
}

File 14 of 18 : Withdrawable.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.16;

import {TokenHelper} from "../asset/TokenHelper.sol";

import {IWithdrawable, Withdraw} from "./IWithdrawable.sol";

abstract contract Withdrawable is IWithdrawable {
    function withdraw(Withdraw[] calldata withdraws_) external virtual {
        _checkWithdraw();

        for (uint256 i = 0; i < withdraws_.length; i++) {
            Withdraw calldata w = withdraws_[i];
            TokenHelper.transferFromThis(w.token, w.to, w.amount);
            emit Withdrawn(w.token, w.amount, w.to);
        }
    }

    function _checkWithdraw() internal view virtual;
}

File 15 of 18 : WhitelistWithdrawableStorage.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.16;

import {StorageSlot} from "../../lib/StorageSlot.sol";

import {TokenHelper} from "../asset/TokenHelper.sol";

import {IAccountWhitelist} from "../whitelist/IAccountWhitelist.sol";

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

abstract contract WhitelistWithdrawableStorage {
    bytes32 private immutable _withdrawWhitelistSlot;

    constructor(bytes32 withdrawWhitelistSlot_) {
        _withdrawWhitelistSlot = withdrawWhitelistSlot_;
    }

    function _withdrawWhitelistStorage() private view returns (StorageSlot.AddressSlot storage) {
        return StorageSlot.getAddressSlot(_withdrawWhitelistSlot);
    }

    function _withdrawWhitelist() internal view returns (IAccountWhitelist) {
        return IAccountWhitelist(_withdrawWhitelistStorage().value);
    }

    function _setWithdrawWhitelist(address withdrawWhitelist_) internal {
        _withdrawWhitelistStorage().value = withdrawWhitelist_;
    }
}

File 16 of 18 : WhitelistWithdrawable.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.16;

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

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

abstract contract WhitelistWithdrawable is Withdrawable, WhitelistWithdrawableStorage {
    constructor(
        bytes32 withdrawWhitelistSlot_,
        address withdrawWhitelist_
    ) WhitelistWithdrawableStorage(withdrawWhitelistSlot_) {
        _initialize(withdrawWhitelist_);
    }

    function initializeWhitelistWithdrawable(address withdrawWhitelist_) internal {
        _initialize(withdrawWhitelist_);
    }

    function _initialize(address withdrawWhitelist_) private {
        require(withdrawWhitelist_ != address(0), "WW: zero withdraw whitelist");
        _setWithdrawWhitelist(withdrawWhitelist_);
    }

    function _checkWithdraw() internal view override {
        _checkWithdrawerWhitelisted();
    }

    function _checkWithdrawerWhitelisted() private view {
        require(_withdrawWhitelist().isAccountWhitelisted(msg.sender), "WW: withdrawer not whitelisted");
    }
}

File 17 of 18 : IUseProtocol.sol
// SPDX-License-Identifier: GPL-2.0-or-later

pragma solidity ^0.8.16;

import {TokenCheck} from "../swap/Swap.sol";

struct UseParams {
    uint256 chain;
    address account;
    TokenCheck[] ins;
    uint256[] inAmounts;
    TokenCheck[] outs;
    bytes args;
    address msgSender;
    bytes msgData;
}

interface IUseProtocol {
    function use(UseParams calldata params) external payable;
}

File 18 of 18 : CBridgeV2.sol
// SPDX-License-Identifier: BUSL-1.1

pragma solidity ^0.8.16;

import {NativeClaimer} from "../../core/asset/NativeClaimer.sol";
import {NativeReturnMods} from "../../core/asset/NativeReturnMods.sol";
import {TokenHelper} from "../../core/asset/TokenHelper.sol";

import {TokenCheck} from "../../core/swap/Swap.sol";

import {IUseProtocol, UseParams} from "../../core/use/IUseProtocol.sol";

import {WhitelistWithdrawable} from "../../core/withdraw/WhitelistWithdrawable.sol";

interface ICBridge {
    function send(
        address receiver,
        address token,
        uint256 amount,
        uint64 dstChainId,
        uint64 nonce,
        uint32 maxSlippage
    ) external;

    function sendNative(
        address receiver,
        uint256 amount,
        uint64 dstChainId,
        uint64 nonce,
        uint32 maxSlippage
    ) external payable;
}

struct CBridgeProtocolV2ConstructorParams {
    /**
     * @dev {ICBridge}-compatible contract address
     */
    address cBridge;
    /**
     * @dev {IAccountWhitelist}-compatible contract address
     */
    address withdrawWhitelist;
}

/**
 * @dev Bridge hop wrapper for cBridge:
 *
 * - Exactly one input & one output
 * - The slippage value is calculated from output min/max (or from args)
 * - The account serves as receiver in destination network specified by the chain
 *
 * @dev The 'V2' introduction:
 *
 * - Fixes slippage calculation from min/max (the value was too low)
 * - Added ability to override min/max slippage deduction via args
 */
contract CBridgeProtocolV2 is IUseProtocol, WhitelistWithdrawable, NativeReturnMods {
    address private immutable _cBridge;

    // prettier-ignore
    // bytes32 private constant _WITHDRAW_WHITELIST_SLOT = bytes32(uint256(keccak256("xSwap.v2.CBridgeV2._withdrawWhitelist")) - 1);
    bytes32 private constant _WITHDRAW_WHITELIST_SLOT = 0x796bf16194baceeeb129462bfb187eebb6dce2ee6facc141657938facb799b42;

    uint256 private constant _C_BRIDGE_SLIPPAGE_UNITS_FACTOR = 1_000_000; // From cBridge slippage implementation

    constructor(
        CBridgeProtocolV2ConstructorParams memory params_
    ) WhitelistWithdrawable(_WITHDRAW_WHITELIST_SLOT, params_.withdrawWhitelist) {
        require(params_.cBridge != address(0), "CB: zero cBridge contract");
        _cBridge = params_.cBridge;
    }

    function cBridge() external view returns (address) {
        return _cBridge;
    }

    function use(UseParams calldata params_) external payable {
        require(params_.chain != block.chainid, "CB: wrong chain id");
        require(params_.account != address(0), "CB: zero receiver");

        require(params_.ins.length == 1, "CB: wrong number of ins");
        require(params_.inAmounts.length == 1, "CB: wrong number of in amounts");
        require(params_.outs.length == 1, "CB: wrong number of outs");

        NativeClaimer.State memory nativeClaimer;
        _hop(
            params_.ins[0],
            params_.inAmounts[0],
            params_.outs[0],
            params_.chain,
            params_.account,
            params_.args,
            nativeClaimer
        );
    }

    function _hop(
        TokenCheck calldata in_,
        uint256 inAmount_,
        TokenCheck calldata out_,
        uint256 chain_,
        address account_,
        bytes calldata args_,
        NativeClaimer.State memory nativeClaimer_
    ) private returnUnclaimedNative(nativeClaimer_) {
        TokenHelper.transferToThis(in_.token, msg.sender, inAmount_, nativeClaimer_);

        uint32 slippage = _slippageFromMinMax(out_);
        if (args_.length > 0) {
            require(args_.length == 4, "CB: invalid args length");
            uint32 argsSlippage = uint32(bytes4(args_));
            require(argsSlippage <= slippage, "CB: args slippage too high");
            slippage = argsSlippage;
        }

        if (TokenHelper.isNative(in_.token)) {
            ICBridge(_cBridge).sendNative{value: inAmount_}(
                account_,
                inAmount_,
                _dstChainId(chain_),
                _nonce(),
                slippage
            );
        } else {
            TokenHelper.approveOfThis(in_.token, _cBridge, inAmount_);
            // prettier-ignore
            ICBridge(_cBridge).send(
                account_,
                in_.token,
                inAmount_,
                _dstChainId(chain_),
                _nonce(),
                slippage
            );
            TokenHelper.revokeOfThis(in_.token, _cBridge);
        }
    }

    function _dstChainId(uint256 chain_) private pure returns (uint64) {
        return uint64(chain_);
    }

    function _nonce() private view returns (uint64) {
        return uint64(block.timestamp); // solhint-disable not-rely-on-time
    }

    function _slippageFromMinMax(TokenCheck calldata out_) private pure returns (uint32) {
        uint256 slippage = ((out_.maxAmount - out_.minAmount) * _C_BRIDGE_SLIPPAGE_UNITS_FACTOR) / out_.maxAmount;
        return uint32(slippage);
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"components":[{"internalType":"address","name":"cBridge","type":"address"},{"internalType":"address","name":"withdrawWhitelist","type":"address"}],"internalType":"struct CBridgeProtocolV2ConstructorParams","name":"params_","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"Withdrawn","type":"event"},{"inputs":[],"name":"cBridge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"chain","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"uint256","name":"maxAmount","type":"uint256"}],"internalType":"struct TokenCheck[]","name":"ins","type":"tuple[]"},{"internalType":"uint256[]","name":"inAmounts","type":"uint256[]"},{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"minAmount","type":"uint256"},{"internalType":"uint256","name":"maxAmount","type":"uint256"}],"internalType":"struct TokenCheck[]","name":"outs","type":"tuple[]"},{"internalType":"bytes","name":"args","type":"bytes"},{"internalType":"address","name":"msgSender","type":"address"},{"internalType":"bytes","name":"msgData","type":"bytes"}],"internalType":"struct UseParams","name":"params_","type":"tuple"}],"name":"use","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"internalType":"struct Withdraw[]","name":"withdraws_","type":"tuple[]"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040523480156200001157600080fd5b5060405162001647380380620016478339810160408190526200003491620001ae565b60208101517f796bf16194baceeeb129462bfb187eebb6dce2ee6facc141657938facb799b426080819052906200006b81620000dd565b505080516001600160a01b0316620000ca5760405162461bcd60e51b815260206004820152601960248201527f43423a207a65726f206342726964676520636f6e74726163740000000000000060448201526064015b60405180910390fd5b516001600160a01b031660a0526200021c565b6001600160a01b038116620001355760405162461bcd60e51b815260206004820152601b60248201527f57573a207a65726f2077697468647261772077686974656c69737400000000006044820152606401620000c1565b620001408162000143565b50565b806200014e6200016f565b80546001600160a01b0319166001600160a01b039290921691909117905550565b6000620001896080516200018e60201b620004201760201c565b905090565b90565b80516001600160a01b0381168114620001a957600080fd5b919050565b600060408284031215620001c157600080fd5b604080519081016001600160401b0381118282101715620001f257634e487b7160e01b600052604160045260246000fd5b604052620002008362000191565b8152620002106020840162000191565b60208201529392505050565b60805160a0516113ea6200025d60003960008181606a015281816105fd015281816106c2015281816106f201526107c90152600061082201526113ea6000f3fe6080604052600436106100345760003560e01c8063160b723c1461003957806336d4b75f1461005b5780635d9c8b1a146100a5575b600080fd5b34801561004557600080fd5b5061005961005436600461106f565b6100b8565b005b34801561006757600080fd5b507f00000000000000000000000000000000000000000000000000000000000000006040516001600160a01b03909116815260200160405180910390f35b6100596100b33660046110e4565b610198565b6100c0610423565b60005b8181101561019357368383838181106100de576100de611120565b60600291909101915061011390506100f96020830183611136565b6101096060840160408501611136565b836020013561042d565b7fcbcdbdf10631a43cc99c80acace8232649421c3f4f73919f16013d47c83a687a6101416020830183611136565b60208301356101566060850160408601611136565b604080516001600160a01b039485168152602081019390935292168183015290519081900360600190a1508061018b81611175565b9150506100c3565b505050565b468135036101ed5760405162461bcd60e51b815260206004820152601260248201527f43423a2077726f6e6720636861696e206964000000000000000000000000000060448201526064015b60405180910390fd5b60006101ff6040830160208401611136565b6001600160a01b0316036102555760405162461bcd60e51b815260206004820152601160248201527f43423a207a65726f20726563656976657200000000000000000000000000000060448201526064016101e4565b610262604082018261118e565b90506001146102b35760405162461bcd60e51b815260206004820152601760248201527f43423a2077726f6e67206e756d626572206f6620696e7300000000000000000060448201526064016101e4565b6102c060608201826111de565b90506001146103115760405162461bcd60e51b815260206004820152601e60248201527f43423a2077726f6e67206e756d626572206f6620696e20616d6f756e7473000060448201526064016101e4565b61031e608082018261118e565b905060011461036f5760405162461bcd60e51b815260206004820152601860248201527f43423a2077726f6e67206e756d626572206f66206f757473000000000000000060448201526064016101e4565b60408051602081019091526000815261041c61038e604084018461118e565b600081811061039f5761039f611120565b9050606002018380606001906103b591906111de565b60008181106103c6576103c6611120565b905060200201358480608001906103dd919061118e565b60008181106103ee576103ee611120565b60600291909101905085356104096040880160208901611136565b61041660a0890189611228565b88610481565b5050565b90565b61042b610820565b565b80801561047b5773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0385160361046757610462838361091a565b61047b565b61047b6001600160a01b038516848461093b565b50505050565b8061048a815190565b156104d75760405162461bcd60e51b815260206004820152601a60248201527f4e523a20636c61696d657220616c726561647920696e2075736500000000000060448201526064016101e4565b6104ef6104e760208b018b611136565b338a856109cc565b60006104fa88610a7a565b905083156105bc57600484146105525760405162461bcd60e51b815260206004820152601760248201527f43423a20696e76616c69642061726773206c656e67746800000000000000000060448201526064016101e4565b600061055e858761126f565b60e01c905063ffffffff82168111156105b95760405162461bcd60e51b815260206004820152601a60248201527f43423a206172677320736c69707061676520746f6f206869676800000000000060448201526064016101e4565b90505b6105ee6105cc60208c018c611136565b6001600160a01b031673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1490565b156106b0576001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016633f2e5fc38a88818b426040516001600160e01b031960e088901b1681526001600160a01b039094166004850152602484019290925267ffffffffffffffff908116604484015216606482015263ffffffff8516608482015260a4016000604051808303818588803b15801561069257600080fd5b505af11580156106a6573d6000803e3d6000fd5b50505050506107ed565b6106e76106c060208c018c611136565b7f00000000000000000000000000000000000000000000000000000000000000008b610aaf565b506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663a5977fbb8761072560208e018e611136565b8c8b426040516001600160e01b031960e088901b1681526001600160a01b039586166004820152949093166024850152604484019190915267ffffffffffffffff908116606484015216608482015263ffffffff841660a482015260c401600060405180830381600087803b15801561079d57600080fd5b505af11580156107b1573d6000803e3d6000fd5b506107ed92506107c791505060208c018c611136565b7f0000000000000000000000000000000000000000000000000000000000000000610b04565b5061081573eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee3361081084610b3d565b61042d565b505050505050505050565b7f0000000000000000000000000000000000000000000000000000000000000000546001600160a01b03166040517f8907e7870000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b039190911690638907e78790602401602060405180830381865afa1580156108aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108ce919061129f565b61042b5760405162461bcd60e51b815260206004820152601e60248201527f57573a2077697468647261776572206e6f742077686974656c6973746564000060448201526064016101e4565b808060000361092857505050565b6101936001600160a01b03841683610b52565b6040516001600160a01b0383166024820152604481018290526101939084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff166001600160e01b031990931692909217909152610c45565b818015610a735773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b03861603610a5e576001600160a01b0384163314610a4f5760405162461bcd60e51b815260206004820152601d60248201527f54483a206e617469766520616c6c6f77732073656e646572206f6e6c7900000060448201526064016101e4565b610a598284610d04565b610a73565b610a736001600160a01b038616853086610d75565b5050505050565b6000806040830135620f4240610a946020860135836112c1565b610a9e91906112d4565b610aa891906112f3565b9392505050565b6000818015610afc5773eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b03861603610ae457829150610afc565b60009150610afc6001600160a01b0386168585610dc6565b509392505050565b73eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee6001600160a01b0383161461041c5761041c6001600160a01b038316826000610dc6565b8051600090610b4c90346112c1565b92915050565b80471015610ba25760405162461bcd60e51b815260206004820152601860248201527f41443a20696e73756666696369656e742062616c616e6365000000000000000060448201526064016101e4565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114610bef576040519150601f19603f3d011682016040523d82523d6000602084013e610bf4565b606091505b50509050806101935760405162461bcd60e51b815260206004820152601860248201527f41443a20756e61626c6520746f2073656e642076616c7565000000000000000060448201526064016101e4565b6000610c9a826040518060400160405280601981526020017f53453a206c6f772d6c6576656c2063616c6c206661696c656400000000000000815250856001600160a01b0316610eee9092919063ffffffff16565b8051909150156101935780806020019051810190610cb8919061129f565b6101935760405162461bcd60e51b815260206004820152601a60248201527f53453a204552433230206f7065726174696f6e206661696c656400000000000060448201526064016101e4565b80610d0e83610b3d565b1015610d5c5760405162461bcd60e51b815260206004820152601a60248201527f4e433a20696e73756666696369656e74206d73672076616c756500000000000060448201526064016101e4565b8082600001818151610d6e9190611315565b9052505050565b6040516001600160a01b038085166024830152831660448201526064810182905261047b9085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401610980565b801580610e5957506040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015610e33573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e579190611328565b155b610ea55760405162461bcd60e51b815260206004820152601f60248201527f53453a20617070726f76652066726f6d206e6f6e2d3020746f206e6f6e2d300060448201526064016101e4565b6040516001600160a01b0383166024820152604481018290526101939084907f095ea7b30000000000000000000000000000000000000000000000000000000090606401610980565b6060610efd8484600085610f05565b949350505050565b606082471015610f575760405162461bcd60e51b815260206004820152601f60248201527f41443a206e6f7420656e6f7567682062616c616e636520666f722063616c6c0060448201526064016101e4565b600080866001600160a01b03168587604051610f739190611365565b60006040518083038185875af1925050503d8060008114610fb0576040519150601f19603f3d011682016040523d82523d6000602084013e610fb5565b606091505b5091509150610fc687838387610fd1565b979650505050505050565b60608315611040578251600003611039576001600160a01b0385163b6110395760405162461bcd60e51b815260206004820152601860248201527f41443a2063616c6c20746f206e6f6e2d636f6e7472616374000000000000000060448201526064016101e4565b5081610efd565b610efd83838151156110555781518083602001fd5b8060405162461bcd60e51b81526004016101e49190611381565b6000806020838503121561108257600080fd5b823567ffffffffffffffff8082111561109a57600080fd5b818501915085601f8301126110ae57600080fd5b8135818111156110bd57600080fd5b8660206060830285010111156110d257600080fd5b60209290920196919550909350505050565b6000602082840312156110f657600080fd5b813567ffffffffffffffff81111561110d57600080fd5b82016101008185031215610aa857600080fd5b634e487b7160e01b600052603260045260246000fd5b60006020828403121561114857600080fd5b81356001600160a01b0381168114610aa857600080fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016111875761118761115f565b5060010190565b6000808335601e198436030181126111a557600080fd5b83018035915067ffffffffffffffff8211156111c057600080fd5b60200191506060810236038213156111d757600080fd5b9250929050565b6000808335601e198436030181126111f557600080fd5b83018035915067ffffffffffffffff82111561121057600080fd5b6020019150600581901b36038213156111d757600080fd5b6000808335601e1984360301811261123f57600080fd5b83018035915067ffffffffffffffff82111561125a57600080fd5b6020019150368190038213156111d757600080fd5b6001600160e01b031981358181169160048510156112975780818660040360031b1b83161692505b505092915050565b6000602082840312156112b157600080fd5b81518015158114610aa857600080fd5b81810381811115610b4c57610b4c61115f565b60008160001904831182151516156112ee576112ee61115f565b500290565b60008261131057634e487b7160e01b600052601260045260246000fd5b500490565b80820180821115610b4c57610b4c61115f565b60006020828403121561133a57600080fd5b5051919050565b60005b8381101561135c578181015183820152602001611344565b50506000910152565b60008251611377818460208701611341565b9190910192915050565b60208152600082518060208401526113a0816040850160208701611341565b601f01601f1916919091016040019291505056fea2646970667358221220a7eec5fbb8a25ef6e85f227e8b8bfd26d7a616f56b38490b1a27e21c1de58af864736f6c63430008100033000000000000000000000000374b8a9f3ec5eb2d97eca84ea27aca45aa1c57ef00000000000000000000000035aa226920301c44285448ecbf5327df0e953db4

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

000000000000000000000000374b8a9f3ec5eb2d97eca84ea27aca45aa1c57ef00000000000000000000000035aa226920301c44285448ecbf5327df0e953db4

-----Decoded View---------------
Arg [0] : params_ (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000374b8a9f3ec5eb2d97eca84ea27aca45aa1c57ef
Arg [1] : 00000000000000000000000035aa226920301c44285448ecbf5327df0e953db4


Deployed ByteCode Sourcemap

1520:3490:17:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;235:338:9;;;;;;;;;;-1:-1:-1;235:338:9;;;;;:::i;:::-;;:::i;:::-;;2325:83:17;;;;;;;;;;-1:-1:-1;2393:8:17;2325:83;;-1:-1:-1;;;;;828:55:18;;;810:74;;798:2;783:18;2325:83:17;;;;;;;2414:703;;;;;;:::i;:::-;;:::i;235:338:9:-;312:16;:14;:16::i;:::-;344:9;339:228;359:21;;;339:228;;;401:19;423:10;;434:1;423:13;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;450:53:9;;-1:-1:-1;479:7:9;;;;423:13;479:7;:::i;:::-;488:4;;;;;;;;:::i;:::-;494:1;:8;;;450:28;:53::i;:::-;522:34;532:7;;;;:1;:7;:::i;:::-;541:8;;;;551:4;;;;;;;;:::i;:::-;522:34;;;-1:-1:-1;;;;;2072:15:18;;;2054:34;;2119:2;2104:18;;2097:34;;;;2167:15;;2147:18;;;2140:43;522:34:9;;;;;;1981:2:18;522:34:9;;;-1:-1:-1;382:3:9;;;;:::i;:::-;;;;339:228;;;;235:338;;:::o;2414:703:17:-;2507:13;2490;;:30;2482:61;;;;-1:-1:-1;;;2482:61:17;;2725:2:18;2482:61:17;;;2707:21:18;2764:2;2744:18;;;2737:30;2803:20;2783:18;;;2776:48;2841:18;;2482:61:17;;;;;;;;;2588:1;2561:15;;;;;;;;:::i;:::-;-1:-1:-1;;;;;2561:29:17;;2553:59;;;;-1:-1:-1;;;2553:59:17;;3072:2:18;2553:59:17;;;3054:21:18;3111:2;3091:18;;;3084:30;3150:19;3130:18;;;3123:47;3187:18;;2553:59:17;2870:341:18;2553:59:17;2631:11;;;;:7;:11;:::i;:::-;:18;;2653:1;2631:23;2623:59;;;;-1:-1:-1;;;2623:59:17;;4000:2:18;2623:59:17;;;3982:21:18;4039:2;4019:18;;;4012:30;4078:25;4058:18;;;4051:53;4121:18;;2623:59:17;3798:347:18;2623:59:17;2700:17;;;;:7;:17;:::i;:::-;:24;;2728:1;2700:29;2692:72;;;;-1:-1:-1;;;2692:72:17;;4902:2:18;2692:72:17;;;4884:21:18;4941:2;4921:18;;;4914:30;4980:32;4960:18;;;4953:60;5030:18;;2692:72:17;4700:354:18;2692:72:17;2782:12;;;;:7;:12;:::i;:::-;:19;;2805:1;2782:24;2774:61;;;;-1:-1:-1;;;2774:61:17;;5261:2:18;2774:61:17;;;5243:21:18;5300:2;5280:18;;;5273:30;5339:26;5319:18;;;5312:54;5383:18;;2774:61:17;5059:348:18;2774:61:17;-1:-1:-1;;;;;;;;;;;;2896:214:17;2914:11;;;;:7;:11;:::i;:::-;2926:1;2914:14;;;;;;;:::i;:::-;;;;;;2942:7;:17;;;;;;;;:::i;:::-;2960:1;2942:20;;;;;;;:::i;:::-;;;;;;;2976:7;:12;;;;;;;;:::i;:::-;2989:1;2976:15;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;3005:13:17;;3032:15;;;;;;;;:::i;:::-;3061:12;;;;:7;:12;:::i;:::-;3087:13;2896:4;:214::i;:::-;2472:645;2414:703;:::o;1761:190:14:-;1931:4;1761:190::o;824:95:7:-;883:29;:27;:29::i;:::-;824:95::o;2333:274:2:-;2426:7;782:49;;814:7;782:49;685:42;-1:-1:-1;;;;;934:22:2;;;2445:156:::1;;2481:37;2505:3;2510:7;2481:23;:37::i;:::-;2445:156;;;2549:41;-1:-1:-1::0;;;;;2549:27:2;::::1;2577:3:::0;2582:7;2549:27:::1;:41::i;:::-;2333:274:::0;;;;:::o;3123:1391:17:-;3398:14;340:18:1;:8;252:22:0;;149:132;340:18:1;:23;332:62;;;;-1:-1:-1;;;332:62:1;;6140:2:18;332:62:1;;;6122:21:18;6179:2;6159:18;;;6152:30;6218:28;6198:18;;;6191:56;6264:18;;332:62:1;5938:350:18;332:62:1;3424:76:17::1;3451:9;;::::0;::::1;:3:::0;:9:::1;:::i;:::-;3462:10;3474:9;3485:14;3424:26;:76::i;:::-;3511:15;3529:25;3549:4;3529:19;:25::i;:::-;3511:43:::0;-1:-1:-1;3568:16:17;;3564:271:::1;;3624:1;3608:17:::0;::::1;3600:53;;;::::0;-1:-1:-1;;;3600:53:17;;6495:2:18;3600:53:17::1;::::0;::::1;6477:21:18::0;6534:2;6514:18;;;6507:30;6573:25;6553:18;;;6546:53;6616:18;;3600:53:17::1;6293:347:18::0;3600:53:17::1;3667:19;3696:13;3703:5:::0;;3696:13:::1;:::i;:::-;3689:21;;::::0;-1:-1:-1;3732:24:17::1;::::0;::::1;::::0;::::1;;3724:63;;;::::0;-1:-1:-1;;;3724:63:17;;7221:2:18;3724:63:17::1;::::0;::::1;7203:21:18::0;7260:2;7240:18;;;7233:30;7299:28;7279:18;;;7272:56;7345:18;;3724:63:17::1;7019:350:18::0;3724:63:17::1;3812:12:::0;-1:-1:-1;3564:271:17::1;3849:31;3870:9;;::::0;::::1;:3:::0;:9:::1;:::i;:::-;-1:-1:-1::0;;;;;934:22:2;685:42;934:22;;854:109;3849:31:17::1;3845:663;;;-1:-1:-1::0;;;;;3905:8:17::1;3896:29;;3933:9:::0;3961:8;3933:9;4026:6;4703:15;3896:203:::1;::::0;-1:-1:-1;;;;;;3896:203:17::1;::::0;;;;;;-1:-1:-1;;;;;7645:55:18;;;3896:203:17::1;::::0;::::1;7627:74:18::0;7717:18;;;7710:34;;;;7763:18;7817:15;;;7797:18;;;7790:43;7869:15;7849:18;;;7842:43;3896:203:17::1;7922:23:18::0;;7901:19;;;7894:52;7599:19;;3896:203:17::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;3845:663;;;4130:57;4156:9;;::::0;::::1;:3:::0;:9:::1;:::i;:::-;4167:8;4177:9;4130:25;:57::i;:::-;-1:-1:-1::0;;;;;;4241:8:17::1;4232:23;;4273:8:::0;4299:9:::1;;::::0;::::1;:3:::0;:9:::1;:::i;:::-;4326::::0;4365:6;4703:15;4232:206:::1;::::0;-1:-1:-1;;;;;;4232:206:17::1;::::0;;;;;;-1:-1:-1;;;;;8317:15:18;;;4232:206:17::1;::::0;::::1;8299:34:18::0;8369:15;;;;8349:18;;;8342:43;8401:18;;;8394:34;;;;8447:18;8501:15;;;8481:18;;;8474:43;8554:15;8533:19;;;8526:44;4232:206:17::1;8607:23:18::0;;8586:19;;;8579:52;8210:19;;4232:206:17::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;4452:45:17::1;::::0;-1:-1:-1;4477:9:17::1;::::0;-1:-1:-1;;4477:9:17::1;::::0;::::1;:3:::0;:9:::1;:::i;:::-;4488:8;4452:24;:45::i;:::-;3414:1100;415:88:1::0;685:42:2;470:10:1;482:20;:8;:18;:20::i;:::-;415:28;:88::i;:::-;3123:1391:17;;;;;;;;;:::o;925:165:7:-;654:22:8;797:33;-1:-1:-1;;;;;797:33:8;995:53:7;;;;;1037:10;995:53;;;810:74:18;-1:-1:-1;;;;;995:41:7;;;;;;;783:18:18;;995:53:7;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;987:96;;;;-1:-1:-1;;;987:96:7;;9126:2:18;987:96:7;;;9108:21:18;9165:2;9145:18;;;9138:30;9204:32;9184:18;;;9177:60;9254:18;;987:96:7;8924:354:18;3537:140:2;3620:7;786;797:1;786:12;782:49;;3537:140;;;:::o;782:49::-;3639:31:::1;-1:-1:-1::0;;;;;3639:22:2;::::1;3662:7:::0;3639:22:::1;:31::i;1124:175:13:-:0;1233:58;;-1:-1:-1;;;;;9475:55:18;;1233:58:13;;;9457:74:18;9547:18;;;9540:34;;;1206:86:13;;1226:5;;1256:23;;9430:18:18;;1233:58:13;;;;-1:-1:-1;;1233:58:13;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;1233:58:13;;;;;;;;;;1206:19;:86::i;1520:807:2:-;1688:7;782:49;;814:7;782:49;685:42;-1:-1:-1;;;;;934:22:2;;;1707:614:::1;;-1:-1:-1::0;;;;;2134:18:2;::::1;3841:10:::0;2134:18:::1;2126:60;;;::::0;-1:-1:-1;;;2126:60:2;;9787:2:18;2126:60:2::1;::::0;::::1;9769:21:18::0;9826:2;9806:18;;;9799:30;9865:31;9845:18;;;9838:59;9914:18;;2126:60:2::1;9585:353:18::0;2126:60:2::1;2200:23;:8:::0;2215:7;2200:14:::1;:23::i;:::-;1707:614;;;2254:56;-1:-1:-1::0;;;;;2254:31:2;::::1;2286:5:::0;3756:4;2302:7;2254:31:::1;:56::i;:::-;1520:807:::0;;;;;:::o;4768:240:17:-;4845:6;;4954:14;;;;1991:9;4884:31;4901:14;;;;4954;4884:31;:::i;:::-;4883:67;;;;:::i;:::-;4882:86;;;;:::i;:::-;4863:105;4768:240;-1:-1:-1;;;4768:240:17:o;2613:347:2:-;2756:17;2738:7;782:49;;814:7;782:49;685:42;-1:-1:-1;;;;;934:22:2;;;2785:169:::1;;2833:7;2821:19;;2785:169;;;2883:1;::::0;-1:-1:-1;2898:45:2::1;-1:-1:-1::0;;;;;2898:26:2;::::1;2925:8:::0;2935:7;2898:26:::1;:45::i;:::-;2613:347:::0;;;;;;:::o;2966:168::-;685:42;-1:-1:-1;;;;;934:22:2;;;3041:87;;3078:39;-1:-1:-1;;;;;3078:26:2;;3105:8;3115:1;3078:26;:39::i;287:146:0:-;404:22;;366:7;;392:34;;:9;:34;:::i;:::-;385:41;287:146;-1:-1:-1;;287:146:0:o;2736:273:10:-;2850:6;2825:21;:31;;2817:68;;;;-1:-1:-1;;;2817:68:10;;10730:2:18;2817:68:10;;;10712:21:18;10769:2;10749:18;;;10742:30;10808:26;10788:18;;;10781:54;10852:18;;2817:68:10;10528:348:18;2817:68:10;2897:12;2915:9;-1:-1:-1;;;;;2915:14:10;2937:6;2915:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2896:52;;;2966:7;2958:44;;;;-1:-1:-1;;;2958:44:10;;11293:2:18;2958:44:10;;;11275:21:18;11332:2;11312:18;;;11305:30;11371:26;11351:18;;;11344:54;11415:18;;2958:44:10;11091:348:18;3876:683:13;4295:23;4321:62;4349:4;4321:62;;;;;;;;;;;;;;;;;4329:5;-1:-1:-1;;;;;4321:27:13;;;:62;;;;;:::i;:::-;4397:17;;4295:88;;-1:-1:-1;4397:21:13;4393:160;;4492:10;4481:30;;;;;;;;;;;;:::i;:::-;4473:69;;;;-1:-1:-1;;;4473:69:13;;11646:2:18;4473:69:13;;;11628:21:18;11685:2;11665:18;;;11658:30;11724:28;11704:18;;;11697:56;11770:18;;4473:69:13;11444:350:18;439:209:0;562:6;539:19;549:8;539:9;:19::i;:::-;:29;;531:68;;;;-1:-1:-1;;;531:68:0;;12001:2:18;531:68:0;;;11983:21:18;12040:2;12020:18;;;12013:30;12079:28;12059:18;;;12052:56;12125:18;;531:68:0;11799:350:18;531:68:0;635:6;609:8;:22;;:32;;;;;;;:::i;:::-;;;-1:-1:-1;;;439:209:0:o;1305:203:13:-;1432:68;;-1:-1:-1;;;;;12565:15:18;;;1432:68:13;;;12547:34:18;12617:15;;12597:18;;;12590:43;12649:18;;;12642:34;;;1405:96:13;;1425:5;;1455:27;;12459:18:18;;1432:68:13;12284:398:18;1768:516:13;2080:10;;;2079:62;;-1:-1:-1;2096:39:13;;;;;2120:4;2096:39;;;12922:34:18;-1:-1:-1;;;;;12992:15:18;;;12972:18;;;12965:43;2096:15:13;;;;;12834:18:18;;2096:39:13;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;2079:62;2071:106;;;;-1:-1:-1;;;2071:106:13;;13410:2:18;2071:106:13;;;13392:21:18;13449:2;13429:18;;;13422:30;13488:33;13468:18;;;13461:61;13539:18;;2071:106:13;13208:355:18;2071:106:13;2214:62;;-1:-1:-1;;;;;9475:55:18;;2214:62:13;;;9457:74:18;9547:18;;;9540:34;;;2187:90:13;;2207:5;;2237:22;;9430:18:18;;2214:62:13;9283:297:18;4151:223:10;4284:12;4315:52;4337:6;4345:4;4351:1;4354:12;4315:21;:52::i;:::-;4308:59;4151:223;-1:-1:-1;;;;4151:223:10:o;5196:439::-;5361:12;5418:5;5393:21;:30;;5385:74;;;;-1:-1:-1;;;5385:74:10;;13770:2:18;5385:74:10;;;13752:21:18;13809:2;13789:18;;;13782:30;13848:33;13828:18;;;13821:61;13899:18;;5385:74:10;13568:355:18;5385:74:10;5470:12;5484:23;5511:6;-1:-1:-1;;;;;5511:11:10;5530:5;5537:4;5511:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5469:73;;;;5559:69;5586:6;5594:7;5603:10;5615:12;5559:26;:69::i;:::-;5552:76;5196:439;-1:-1:-1;;;;;;;5196:439:10:o;7681:623::-;7861:12;7889:7;7885:413;;;7916:10;:17;7937:1;7916:22;7912:281;;-1:-1:-1;;;;;1789:19:10;;;8123:55;;;;-1:-1:-1;;;8123:55:10;;14677:2:18;8123:55:10;;;14659:21:18;14716:2;14696:18;;;14689:30;14755:26;14735:18;;;14728:54;14799:18;;8123:55:10;14475:348:18;8123:55:10;-1:-1:-1;8213:10:10;8206:17;;7885:413;8254:33;8262:10;8274:12;8985:17;;:21;8981:379;;9213:10;9207:17;9269:15;9256:10;9252:2;9248:19;9241:44;8981:379;9336:12;9329:20;;-1:-1:-1;;;9329:20:10;;;;;;;;:::i;14:645:18:-;127:6;135;188:2;176:9;167:7;163:23;159:32;156:52;;;204:1;201;194:12;156:52;244:9;231:23;273:18;314:2;306:6;303:14;300:34;;;330:1;327;320:12;300:34;368:6;357:9;353:22;343:32;;413:7;406:4;402:2;398:13;394:27;384:55;;435:1;432;425:12;384:55;475:2;462:16;501:2;493:6;490:14;487:34;;;517:1;514;507:12;487:34;573:7;568:2;560:4;552:6;548:17;544:2;540:26;536:35;533:48;530:68;;;594:1;591;584:12;530:68;625:2;617:11;;;;;647:6;;-1:-1:-1;14:645:18;;-1:-1:-1;;;;14:645:18:o;895:388::-;982:6;1035:2;1023:9;1014:7;1010:23;1006:32;1003:52;;;1051:1;1048;1041:12;1003:52;1091:9;1078:23;1124:18;1116:6;1113:30;1110:50;;;1156:1;1153;1146:12;1110:50;1179:22;;1235:3;1217:16;;;1213:26;1210:46;;;1252:1;1249;1242:12;1288:184;-1:-1:-1;;;1337:1:18;1330:88;1437:4;1434:1;1427:15;1461:4;1458:1;1451:15;1477:309;1536:6;1589:2;1577:9;1568:7;1564:23;1560:32;1557:52;;;1605:1;1602;1595:12;1557:52;1644:9;1631:23;-1:-1:-1;;;;;1687:5:18;1683:54;1676:5;1673:65;1663:93;;1752:1;1749;1742:12;2194:184;-1:-1:-1;;;2243:1:18;2236:88;2343:4;2340:1;2333:15;2367:4;2364:1;2357:15;2383:135;2422:3;2443:17;;;2440:43;;2463:18;;:::i;:::-;-1:-1:-1;2510:1:18;2499:13;;2383:135::o;3216:577::-;3338:4;3344:6;3404:11;3391:25;3498:2;3494:7;3483:8;3467:14;3463:29;3459:43;3439:18;3435:68;3425:96;;3517:1;3514;3507:12;3425:96;3544:33;;3596:20;;;-1:-1:-1;3639:18:18;3628:30;;3625:50;;;3671:1;3668;3661:12;3625:50;3704:4;3692:17;;-1:-1:-1;3763:4:18;3751:17;;3735:14;3731:38;3721:49;;3718:69;;;3783:1;3780;3773:12;3718:69;3216:577;;;;;:::o;4150:545::-;4243:4;4249:6;4309:11;4296:25;4403:2;4399:7;4388:8;4372:14;4368:29;4364:43;4344:18;4340:68;4330:96;;4422:1;4419;4412:12;4330:96;4449:33;;4501:20;;;-1:-1:-1;4544:18:18;4533:30;;4530:50;;;4576:1;4573;4566:12;4530:50;4609:4;4597:17;;-1:-1:-1;4660:1:18;4656:14;;;4640;4636:35;4626:46;;4623:66;;;4685:1;4682;4675:12;5412:521;5489:4;5495:6;5555:11;5542:25;5649:2;5645:7;5634:8;5618:14;5614:29;5610:43;5590:18;5586:68;5576:96;;5668:1;5665;5658:12;5576:96;5695:33;;5747:20;;;-1:-1:-1;5790:18:18;5779:30;;5776:50;;;5822:1;5819;5812:12;5776:50;5855:4;5843:17;;-1:-1:-1;5886:14:18;5882:27;;;5872:38;;5869:58;;;5923:1;5920;5913:12;6645:369;-1:-1:-1;;;;;;6765:19:18;;6887:11;;;;6918:1;6910:10;;6907:101;;;6995:2;6989;6982:3;6979:1;6975:11;6972:1;6968:19;6964:28;6960:2;6956:37;6952:46;6943:55;;6907:101;;;6645:369;;;;:::o;8642:277::-;8709:6;8762:2;8750:9;8741:7;8737:23;8733:32;8730:52;;;8778:1;8775;8768:12;8730:52;8810:9;8804:16;8863:5;8856:13;8849:21;8842:5;8839:32;8829:60;;8885:1;8882;8875:12;9943:128;10010:9;;;10031:11;;;10028:37;;;10045:18;;:::i;10076:168::-;10116:7;10182:1;10178;10174:6;10170:14;10167:1;10164:21;10159:1;10152:9;10145:17;10141:45;10138:71;;;10189:18;;:::i;:::-;-1:-1:-1;10229:9:18;;10076:168::o;10249:274::-;10289:1;10315;10305:189;;-1:-1:-1;;;10347:1:18;10340:88;10451:4;10448:1;10441:15;10479:4;10476:1;10469:15;10305:189;-1:-1:-1;10508:9:18;;10249:274::o;12154:125::-;12219:9;;;12240:10;;;12237:36;;;12253:18;;:::i;13019:184::-;13089:6;13142:2;13130:9;13121:7;13117:23;13113:32;13110:52;;;13158:1;13155;13148:12;13110:52;-1:-1:-1;13181:16:18;;13019:184;-1:-1:-1;13019:184:18:o;13928:250::-;14013:1;14023:113;14037:6;14034:1;14031:13;14023:113;;;14113:11;;;14107:18;14094:11;;;14087:39;14059:2;14052:10;14023:113;;;-1:-1:-1;;14170:1:18;14152:16;;14145:27;13928:250::o;14183:287::-;14312:3;14350:6;14344:13;14366:66;14425:6;14420:3;14413:4;14405:6;14401:17;14366:66;:::i;:::-;14448:16;;;;;14183:287;-1:-1:-1;;14183:287:18:o;14828:396::-;14977:2;14966:9;14959:21;14940:4;15009:6;15003:13;15052:6;15047:2;15036:9;15032:18;15025:34;15068:79;15140:6;15135:2;15124:9;15120:18;15115:2;15107:6;15103:15;15068:79;:::i;:::-;15208:2;15187:15;-1:-1:-1;;15183:29:18;15168:45;;;;15215:2;15164:54;;14828:396;-1:-1:-1;;14828:396:18:o

Swarm Source

ipfs://a7eec5fbb8a25ef6e85f227e8b8bfd26d7a616f56b38490b1a27e21c1de58af8
Block Transaction Gas Used Reward
Age Block Fee Address BC Fee Address Voting Power Jailed Incoming
Validator ID :
0 FTM

Amount Staked
0

Amount Delegated
0

Staking Total
0

Staking Start Epoch
0

Staking Start Time
0

Proof of Importance
0

Origination Score
0

Validation Score
0

Active
0

Online
0

Downtime
0 s
Address Amount claimed Rewards Created On Epoch Created On
Block Uncle Number Difficulty Gas Used Reward
Loading
Loading
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.