ETH Price: $3,490.65 (+2.23%)
Gas: 3 Gwei

Contract

0xf384663C04A77A732E7A222C65b33Fe471C7011C
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
0x60806040107160752020-08-23 10:42:251426 days ago1598179345IN
 Create: MooniswapBridge
0 ETH0.0544419176

Latest 25 internal transactions (View All)

Advanced mode:
Parent Transaction Hash Block From To
107285312020-08-25 8:33:401424 days ago1598344420
0xf384663C...471C7011C
7.22950732 ETH
107285312020-08-25 8:33:401424 days ago1598344420
0xf384663C...471C7011C
7.22950732 ETH
107285272020-08-25 8:32:461424 days ago1598344366
0xf384663C...471C7011C
12.69883522 ETH
107285272020-08-25 8:32:461424 days ago1598344366
0xf384663C...471C7011C
12.69883522 ETH
107285242020-08-25 8:31:591424 days ago1598344319
0xf384663C...471C7011C
6.81851229 ETH
107285242020-08-25 8:31:591424 days ago1598344319
0xf384663C...471C7011C
6.81851229 ETH
107285232020-08-25 8:31:041424 days ago1598344264
0xf384663C...471C7011C
12.9169052 ETH
107285232020-08-25 8:31:041424 days ago1598344264
0xf384663C...471C7011C
12.9169052 ETH
107279332020-08-25 6:20:371424 days ago1598336437
0xf384663C...471C7011C
6.11215018 ETH
107279332020-08-25 6:20:371424 days ago1598336437
0xf384663C...471C7011C
6.11215018 ETH
107272582020-08-25 3:47:151424 days ago1598327235
0xf384663C...471C7011C
2.89335796 ETH
107272582020-08-25 3:47:151424 days ago1598327235
0xf384663C...471C7011C
2.89335796 ETH
107271652020-08-25 3:24:371424 days ago1598325877
0xf384663C...471C7011C
3.00660844 ETH
107271652020-08-25 3:24:371424 days ago1598325877
0xf384663C...471C7011C
3.00660844 ETH
107271132020-08-25 3:11:151424 days ago1598325075
0xf384663C...471C7011C
16 ETH
107271132020-08-25 3:11:151424 days ago1598325075
0xf384663C...471C7011C
16 ETH
107265792020-08-25 1:09:531425 days ago1598317793
0xf384663C...471C7011C
7.10094547 ETH
107265792020-08-25 1:09:531425 days ago1598317793
0xf384663C...471C7011C
7.10094547 ETH
107264602020-08-25 0:43:281425 days ago1598316208
0xf384663C...471C7011C
22.46533892 ETH
107264602020-08-25 0:43:281425 days ago1598316208
0xf384663C...471C7011C
22.46533892 ETH
107259402020-08-24 22:49:371425 days ago1598309377
0xf384663C...471C7011C
3.80953215 ETH
107259402020-08-24 22:49:371425 days ago1598309377
0xf384663C...471C7011C
3.80953215 ETH
107257242020-08-24 22:05:571425 days ago1598306757
0xf384663C...471C7011C
3.53909021 ETH
107257242020-08-24 22:05:571425 days ago1598306757
0xf384663C...471C7011C
3.53909021 ETH
107257122020-08-24 22:03:311425 days ago1598306611
0xf384663C...471C7011C
5.38654399 ETH
View All Internal Transactions
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
MooniswapBridge

Compiler Version
v0.5.17+commit.d19bba13

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, Apache-2.0 license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2020-08-23
*/

pragma solidity ^0.5.9;
pragma experimental ABIEncoderV2;

/*

  Copyright 2020 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

/*

  Copyright 2019 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

contract IERC20Token {

    // solhint-disable no-simple-event-func-name
    event Transfer(
        address indexed _from,
        address indexed _to,
        uint256 _value
    );

    event Approval(
        address indexed _owner,
        address indexed _spender,
        uint256 _value
    );

    /// @dev send `value` token to `to` from `msg.sender`
    /// @param _to The address of the recipient
    /// @param _value The amount of token to be transferred
    /// @return True if transfer was successful
    function transfer(address _to, uint256 _value)
        external
        returns (bool);

    /// @dev send `value` token to `to` from `from` on the condition it is approved by `from`
    /// @param _from The address of the sender
    /// @param _to The address of the recipient
    /// @param _value The amount of token to be transferred
    /// @return True if transfer was successful
    function transferFrom(
        address _from,
        address _to,
        uint256 _value
    )
        external
        returns (bool);

    /// @dev `msg.sender` approves `_spender` to spend `_value` tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @param _value The amount of wei to be approved for transfer
    /// @return Always true if the call has enough gas to complete execution
    function approve(address _spender, uint256 _value)
        external
        returns (bool);

    /// @dev Query total supply of token
    /// @return Total supply of token
    function totalSupply()
        external
        view
        returns (uint256);

    /// @param _owner The address from which the balance will be retrieved
    /// @return Balance of owner
    function balanceOf(address _owner)
        external
        view
        returns (uint256);

    /// @param _owner The address of the account owning tokens
    /// @param _spender The address of the account able to transfer the tokens
    /// @return Amount of remaining tokens allowed to spent
    function allowance(address _owner, address _spender)
        external
        view
        returns (uint256);
}

/*

  Copyright 2019 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

contract IEtherToken is
    IERC20Token
{
    function deposit()
        public
        payable;

    function withdraw(uint256 amount)
        public;
}

/*

  Copyright 2019 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

/*

  Copyright 2019 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

library LibRichErrors {

    // bytes4(keccak256("Error(string)"))
    bytes4 internal constant STANDARD_ERROR_SELECTOR =
        0x08c379a0;

    // solhint-disable func-name-mixedcase
    /// @dev ABI encode a standard, string revert error payload.
    ///      This is the same payload that would be included by a `revert(string)`
    ///      solidity statement. It has the function signature `Error(string)`.
    /// @param message The error string.
    /// @return The ABI encoded error.
    function StandardError(
        string memory message
    )
        internal
        pure
        returns (bytes memory)
    {
        return abi.encodeWithSelector(
            STANDARD_ERROR_SELECTOR,
            bytes(message)
        );
    }
    // solhint-enable func-name-mixedcase

    /// @dev Reverts an encoded rich revert reason `errorData`.
    /// @param errorData ABI encoded error data.
    function rrevert(bytes memory errorData)
        internal
        pure
    {
        assembly {
            revert(add(errorData, 0x20), mload(errorData))
        }
    }
}

/*

  Copyright 2019 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

/*

  Copyright 2019 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

library LibBytesRichErrors {

    enum InvalidByteOperationErrorCodes {
        FromLessThanOrEqualsToRequired,
        ToLessThanOrEqualsLengthRequired,
        LengthGreaterThanZeroRequired,
        LengthGreaterThanOrEqualsFourRequired,
        LengthGreaterThanOrEqualsTwentyRequired,
        LengthGreaterThanOrEqualsThirtyTwoRequired,
        LengthGreaterThanOrEqualsNestedBytesLengthRequired,
        DestinationLengthGreaterThanOrEqualSourceLengthRequired
    }

    // bytes4(keccak256("InvalidByteOperationError(uint8,uint256,uint256)"))
    bytes4 internal constant INVALID_BYTE_OPERATION_ERROR_SELECTOR =
        0x28006595;

    // solhint-disable func-name-mixedcase
    function InvalidByteOperationError(
        InvalidByteOperationErrorCodes errorCode,
        uint256 offset,
        uint256 required
    )
        internal
        pure
        returns (bytes memory)
    {
        return abi.encodeWithSelector(
            INVALID_BYTE_OPERATION_ERROR_SELECTOR,
            errorCode,
            offset,
            required
        );
    }
}

library LibBytes {

    using LibBytes for bytes;

    /// @dev Gets the memory address for a byte array.
    /// @param input Byte array to lookup.
    /// @return memoryAddress Memory address of byte array. This
    ///         points to the header of the byte array which contains
    ///         the length.
    function rawAddress(bytes memory input)
        internal
        pure
        returns (uint256 memoryAddress)
    {
        assembly {
            memoryAddress := input
        }
        return memoryAddress;
    }

    /// @dev Gets the memory address for the contents of a byte array.
    /// @param input Byte array to lookup.
    /// @return memoryAddress Memory address of the contents of the byte array.
    function contentAddress(bytes memory input)
        internal
        pure
        returns (uint256 memoryAddress)
    {
        assembly {
            memoryAddress := add(input, 32)
        }
        return memoryAddress;
    }

    /// @dev Copies `length` bytes from memory location `source` to `dest`.
    /// @param dest memory address to copy bytes to.
    /// @param source memory address to copy bytes from.
    /// @param length number of bytes to copy.
    function memCopy(
        uint256 dest,
        uint256 source,
        uint256 length
    )
        internal
        pure
    {
        if (length < 32) {
            // Handle a partial word by reading destination and masking
            // off the bits we are interested in.
            // This correctly handles overlap, zero lengths and source == dest
            assembly {
                let mask := sub(exp(256, sub(32, length)), 1)
                let s := and(mload(source), not(mask))
                let d := and(mload(dest), mask)
                mstore(dest, or(s, d))
            }
        } else {
            // Skip the O(length) loop when source == dest.
            if (source == dest) {
                return;
            }

            // For large copies we copy whole words at a time. The final
            // word is aligned to the end of the range (instead of after the
            // previous) to handle partial words. So a copy will look like this:
            //
            //  ####
            //      ####
            //          ####
            //            ####
            //
            // We handle overlap in the source and destination range by
            // changing the copying direction. This prevents us from
            // overwriting parts of source that we still need to copy.
            //
            // This correctly handles source == dest
            //
            if (source > dest) {
                assembly {
                    // We subtract 32 from `sEnd` and `dEnd` because it
                    // is easier to compare with in the loop, and these
                    // are also the addresses we need for copying the
                    // last bytes.
                    length := sub(length, 32)
                    let sEnd := add(source, length)
                    let dEnd := add(dest, length)

                    // Remember the last 32 bytes of source
                    // This needs to be done here and not after the loop
                    // because we may have overwritten the last bytes in
                    // source already due to overlap.
                    let last := mload(sEnd)

                    // Copy whole words front to back
                    // Note: the first check is always true,
                    // this could have been a do-while loop.
                    // solhint-disable-next-line no-empty-blocks
                    for {} lt(source, sEnd) {} {
                        mstore(dest, mload(source))
                        source := add(source, 32)
                        dest := add(dest, 32)
                    }

                    // Write the last 32 bytes
                    mstore(dEnd, last)
                }
            } else {
                assembly {
                    // We subtract 32 from `sEnd` and `dEnd` because those
                    // are the starting points when copying a word at the end.
                    length := sub(length, 32)
                    let sEnd := add(source, length)
                    let dEnd := add(dest, length)

                    // Remember the first 32 bytes of source
                    // This needs to be done here and not after the loop
                    // because we may have overwritten the first bytes in
                    // source already due to overlap.
                    let first := mload(source)

                    // Copy whole words back to front
                    // We use a signed comparisson here to allow dEnd to become
                    // negative (happens when source and dest < 32). Valid
                    // addresses in local memory will never be larger than
                    // 2**255, so they can be safely re-interpreted as signed.
                    // Note: the first check is always true,
                    // this could have been a do-while loop.
                    // solhint-disable-next-line no-empty-blocks
                    for {} slt(dest, dEnd) {} {
                        mstore(dEnd, mload(sEnd))
                        sEnd := sub(sEnd, 32)
                        dEnd := sub(dEnd, 32)
                    }

                    // Write the first 32 bytes
                    mstore(dest, first)
                }
            }
        }
    }

    /// @dev Returns a slices from a byte array.
    /// @param b The byte array to take a slice from.
    /// @param from The starting index for the slice (inclusive).
    /// @param to The final index for the slice (exclusive).
    /// @return result The slice containing bytes at indices [from, to)
    function slice(
        bytes memory b,
        uint256 from,
        uint256 to
    )
        internal
        pure
        returns (bytes memory result)
    {
        // Ensure that the from and to positions are valid positions for a slice within
        // the byte array that is being used.
        if (from > to) {
            LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(
                LibBytesRichErrors.InvalidByteOperationErrorCodes.FromLessThanOrEqualsToRequired,
                from,
                to
            ));
        }
        if (to > b.length) {
            LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(
                LibBytesRichErrors.InvalidByteOperationErrorCodes.ToLessThanOrEqualsLengthRequired,
                to,
                b.length
            ));
        }

        // Create a new bytes structure and copy contents
        result = new bytes(to - from);
        memCopy(
            result.contentAddress(),
            b.contentAddress() + from,
            result.length
        );
        return result;
    }

    /// @dev Returns a slice from a byte array without preserving the input.
    /// @param b The byte array to take a slice from. Will be destroyed in the process.
    /// @param from The starting index for the slice (inclusive).
    /// @param to The final index for the slice (exclusive).
    /// @return result The slice containing bytes at indices [from, to)
    /// @dev When `from == 0`, the original array will match the slice. In other cases its state will be corrupted.
    function sliceDestructive(
        bytes memory b,
        uint256 from,
        uint256 to
    )
        internal
        pure
        returns (bytes memory result)
    {
        // Ensure that the from and to positions are valid positions for a slice within
        // the byte array that is being used.
        if (from > to) {
            LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(
                LibBytesRichErrors.InvalidByteOperationErrorCodes.FromLessThanOrEqualsToRequired,
                from,
                to
            ));
        }
        if (to > b.length) {
            LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(
                LibBytesRichErrors.InvalidByteOperationErrorCodes.ToLessThanOrEqualsLengthRequired,
                to,
                b.length
            ));
        }

        // Create a new bytes structure around [from, to) in-place.
        assembly {
            result := add(b, from)
            mstore(result, sub(to, from))
        }
        return result;
    }

    /// @dev Pops the last byte off of a byte array by modifying its length.
    /// @param b Byte array that will be modified.
    /// @return The byte that was popped off.
    function popLastByte(bytes memory b)
        internal
        pure
        returns (bytes1 result)
    {
        if (b.length == 0) {
            LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(
                LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanZeroRequired,
                b.length,
                0
            ));
        }

        // Store last byte.
        result = b[b.length - 1];

        assembly {
            // Decrement length of byte array.
            let newLen := sub(mload(b), 1)
            mstore(b, newLen)
        }
        return result;
    }

    /// @dev Tests equality of two byte arrays.
    /// @param lhs First byte array to compare.
    /// @param rhs Second byte array to compare.
    /// @return True if arrays are the same. False otherwise.
    function equals(
        bytes memory lhs,
        bytes memory rhs
    )
        internal
        pure
        returns (bool equal)
    {
        // Keccak gas cost is 30 + numWords * 6. This is a cheap way to compare.
        // We early exit on unequal lengths, but keccak would also correctly
        // handle this.
        return lhs.length == rhs.length && keccak256(lhs) == keccak256(rhs);
    }

    /// @dev Reads an address from a position in a byte array.
    /// @param b Byte array containing an address.
    /// @param index Index in byte array of address.
    /// @return address from byte array.
    function readAddress(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (address result)
    {
        if (b.length < index + 20) {
            LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(
                LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsTwentyRequired,
                b.length,
                index + 20 // 20 is length of address
            ));
        }

        // Add offset to index:
        // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)
        // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)
        index += 20;

        // Read address from array memory
        assembly {
            // 1. Add index to address of bytes array
            // 2. Load 32-byte word from memory
            // 3. Apply 20-byte mask to obtain address
            result := and(mload(add(b, index)), 0xffffffffffffffffffffffffffffffffffffffff)
        }
        return result;
    }

    /// @dev Writes an address into a specific position in a byte array.
    /// @param b Byte array to insert address into.
    /// @param index Index in byte array of address.
    /// @param input Address to put into byte array.
    function writeAddress(
        bytes memory b,
        uint256 index,
        address input
    )
        internal
        pure
    {
        if (b.length < index + 20) {
            LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(
                LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsTwentyRequired,
                b.length,
                index + 20 // 20 is length of address
            ));
        }

        // Add offset to index:
        // 1. Arrays are prefixed by 32-byte length parameter (add 32 to index)
        // 2. Account for size difference between address length and 32-byte storage word (subtract 12 from index)
        index += 20;

        // Store address into array memory
        assembly {
            // The address occupies 20 bytes and mstore stores 32 bytes.
            // First fetch the 32-byte word where we'll be storing the address, then
            // apply a mask so we have only the bytes in the word that the address will not occupy.
            // Then combine these bytes with the address and store the 32 bytes back to memory with mstore.

            // 1. Add index to address of bytes array
            // 2. Load 32-byte word from memory
            // 3. Apply 12-byte mask to obtain extra bytes occupying word of memory where we'll store the address
            let neighbors := and(
                mload(add(b, index)),
                0xffffffffffffffffffffffff0000000000000000000000000000000000000000
            )

            // Make sure input address is clean.
            // (Solidity does not guarantee this)
            input := and(input, 0xffffffffffffffffffffffffffffffffffffffff)

            // Store the neighbors and address into memory
            mstore(add(b, index), xor(input, neighbors))
        }
    }

    /// @dev Reads a bytes32 value from a position in a byte array.
    /// @param b Byte array containing a bytes32 value.
    /// @param index Index in byte array of bytes32 value.
    /// @return bytes32 value from byte array.
    function readBytes32(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (bytes32 result)
    {
        if (b.length < index + 32) {
            LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(
                LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsThirtyTwoRequired,
                b.length,
                index + 32
            ));
        }

        // Arrays are prefixed by a 256 bit length parameter
        index += 32;

        // Read the bytes32 from array memory
        assembly {
            result := mload(add(b, index))
        }
        return result;
    }

    /// @dev Writes a bytes32 into a specific position in a byte array.
    /// @param b Byte array to insert <input> into.
    /// @param index Index in byte array of <input>.
    /// @param input bytes32 to put into byte array.
    function writeBytes32(
        bytes memory b,
        uint256 index,
        bytes32 input
    )
        internal
        pure
    {
        if (b.length < index + 32) {
            LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(
                LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsThirtyTwoRequired,
                b.length,
                index + 32
            ));
        }

        // Arrays are prefixed by a 256 bit length parameter
        index += 32;

        // Read the bytes32 from array memory
        assembly {
            mstore(add(b, index), input)
        }
    }

    /// @dev Reads a uint256 value from a position in a byte array.
    /// @param b Byte array containing a uint256 value.
    /// @param index Index in byte array of uint256 value.
    /// @return uint256 value from byte array.
    function readUint256(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (uint256 result)
    {
        result = uint256(readBytes32(b, index));
        return result;
    }

    /// @dev Writes a uint256 into a specific position in a byte array.
    /// @param b Byte array to insert <input> into.
    /// @param index Index in byte array of <input>.
    /// @param input uint256 to put into byte array.
    function writeUint256(
        bytes memory b,
        uint256 index,
        uint256 input
    )
        internal
        pure
    {
        writeBytes32(b, index, bytes32(input));
    }

    /// @dev Reads an unpadded bytes4 value from a position in a byte array.
    /// @param b Byte array containing a bytes4 value.
    /// @param index Index in byte array of bytes4 value.
    /// @return bytes4 value from byte array.
    function readBytes4(
        bytes memory b,
        uint256 index
    )
        internal
        pure
        returns (bytes4 result)
    {
        if (b.length < index + 4) {
            LibRichErrors.rrevert(LibBytesRichErrors.InvalidByteOperationError(
                LibBytesRichErrors.InvalidByteOperationErrorCodes.LengthGreaterThanOrEqualsFourRequired,
                b.length,
                index + 4
            ));
        }

        // Arrays are prefixed by a 32 byte length field
        index += 32;

        // Read the bytes4 from array memory
        assembly {
            result := mload(add(b, index))
            // Solidity does not require us to clean the trailing bytes.
            // We do it anyway
            result := and(result, 0xFFFFFFFF00000000000000000000000000000000000000000000000000000000)
        }
        return result;
    }

    /// @dev Writes a new length to a byte array.
    ///      Decreasing length will lead to removing the corresponding lower order bytes from the byte array.
    ///      Increasing length may lead to appending adjacent in-memory bytes to the end of the byte array.
    /// @param b Bytes array to write new length to.
    /// @param length New length of byte array.
    function writeLength(bytes memory b, uint256 length)
        internal
        pure
    {
        assembly {
            mstore(b, length)
        }
    }
}

library LibERC20Token {
    bytes constant private DECIMALS_CALL_DATA = hex"313ce567";

    /// @dev Calls `IERC20Token(token).approve()`.
    ///      Reverts if `false` is returned or if the return
    ///      data length is nonzero and not 32 bytes.
    /// @param token The address of the token contract.
    /// @param spender The address that receives an allowance.
    /// @param allowance The allowance to set.
    function approve(
        address token,
        address spender,
        uint256 allowance
    )
        internal
    {
        bytes memory callData = abi.encodeWithSelector(
            IERC20Token(0).approve.selector,
            spender,
            allowance
        );
        _callWithOptionalBooleanResult(token, callData);
    }

    /// @dev Calls `IERC20Token(token).approve()` and sets the allowance to the
    ///      maximum if the current approval is not already >= an amount.
    ///      Reverts if `false` is returned or if the return
    ///      data length is nonzero and not 32 bytes.
    /// @param token The address of the token contract.
    /// @param spender The address that receives an allowance.
    /// @param amount The minimum allowance needed.
    function approveIfBelow(
        address token,
        address spender,
        uint256 amount
    )
        internal
    {
        if (IERC20Token(token).allowance(address(this), spender) < amount) {
            approve(token, spender, uint256(-1));
        }
    }

    /// @dev Calls `IERC20Token(token).transfer()`.
    ///      Reverts if `false` is returned or if the return
    ///      data length is nonzero and not 32 bytes.
    /// @param token The address of the token contract.
    /// @param to The address that receives the tokens
    /// @param amount Number of tokens to transfer.
    function transfer(
        address token,
        address to,
        uint256 amount
    )
        internal
    {
        bytes memory callData = abi.encodeWithSelector(
            IERC20Token(0).transfer.selector,
            to,
            amount
        );
        _callWithOptionalBooleanResult(token, callData);
    }

    /// @dev Calls `IERC20Token(token).transferFrom()`.
    ///      Reverts if `false` is returned or if the return
    ///      data length is nonzero and not 32 bytes.
    /// @param token The address of the token contract.
    /// @param from The owner of the tokens.
    /// @param to The address that receives the tokens
    /// @param amount Number of tokens to transfer.
    function transferFrom(
        address token,
        address from,
        address to,
        uint256 amount
    )
        internal
    {
        bytes memory callData = abi.encodeWithSelector(
            IERC20Token(0).transferFrom.selector,
            from,
            to,
            amount
        );
        _callWithOptionalBooleanResult(token, callData);
    }

    /// @dev Retrieves the number of decimals for a token.
    ///      Returns `18` if the call reverts.
    /// @param token The address of the token contract.
    /// @return tokenDecimals The number of decimals places for the token.
    function decimals(address token)
        internal
        view
        returns (uint8 tokenDecimals)
    {
        tokenDecimals = 18;
        (bool didSucceed, bytes memory resultData) = token.staticcall(DECIMALS_CALL_DATA);
        if (didSucceed && resultData.length == 32) {
            tokenDecimals = uint8(LibBytes.readUint256(resultData, 0));
        }
    }

    /// @dev Retrieves the allowance for a token, owner, and spender.
    ///      Returns `0` if the call reverts.
    /// @param token The address of the token contract.
    /// @param owner The owner of the tokens.
    /// @param spender The address the spender.
    /// @return allowance The allowance for a token, owner, and spender.
    function allowance(address token, address owner, address spender)
        internal
        view
        returns (uint256 allowance_)
    {
        (bool didSucceed, bytes memory resultData) = token.staticcall(
            abi.encodeWithSelector(
                IERC20Token(0).allowance.selector,
                owner,
                spender
            )
        );
        if (didSucceed && resultData.length == 32) {
            allowance_ = LibBytes.readUint256(resultData, 0);
        }
    }

    /// @dev Retrieves the balance for a token owner.
    ///      Returns `0` if the call reverts.
    /// @param token The address of the token contract.
    /// @param owner The owner of the tokens.
    /// @return balance The token balance of an owner.
    function balanceOf(address token, address owner)
        internal
        view
        returns (uint256 balance)
    {
        (bool didSucceed, bytes memory resultData) = token.staticcall(
            abi.encodeWithSelector(
                IERC20Token(0).balanceOf.selector,
                owner
            )
        );
        if (didSucceed && resultData.length == 32) {
            balance = LibBytes.readUint256(resultData, 0);
        }
    }

    /// @dev Executes a call on address `target` with calldata `callData`
    ///      and asserts that either nothing was returned or a single boolean
    ///      was returned equal to `true`.
    /// @param target The call target.
    /// @param callData The abi-encoded call data.
    function _callWithOptionalBooleanResult(
        address target,
        bytes memory callData
    )
        private
    {
        (bool didSucceed, bytes memory resultData) = target.call(callData);
        if (didSucceed) {
            if (resultData.length == 0) {
                return;
            }
            if (resultData.length == 32) {
                uint256 result = LibBytes.readUint256(resultData, 0);
                if (result == 1) {
                    return;
                }
            }
        }
        LibRichErrors.rrevert(resultData);
    }
}

/*

  Copyright 2019 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

contract IWallet {

    bytes4 internal constant LEGACY_WALLET_MAGIC_VALUE = 0xb0671381;

    /// @dev Validates a hash with the `Wallet` signature type.
    /// @param hash Message hash that is signed.
    /// @param signature Proof of signing.
    /// @return magicValue `bytes4(0xb0671381)` if the signature check succeeds.
    function isValidSignature(
        bytes32 hash,
        bytes calldata signature
    )
        external
        view
        returns (bytes4 magicValue);
}

/*

  Copyright 2019 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

contract DeploymentConstants {

    // solhint-disable separate-by-one-line-in-contract

    // Mainnet addresses ///////////////////////////////////////////////////////
    /// @dev Mainnet address of the WETH contract.
    address constant private WETH_ADDRESS = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
    /// @dev Mainnet address of the KyberNetworkProxy contract.
    address constant private KYBER_NETWORK_PROXY_ADDRESS = 0x9AAb3f75489902f3a48495025729a0AF77d4b11e;
    /// @dev Mainnet address of the `UniswapExchangeFactory` contract.
    address constant private UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xc0a47dFe034B400B47bDaD5FecDa2621de6c4d95;
    /// @dev Mainnet address of the `UniswapV2Router01` contract.
    address constant private UNISWAP_V2_ROUTER_01_ADDRESS = 0xf164fC0Ec4E93095b804a4795bBe1e041497b92a;
    /// @dev Mainnet address of the Eth2Dai `MatchingMarket` contract.
    address constant private ETH2DAI_ADDRESS = 0x794e6e91555438aFc3ccF1c5076A74F42133d08D;
    /// @dev Mainnet address of the `ERC20BridgeProxy` contract
    address constant private ERC20_BRIDGE_PROXY_ADDRESS = 0x8ED95d1746bf1E4dAb58d8ED4724f1Ef95B20Db0;
    ///@dev Mainnet address of the `Dai` (multi-collateral) contract
    address constant private DAI_ADDRESS = 0x6B175474E89094C44Da98b954EedeAC495271d0F;
    /// @dev Mainnet address of the `Chai` contract
    address constant private CHAI_ADDRESS = 0x06AF07097C9Eeb7fD685c692751D5C66dB49c215;
    /// @dev Mainnet address of the 0x DevUtils contract.
    address constant private DEV_UTILS_ADDRESS = 0x74134CF88b21383713E096a5ecF59e297dc7f547;
    /// @dev Kyber ETH pseudo-address.
    address constant internal KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
    /// @dev Mainnet address of the dYdX contract.
    address constant private DYDX_ADDRESS = 0x1E0447b19BB6EcFdAe1e4AE1694b0C3659614e4e;
    /// @dev Mainnet address of the GST2 contract
    address constant private GST_ADDRESS = 0x0000000000b3F879cb30FE243b4Dfee438691c04;
    /// @dev Mainnet address of the GST Collector
    address constant private GST_COLLECTOR_ADDRESS = 0x000000D3b08566BE75A6DB803C03C85C0c1c5B96;
    /// @dev Mainnet address of the mStable mUSD contract.
    address constant private MUSD_ADDRESS = 0xe2f2a5C287993345a840Db3B0845fbC70f5935a5;
    /// @dev Mainnet address of the Mooniswap Registry contract
    address constant private MOONISWAP_REGISTRY = 0x71CD6666064C3A1354a3B4dca5fA1E2D3ee7D303;

    // // Ropsten addresses ///////////////////////////////////////////////////////
    // /// @dev Mainnet address of the WETH contract.
    // address constant private WETH_ADDRESS = 0xc778417E063141139Fce010982780140Aa0cD5Ab;
    // /// @dev Mainnet address of the KyberNetworkProxy contract.
    // address constant private KYBER_NETWORK_PROXY_ADDRESS = 0xd719c34261e099Fdb33030ac8909d5788D3039C4;
    // /// @dev Mainnet address of the `UniswapExchangeFactory` contract.
    // address constant private UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0x9c83dCE8CA20E9aAF9D3efc003b2ea62aBC08351;
    // /// @dev Mainnet address of the `UniswapV2Router01` contract.
    // address constant private UNISWAP_V2_ROUTER_01_ADDRESS = 0xf164fC0Ec4E93095b804a4795bBe1e041497b92a;
    // /// @dev Mainnet address of the Eth2Dai `MatchingMarket` contract.
    // address constant private ETH2DAI_ADDRESS = address(0);
    // /// @dev Mainnet address of the `ERC20BridgeProxy` contract
    // address constant private ERC20_BRIDGE_PROXY_ADDRESS = 0xb344afeD348de15eb4a9e180205A2B0739628339;
    // ///@dev Mainnet address of the `Dai` (multi-collateral) contract
    // address constant private DAI_ADDRESS = address(0);
    // /// @dev Mainnet address of the `Chai` contract
    // address constant private CHAI_ADDRESS = address(0);
    // /// @dev Mainnet address of the 0x DevUtils contract.
    // address constant private DEV_UTILS_ADDRESS = 0xC812AF3f3fBC62F76ea4262576EC0f49dB8B7f1c;
    // /// @dev Kyber ETH pseudo-address.
    // address constant internal KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
    // /// @dev Mainnet address of the dYdX contract.
    // address constant private DYDX_ADDRESS = address(0);
    // /// @dev Mainnet address of the GST2 contract
    // address constant private GST_ADDRESS = address(0);
    // /// @dev Mainnet address of the GST Collector
    // address constant private GST_COLLECTOR_ADDRESS = address(0);
    // /// @dev Mainnet address of the mStable mUSD contract.
    // address constant private MUSD_ADDRESS = 0x4E1000616990D83e56f4b5fC6CC8602DcfD20459;

    // // Rinkeby addresses ///////////////////////////////////////////////////////
    // /// @dev Mainnet address of the WETH contract.
    // address constant private WETH_ADDRESS = 0xc778417E063141139Fce010982780140Aa0cD5Ab;
    // /// @dev Mainnet address of the KyberNetworkProxy contract.
    // address constant private KYBER_NETWORK_PROXY_ADDRESS = 0x0d5371e5EE23dec7DF251A8957279629aa79E9C5;
    // /// @dev Mainnet address of the `UniswapExchangeFactory` contract.
    // address constant private UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xf5D915570BC477f9B8D6C0E980aA81757A3AaC36;
    // /// @dev Mainnet address of the `UniswapV2Router01` contract.
    // address constant private UNISWAP_V2_ROUTER_01_ADDRESS = 0xf164fC0Ec4E93095b804a4795bBe1e041497b92a;
    // /// @dev Mainnet address of the Eth2Dai `MatchingMarket` contract.
    // address constant private ETH2DAI_ADDRESS = address(0);
    // /// @dev Mainnet address of the `ERC20BridgeProxy` contract
    // address constant private ERC20_BRIDGE_PROXY_ADDRESS = 0xA2AA4bEFED748Fba27a3bE7Dfd2C4b2c6DB1F49B;
    // ///@dev Mainnet address of the `Dai` (multi-collateral) contract
    // address constant private DAI_ADDRESS = address(0);
    // /// @dev Mainnet address of the `Chai` contract
    // address constant private CHAI_ADDRESS = address(0);
    // /// @dev Mainnet address of the 0x DevUtils contract.
    // address constant private DEV_UTILS_ADDRESS = 0x46B5BC959e8A754c0256FFF73bF34A52Ad5CdfA9;
    // /// @dev Kyber ETH pseudo-address.
    // address constant internal KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
    // /// @dev Mainnet address of the dYdX contract.
    // address constant private DYDX_ADDRESS = address(0);
    // /// @dev Mainnet address of the GST2 contract
    // address constant private GST_ADDRESS = address(0);
    // /// @dev Mainnet address of the GST Collector
    // address constant private GST_COLLECTOR_ADDRESS = address(0);
    // /// @dev Mainnet address of the mStable mUSD contract.
    // address constant private MUSD_ADDRESS = address(0);

    // // Kovan addresses /////////////////////////////////////////////////////////
    // /// @dev Kovan address of the WETH contract.
    // address constant private WETH_ADDRESS = 0xd0A1E359811322d97991E03f863a0C30C2cF029C;
    // /// @dev Kovan address of the KyberNetworkProxy contract.
    // address constant private KYBER_NETWORK_PROXY_ADDRESS = 0x692f391bCc85cefCe8C237C01e1f636BbD70EA4D;
    // /// @dev Kovan address of the `UniswapExchangeFactory` contract.
    // address constant private UNISWAP_EXCHANGE_FACTORY_ADDRESS = 0xD3E51Ef092B2845f10401a0159B2B96e8B6c3D30;
    // /// @dev Kovan address of the `UniswapV2Router01` contract.
    // address constant private UNISWAP_V2_ROUTER_01_ADDRESS = 0xf164fC0Ec4E93095b804a4795bBe1e041497b92a;
    // /// @dev Kovan address of the Eth2Dai `MatchingMarket` contract.
    // address constant private ETH2DAI_ADDRESS = 0xe325acB9765b02b8b418199bf9650972299235F4;
    // /// @dev Kovan address of the `ERC20BridgeProxy` contract
    // address constant private ERC20_BRIDGE_PROXY_ADDRESS = 0x3577552C1Fb7A44aD76BeEB7aB53251668A21F8D;
    // /// @dev Kovan address of the `Chai` contract
    // address constant private CHAI_ADDRESS = address(0);
    // /// @dev Kovan address of the `Dai` (multi-collateral) contract
    // address constant private DAI_ADDRESS = 0x4F96Fe3b7A6Cf9725f59d353F723c1bDb64CA6Aa;
    // /// @dev Kovan address of the 0x DevUtils contract.
    // address constant private DEV_UTILS_ADDRESS = 0x9402639A828BdF4E9e4103ac3B69E1a6E522eB59;
    // /// @dev Kyber ETH pseudo-address.
    // address constant internal KYBER_ETH_ADDRESS = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE;
    // /// @dev Kovan address of the dYdX contract.
    // address constant private DYDX_ADDRESS = address(0);
    // /// @dev Kovan address of the GST2 contract
    // address constant private GST_ADDRESS = address(0);
    // /// @dev Kovan address of the GST Collector
    // address constant private GST_COLLECTOR_ADDRESS = address(0);
    // /// @dev Mainnet address of the mStable mUSD contract.
    // address constant private MUSD_ADDRESS = address(0);

    /// @dev Overridable way to get the `KyberNetworkProxy` address.
    /// @return kyberAddress The `IKyberNetworkProxy` address.
    function _getKyberNetworkProxyAddress()
        internal
        view
        returns (address kyberAddress)
    {
        return KYBER_NETWORK_PROXY_ADDRESS;
    }

    /// @dev Overridable way to get the WETH address.
    /// @return wethAddress The WETH address.
    function _getWethAddress()
        internal
        view
        returns (address wethAddress)
    {
        return WETH_ADDRESS;
    }

    /// @dev Overridable way to get the `UniswapExchangeFactory` address.
    /// @return uniswapAddress The `UniswapExchangeFactory` address.
    function _getUniswapExchangeFactoryAddress()
        internal
        view
        returns (address uniswapAddress)
    {
        return UNISWAP_EXCHANGE_FACTORY_ADDRESS;
    }

    /// @dev Overridable way to get the `UniswapV2Router01` address.
    /// @return uniswapRouterAddress The `UniswapV2Router01` address.
    function _getUniswapV2Router01Address()
        internal
        view
        returns (address uniswapRouterAddress)
    {
        return UNISWAP_V2_ROUTER_01_ADDRESS;
    }

    /// @dev An overridable way to retrieve the Eth2Dai `MatchingMarket` contract.
    /// @return eth2daiAddress The Eth2Dai `MatchingMarket` contract.
    function _getEth2DaiAddress()
        internal
        view
        returns (address eth2daiAddress)
    {
        return ETH2DAI_ADDRESS;
    }

    /// @dev An overridable way to retrieve the `ERC20BridgeProxy` contract.
    /// @return erc20BridgeProxyAddress The `ERC20BridgeProxy` contract.
    function _getERC20BridgeProxyAddress()
        internal
        view
        returns (address erc20BridgeProxyAddress)
    {
        return ERC20_BRIDGE_PROXY_ADDRESS;
    }

    /// @dev An overridable way to retrieve the `Dai` contract.
    /// @return daiAddress The `Dai` contract.
    function _getDaiAddress()
        internal
        view
        returns (address daiAddress)
    {
        return DAI_ADDRESS;
    }

    /// @dev An overridable way to retrieve the `Chai` contract.
    /// @return chaiAddress The `Chai` contract.
    function _getChaiAddress()
        internal
        view
        returns (address chaiAddress)
    {
        return CHAI_ADDRESS;
    }

    /// @dev An overridable way to retrieve the 0x `DevUtils` contract address.
    /// @return devUtils The 0x `DevUtils` contract address.
    function _getDevUtilsAddress()
        internal
        view
        returns (address devUtils)
    {
        return DEV_UTILS_ADDRESS;
    }

    /// @dev Overridable way to get the DyDx contract.
    /// @return exchange The DyDx exchange contract.
    function _getDydxAddress()
        internal
        view
        returns (address dydxAddress)
    {
        return DYDX_ADDRESS;
    }

    /// @dev An overridable way to retrieve the GST2 contract address.
    /// @return gst The GST contract.
    function _getGstAddress()
        internal
        view
        returns (address gst)
    {
        return GST_ADDRESS;
    }

    /// @dev An overridable way to retrieve the GST Collector address.
    /// @return collector The GST collector address.
    function _getGstCollectorAddress()
        internal
        view
        returns (address collector)
    {
        return GST_COLLECTOR_ADDRESS;
    }

    /// @dev An overridable way to retrieve the mStable mUSD address.
    /// @return musd The mStable mUSD address.
    function _getMUsdAddress()
        internal
        view
        returns (address musd)
    {
        return MUSD_ADDRESS;
    }

    /// @dev An overridable way to retrieve the Mooniswap registry address.
    /// @return musd The Mooniswap registry address.
    function _getMooniswapAddress()
        internal
        view
        returns (address registry)
    {
        return MOONISWAP_REGISTRY;
    }
}

/*

  Copyright 2019 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

contract IERC20Bridge {

    /// @dev Result of a successful bridge call.
    bytes4 constant internal BRIDGE_SUCCESS = 0xdc1600f3;

    /// @dev Emitted when a trade occurs.
    /// @param inputToken The token the bridge is converting from.
    /// @param outputToken The token the bridge is converting to.
    /// @param inputTokenAmount Amount of input token.
    /// @param outputTokenAmount Amount of output token.
    /// @param from The `from` address in `bridgeTransferFrom()`
    /// @param to The `to` address in `bridgeTransferFrom()`
    event ERC20BridgeTransfer(
        address inputToken,
        address outputToken,
        uint256 inputTokenAmount,
        uint256 outputTokenAmount,
        address from,
        address to
    );

    /// @dev Transfers `amount` of the ERC20 `tokenAddress` from `from` to `to`.
    /// @param tokenAddress The address of the ERC20 token to transfer.
    /// @param from Address to transfer asset from.
    /// @param to Address to transfer asset to.
    /// @param amount Amount of asset to transfer.
    /// @param bridgeData Arbitrary asset data needed by the bridge contract.
    /// @return success The magic bytes `0xdc1600f3` if successful.
    function bridgeTransferFrom(
        address tokenAddress,
        address from,
        address to,
        uint256 amount,
        bytes calldata bridgeData
    )
        external
        returns (bytes4 success);
}

/*

  Copyright 2020 ZeroEx Intl.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

*/

interface IMooniswapRegistry {

    function pools(address token1, address token2) external view returns(address);
}

interface IMooniswap {

    function swap(
        address fromToken,
        address destToken,
        uint256 amount,
        uint256 minReturn,
        address referral
    )
        external
        payable
        returns(uint256 returnAmount);
}

// solhint-disable space-after-comma
// solhint-disable not-rely-on-time
contract MooniswapBridge is
    IERC20Bridge,
    IWallet,
    DeploymentConstants
{

    struct TransferState {
        IMooniswap pool;
        uint256 fromTokenBalance;
        IEtherToken weth;
        uint256 boughtAmount;
        address fromTokenAddress;
        address toTokenAddress;
    }

    // solhint-disable no-empty-blocks
    /// @dev Payable fallback to receive ETH from uniswap.
    function ()
        external
        payable
    {}

    /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
    ///      `toTokenAddress` tokens by selling the entirety of the `fromTokenAddress`
    ///      token encoded in the bridge data.
    /// @param toTokenAddress The token to buy and transfer to `to`.
    /// @param from The maker (this contract).
    /// @param to The recipient of the bought tokens.
    /// @param amount Minimum amount of `toTokenAddress` tokens to buy.
    /// @param bridgeData The abi-encoded path of token addresses. Last element must be toTokenAddress
    /// @return success The magic bytes if successful.
    function bridgeTransferFrom(
        address toTokenAddress,
        address from,
        address to,
        uint256 amount,
        bytes calldata bridgeData
    )
        external
        returns (bytes4 success)
    {
        // State memory object to avoid stack overflows.
        TransferState memory state;
        // Decode the bridge data to get the `fromTokenAddress`.
        address fromTokenAddress = abi.decode(bridgeData, (address));
        // Get the weth contract.
        state.weth = IEtherToken(_getWethAddress());
        // Get our balance of `fromTokenAddress` token.
        state.fromTokenBalance = IERC20Token(fromTokenAddress).balanceOf(address(this));

        state.fromTokenAddress = fromTokenAddress == address(state.weth) ? address(0) : fromTokenAddress;
        state.toTokenAddress = toTokenAddress == address(state.weth) ? address(0) : toTokenAddress;
        state.pool = IMooniswap(
            IMooniswapRegistry(_getMooniswapAddress()).pools(
                state.fromTokenAddress,
                state.toTokenAddress
            )
        );

        // withdraw WETH to ETH
        if (state.fromTokenAddress == address(0)) {
            state.weth.withdraw(state.fromTokenBalance);
        } else {
            // Grant the pool an allowance.
            LibERC20Token.approveIfBelow(
                state.fromTokenAddress,
                address(state.pool),
                state.fromTokenBalance
            );
        }
        uint256 ethValue = state.fromTokenAddress == address(0) ? state.fromTokenBalance : 0;
        state.boughtAmount = state.pool.swap.value(ethValue)(
            state.fromTokenAddress,
            state.toTokenAddress,
            state.fromTokenBalance,
            amount,
            address(0)
        );
        // Deposit to WETH
        if (state.toTokenAddress == address(0)) {
            state.weth.deposit.value(state.boughtAmount)();
        }

        // Transfer funds to `to`
        IERC20Token(toTokenAddress).transfer(to, state.boughtAmount);

        emit ERC20BridgeTransfer(
            // input token
            fromTokenAddress,
            // output token
            toTokenAddress,
            // input token amount
            state.fromTokenBalance,
            // output token amount
            state.boughtAmount,
            from,
            to
        );

        return BRIDGE_SUCCESS;
    }

    /// @dev `SignatureType.Wallet` callback, so that this bridge can be the maker
    ///      and sign for itself in orders. Always succeeds.
    /// @return magicValue Success bytes, always.
    function isValidSignature(
        bytes32,
        bytes calldata
    )
        external
        view
        returns (bytes4 magicValue)
    {
        return LEGACY_WALLET_MAGIC_VALUE;
    }
}

Contract Security Audit

Contract ABI

[{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"inputToken","type":"address"},{"indexed":false,"internalType":"address","name":"outputToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"inputTokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"outputTokenAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"}],"name":"ERC20BridgeTransfer","type":"event"},{"payable":true,"stateMutability":"payable","type":"fallback"},{"constant":false,"inputs":[{"internalType":"address","name":"toTokenAddress","type":"address"},{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"bridgeData","type":"bytes"}],"name":"bridgeTransferFrom","outputs":[{"internalType":"bytes4","name":"success","type":"bytes4"}],"payable":false,"stateMutability":"nonpayable","type":"function"},{"constant":true,"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"isValidSignature","outputs":[{"internalType":"bytes4","name":"magicValue","type":"bytes4"}],"payable":false,"stateMutability":"view","type":"function"}]

608060405234801561001057600080fd5b50610c00806100206000396000f3fe6080604052600436106100295760003560e01c80631626ba7e1461002b578063c2df82e614610061575b005b34801561003757600080fd5b5061004b6100463660046108f8565b610081565b6040516100589190610aba565b60405180910390f35b34801561006d57600080fd5b5061004b61007c36600461084a565b610091565b63b067138160e01b5b9392505050565b600061009b610751565b60006100a98486018661082c565b90506100b36104d1565b6001600160a01b03908116604080850191909152516370a0823160e01b8152908216906370a08231906100ea9030906004016109da565b60206040518083038186803b15801561010257600080fd5b505afa158015610116573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061013a919081019061094e565b602083015260408201516001600160a01b0382811691161461015c578061015f565b60005b6001600160a01b03908116608084015260408301518a82169116146101845788610187565b60005b6001600160a01b031660a083015261019d6104e9565b6001600160a01b031663901754d783608001518460a001516040518363ffffffff1660e01b81526004016101d29291906109e8565b60206040518083038186803b1580156101ea57600080fd5b505afa1580156101fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506102229190810190610806565b6001600160a01b0390811683526080830151166102a45781604001516001600160a01b0316632e1a7d4d83602001516040518263ffffffff1660e01b815260040161026d9190610af0565b600060405180830381600087803b15801561028757600080fd5b505af115801561029b573d6000803e3d6000fd5b505050506102bb565b6102bb826080015183600001518460200151610501565b60808201516000906001600160a01b0316156102d85760006102de565b82602001515b905082600001516001600160a01b031663d5bcb9b58285608001518660a0015187602001518c60006040518763ffffffff1660e01b8152600401610326959493929190610a03565b6020604051808303818588803b15801561033f57600080fd5b505af1158015610353573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250610378919081019061094e565b606084015260a08301516001600160a01b03166103ec5782604001516001600160a01b031663d0e30db084606001516040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b50505050505b606083015160405163a9059cbb60e01b81526001600160a01b038c169163a9059cbb9161041d918c91600401610a9f565b602060405180830381600087803b15801561043757600080fd5b505af115801561044b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061046f91908101906108da565b507f349fc08071558d8e3aa92dec9396e4e9f2dfecd6bb9065759d1932e7da43b8a9828b856020015186606001518d8d6040516104b196959493929190610a45565b60405180910390a15063dc1600f360e01b925050505b9695505050505050565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290565b7371cd6666064c3a1354a3b4dca5fa1e2d3ee7d30390565b604051636eb1769f60e11b815281906001600160a01b0385169063dd62ed3e9061053190309087906004016109e8565b60206040518083038186803b15801561054957600080fd5b505afa15801561055d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610581919081019061094e565b1015610594576105948383600019610599565b505050565b60405160609063095ea7b360e01b906105b89085908590602401610a9f565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915290506105f684826105fc565b50505050565b60006060836001600160a01b03168360405161061891906109ce565b6000604051808303816000865af19150503d8060008114610655576040519150601f19603f3d011682016040523d82523d6000602084013e61065a565b606091505b5091509150811561069e5780516106725750506106a7565b80516020141561069e5760006106898260006106ab565b9050806001141561069c575050506106a7565b505b6105f6816106c0565b5050565b60006106b783836106c8565b90505b92915050565b805160208201fd5b600081602001835110156106ee576106ee6106e960058551856020016106f7565b6106c0565b50016020015190565b6060632800659560e01b84848460405160240161071693929190610ac8565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915290509392505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b80356106ba81610b97565b80516106ba81610b97565b80516106ba81610bab565b80356106ba81610bb4565b60008083601f8401126107c457600080fd5b50813567ffffffffffffffff8111156107dc57600080fd5b6020830191508360018202830111156107f457600080fd5b9250929050565b80516106ba81610bb4565b60006020828403121561081857600080fd5b60006108248484610791565b949350505050565b60006020828403121561083e57600080fd5b60006108248484610786565b60008060008060008060a0878903121561086357600080fd5b600061086f8989610786565b965050602061088089828a01610786565b955050604061089189828a01610786565b94505060606108a289828a016107a7565b935050608087013567ffffffffffffffff8111156108bf57600080fd5b6108cb89828a016107b2565b92509250509295509295509295565b6000602082840312156108ec57600080fd5b6000610824848461079c565b60008060006040848603121561090d57600080fd5b600061091986866107a7565b935050602084013567ffffffffffffffff81111561093657600080fd5b610942868287016107b2565b92509250509250925092565b60006020828403121561096057600080fd5b600061082484846107fb565b61097581610b3d565b82525050565b61097581610b07565b61097581610b1a565b600061099882610afe565b6109a28185610b02565b93506109b2818560208601610b5e565b9290920192915050565b61097581610b48565b61097581610b17565b600061008a828461098d565b602081016106ba828461096c565b604081016109f6828561097b565b61008a602083018461097b565b60a08101610a11828861097b565b610a1e602083018761097b565b610a2b60408301866109c5565b610a3860608301856109c5565b6104c7608083018461096c565b60c08101610a53828961097b565b610a60602083018861097b565b610a6d60408301876109c5565b610a7a60608301866109c5565b610a87608083018561097b565b610a9460a083018461097b565b979650505050505050565b60408101610aad828561097b565b61008a60208301846109c5565b602081016106ba8284610984565b60608101610ad682866109bc565b610ae360208301856109c5565b61082460408301846109c5565b602081016106ba82846109c5565b5190565b919050565b60006106ba82610b31565b151590565b90565b6001600160e01b03191690565b80610b0281610b8a565b6001600160a01b031690565b60006106ba82610b53565b60006106ba82610b27565b60006106ba82610b07565b60005b83811015610b79578181015183820152602001610b61565b838111156105f65750506000910152565b60088110610b9457fe5b50565b610ba081610b07565b8114610b9457600080fd5b610ba081610b12565b610ba081610b1756fea365627a7a7231582088034d4797de50606fc409b29605aaee9470fadeaf51709766e29ede6c887d3c6c6578706572696d656e74616cf564736f6c63430005110040

Deployed Bytecode

0x6080604052600436106100295760003560e01c80631626ba7e1461002b578063c2df82e614610061575b005b34801561003757600080fd5b5061004b6100463660046108f8565b610081565b6040516100589190610aba565b60405180910390f35b34801561006d57600080fd5b5061004b61007c36600461084a565b610091565b63b067138160e01b5b9392505050565b600061009b610751565b60006100a98486018661082c565b90506100b36104d1565b6001600160a01b03908116604080850191909152516370a0823160e01b8152908216906370a08231906100ea9030906004016109da565b60206040518083038186803b15801561010257600080fd5b505afa158015610116573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061013a919081019061094e565b602083015260408201516001600160a01b0382811691161461015c578061015f565b60005b6001600160a01b03908116608084015260408301518a82169116146101845788610187565b60005b6001600160a01b031660a083015261019d6104e9565b6001600160a01b031663901754d783608001518460a001516040518363ffffffff1660e01b81526004016101d29291906109e8565b60206040518083038186803b1580156101ea57600080fd5b505afa1580156101fe573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052506102229190810190610806565b6001600160a01b0390811683526080830151166102a45781604001516001600160a01b0316632e1a7d4d83602001516040518263ffffffff1660e01b815260040161026d9190610af0565b600060405180830381600087803b15801561028757600080fd5b505af115801561029b573d6000803e3d6000fd5b505050506102bb565b6102bb826080015183600001518460200151610501565b60808201516000906001600160a01b0316156102d85760006102de565b82602001515b905082600001516001600160a01b031663d5bcb9b58285608001518660a0015187602001518c60006040518763ffffffff1660e01b8152600401610326959493929190610a03565b6020604051808303818588803b15801561033f57600080fd5b505af1158015610353573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250610378919081019061094e565b606084015260a08301516001600160a01b03166103ec5782604001516001600160a01b031663d0e30db084606001516040518263ffffffff1660e01b81526004016000604051808303818588803b1580156103d257600080fd5b505af11580156103e6573d6000803e3d6000fd5b50505050505b606083015160405163a9059cbb60e01b81526001600160a01b038c169163a9059cbb9161041d918c91600401610a9f565b602060405180830381600087803b15801561043757600080fd5b505af115801561044b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525061046f91908101906108da565b507f349fc08071558d8e3aa92dec9396e4e9f2dfecd6bb9065759d1932e7da43b8a9828b856020015186606001518d8d6040516104b196959493929190610a45565b60405180910390a15063dc1600f360e01b925050505b9695505050505050565b73c02aaa39b223fe8d0a0e5c4f27ead9083c756cc290565b7371cd6666064c3a1354a3b4dca5fa1e2d3ee7d30390565b604051636eb1769f60e11b815281906001600160a01b0385169063dd62ed3e9061053190309087906004016109e8565b60206040518083038186803b15801561054957600080fd5b505afa15801561055d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250610581919081019061094e565b1015610594576105948383600019610599565b505050565b60405160609063095ea7b360e01b906105b89085908590602401610a9f565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915290506105f684826105fc565b50505050565b60006060836001600160a01b03168360405161061891906109ce565b6000604051808303816000865af19150503d8060008114610655576040519150601f19603f3d011682016040523d82523d6000602084013e61065a565b606091505b5091509150811561069e5780516106725750506106a7565b80516020141561069e5760006106898260006106ab565b9050806001141561069c575050506106a7565b505b6105f6816106c0565b5050565b60006106b783836106c8565b90505b92915050565b805160208201fd5b600081602001835110156106ee576106ee6106e960058551856020016106f7565b6106c0565b50016020015190565b6060632800659560e01b84848460405160240161071693929190610ac8565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915290509392505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a081019190915290565b80356106ba81610b97565b80516106ba81610b97565b80516106ba81610bab565b80356106ba81610bb4565b60008083601f8401126107c457600080fd5b50813567ffffffffffffffff8111156107dc57600080fd5b6020830191508360018202830111156107f457600080fd5b9250929050565b80516106ba81610bb4565b60006020828403121561081857600080fd5b60006108248484610791565b949350505050565b60006020828403121561083e57600080fd5b60006108248484610786565b60008060008060008060a0878903121561086357600080fd5b600061086f8989610786565b965050602061088089828a01610786565b955050604061089189828a01610786565b94505060606108a289828a016107a7565b935050608087013567ffffffffffffffff8111156108bf57600080fd5b6108cb89828a016107b2565b92509250509295509295509295565b6000602082840312156108ec57600080fd5b6000610824848461079c565b60008060006040848603121561090d57600080fd5b600061091986866107a7565b935050602084013567ffffffffffffffff81111561093657600080fd5b610942868287016107b2565b92509250509250925092565b60006020828403121561096057600080fd5b600061082484846107fb565b61097581610b3d565b82525050565b61097581610b07565b61097581610b1a565b600061099882610afe565b6109a28185610b02565b93506109b2818560208601610b5e565b9290920192915050565b61097581610b48565b61097581610b17565b600061008a828461098d565b602081016106ba828461096c565b604081016109f6828561097b565b61008a602083018461097b565b60a08101610a11828861097b565b610a1e602083018761097b565b610a2b60408301866109c5565b610a3860608301856109c5565b6104c7608083018461096c565b60c08101610a53828961097b565b610a60602083018861097b565b610a6d60408301876109c5565b610a7a60608301866109c5565b610a87608083018561097b565b610a9460a083018461097b565b979650505050505050565b60408101610aad828561097b565b61008a60208301846109c5565b602081016106ba8284610984565b60608101610ad682866109bc565b610ae360208301856109c5565b61082460408301846109c5565b602081016106ba82846109c5565b5190565b919050565b60006106ba82610b31565b151590565b90565b6001600160e01b03191690565b80610b0281610b8a565b6001600160a01b031690565b60006106ba82610b53565b60006106ba82610b27565b60006106ba82610b07565b60005b83811015610b79578181015183820152602001610b61565b838111156105f65750506000910152565b60088110610b9457fe5b50565b610ba081610b07565b8114610b9457600080fd5b610ba081610b12565b610ba081610b1756fea365627a7a7231582088034d4797de50606fc409b29605aaee9470fadeaf51709766e29ede6c887d3c6c6578706572696d656e74616cf564736f6c63430005110040

Deployed Bytecode Sourcemap

50737:3977:0:-;;;;;;;;;;;;;;;;;;;;;;;;54510:201;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;54510:201:0;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;51829:2476;;8:9:-1;5:2;;;30:1;27;20:12;5:2;-1:-1;51829:2476:0;;;;;;;;:::i;54510:201::-;-1:-1:-1;;;54510:201:0;;;;;;:::o;51829:2476::-;52038:14;52128:26;;:::i;:::-;52231:24;52258:33;;;;52269:10;52258:33;;;52231:60;;52362:17;:15;:17::i;:::-;-1:-1:-1;;;;;52337:43:0;;;:10;;;;:43;;;;52473:54;-1:-1:-1;;;52473:54:0;;:39;;;;;;:54;;52521:4;;52473:54;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52473:54:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52473:54:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;52473:54:0;;;;;;;;;52448:22;;;:79;52593:10;;;;-1:-1:-1;;;;;52565:39:0;;;;;;:71;;52620:16;52565:71;;;52615:1;52565:71;-1:-1:-1;;;;;52540:96:0;;;:22;;;:96;52696:10;;;;52670:37;;;;;;:67;;52723:14;52670:67;;;52718:1;52670:67;-1:-1:-1;;;;;52647:90:0;:20;;;:90;52805:22;:20;:22::i;:::-;-1:-1:-1;;;;;52786:48:0;;52853:5;:22;;;52894:5;:20;;;52786:143;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;52786:143:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;52786:143:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;52786:143:0;;;;;;;;;-1:-1:-1;;;;;52748:192:0;;;;;52990:22;;;;:36;52986:353;;53043:5;:10;;;-1:-1:-1;;;;;53043:19:0;;53063:5;:22;;;53043:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53043:43:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53043:43:0;;;;52986:353;;;53164:163;53211:5;:22;;;53260:5;:10;;;53290:5;:22;;;53164:28;:163::i;:::-;53368:22;;;;53349:16;;-1:-1:-1;;;;;53368:36:0;;:65;;53432:1;53368:65;;;53407:5;:22;;;53368:65;53349:84;;53465:5;:10;;;-1:-1:-1;;;;;53465:15:0;;53487:8;53511:5;:22;;;53548:5;:20;;;53583:5;:22;;;53620:6;53649:1;53465:197;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53465:197:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53465:197:0;;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;53465:197:0;;;;;;;;;53444:18;;;:218;53705:20;;;;-1:-1:-1;;;;;53705:34:0;53701:113;;53756:5;:10;;;-1:-1:-1;;;;;53756:18:0;;53781:5;:18;;;53756:46;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53756:46:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53756:46:0;;;;;53701:113;53902:18;;;;53861:60;;-1:-1:-1;;;53861:60:0;;-1:-1:-1;;;;;53861:36:0;;;;;:60;;53898:2;;53861:60;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;53861:60:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;53861:60:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;53861:60:0;;;;;;;;;;53939:324;54001:16;54061:14;54125:5;:22;;;54198:5;:18;;;54231:4;54250:2;53939:324;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;54283:14:0;-1:-1:-1;;;51829:2476:0;;;;;;;;;:::o;43978:141::-;34936:42;43978:141;:::o;47455:149::-;37116:42;47455:149;:::o;28102:277::-;28246:52;;-1:-1:-1;;;28246:52:0;;28301:6;;-1:-1:-1;;;;;28246:28:0;;;;;:52;;28283:4;;28290:7;;28246:52;;;;;;;;;;;;;;;;8:9:-1;5:2;;;30:1;27;20:12;5:2;28246:52:0;;;;8:9:-1;5:2;;;45:16;42:1;39;24:38;77:16;74:1;67:27;5:2;28246:52:0;;;;;;;101:4:-1;97:9;90:4;84;80:15;76:31;69:5;65:43;126:6;120:4;113:20;0:138;28246:52:0;;;;;;;;;:61;28242:130;;;28324:36;28332:5;28339:7;-1:-1:-1;;28324:7:0;:36::i;:::-;28102:277;;;:::o;27296:351::-;27456:125;;27432:21;;-1:-1:-1;;;27493:31:0;27456:125;;27539:7;;27561:9;;27456:125;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;27456:125:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;27456:125:0;;;179:29:-1;;;;160:49;;;27456:125:0;-1:-1:-1;27592:47:0;27623:5;27456:125;27592:30;:47::i;:::-;27296:351;;;;:::o;32366:590::-;32504:15;32521:23;32548:6;-1:-1:-1;;;;;32548:11:0;32560:8;32548:21;;;;;;;;;;;;;;;;;;;;;;;14:1:-1;21;16:31;;;;75:4;69:11;64:16;;144:4;140:9;133:4;115:16;111:27;107:43;104:1;100:51;94:4;87:65;169:16;166:1;159:27;225:16;222:1;215:4;212:1;208:12;193:49;7:242;;16:31;36:4;31:9;;7:242;;32503:66:0;;;;32584:10;32580:325;;;32615:17;;32611:69;;32658:7;;;;32611:69;32698:10;:17;32719:2;32698:23;32694:200;;;32742:14;32759:35;32780:10;32792:1;32759:20;:35::i;:::-;32742:52;;32817:6;32827:1;32817:11;32813:66;;;32853:7;;;;;32813:66;32694:200;;32915:33;32937:10;32915:21;:33::i;32366:590::-;;;:::o;24500:230::-;24627:14;24676:21;24688:1;24691:5;24676:11;:21::i;:::-;24668:30;-1:-1:-1;24500:230:0;;;;;:::o;6345:177::-;6493:9;6487:16;6480:4;6469:9;6465:20;6458:46;22645:703;22772:14;22819:5;22827:2;22819:10;22808:1;:8;:21;22804:303;;;22846:249;22868:226;22931:92;23042:1;:8;23069:5;23077:2;23069:10;22868:44;:226::i;:::-;22846:21;:249::i;:::-;-1:-1:-1;23292:13:0;23190:2;23292:13;23286:20;;22645:703::o;8429:393::-;8624:12;8366:10;8698:37;;8750:9;8774:6;8795:8;8661:153;;;;;;;;;;;;;;;-1:-1:-1;;26:21;;;22:32;6:49;;8661:153:0;;;49:4:-1;25:18;;61:17;;-1:-1;;;;;182:15;-1:-1;;;;;;8661:153:0;;;179:29:-1;;;;160:49;;;8661:153:0;-1:-1:-1;8429:393:0;;;;;:::o;50737:3977::-;;;;;;;;;-1:-1:-1;50737:3977:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5:130:-1:-;72:20;;97:33;72:20;97:33;;142:134;220:13;;238:33;220:13;238:33;;436:128;511:13;;529:30;511:13;529:30;;571:130;638:20;;663:33;638:20;663:33;;722:336;;;836:3;829:4;821:6;817:17;813:27;803:2;;854:1;851;844:12;803:2;-1:-1;874:20;;914:18;903:30;;900:2;;;946:1;943;936:12;900:2;980:4;972:6;968:17;956:29;;1031:3;1023:4;1015:6;1011:17;1001:8;997:32;994:41;991:2;;;1048:1;1045;1038:12;991:2;796:262;;;;;;1203:134;1281:13;;1299:33;1281:13;1299:33;;1344:263;;1459:2;1447:9;1438:7;1434:23;1430:32;1427:2;;;1475:1;1472;1465:12;1427:2;1510:1;1527:64;1583:7;1563:9;1527:64;;;1517:74;1421:186;-1:-1;;;;1421:186;1614:257;;1726:2;1714:9;1705:7;1701:23;1697:32;1694:2;;;1742:1;1739;1732:12;1694:2;1777:1;1794:61;1847:7;1827:9;1794:61;;1878:867;;;;;;;2069:3;2057:9;2048:7;2044:23;2040:33;2037:2;;;2086:1;2083;2076:12;2037:2;2121:1;2138:53;2183:7;2163:9;2138:53;;;2128:63;;2100:97;2228:2;2246:53;2291:7;2282:6;2271:9;2267:22;2246:53;;;2236:63;;2207:98;2336:2;2354:53;2399:7;2390:6;2379:9;2375:22;2354:53;;;2344:63;;2315:98;2444:2;2462:53;2507:7;2498:6;2487:9;2483:22;2462:53;;;2452:63;;2423:98;2580:3;2569:9;2565:19;2552:33;2605:18;2597:6;2594:30;2591:2;;;2637:1;2634;2627:12;2591:2;2665:64;2721:7;2712:6;2701:9;2697:22;2665:64;;;2655:74;;;;2531:204;2031:714;;;;;;;;;2752:257;;2864:2;2852:9;2843:7;2839:23;2835:32;2832:2;;;2880:1;2877;2870:12;2832:2;2915:1;2932:61;2985:7;2965:9;2932:61;;3016:490;;;;3156:2;3144:9;3135:7;3131:23;3127:32;3124:2;;;3172:1;3169;3162:12;3124:2;3207:1;3224:53;3269:7;3249:9;3224:53;;;3214:63;;3186:97;3342:2;3331:9;3327:18;3314:32;3366:18;3358:6;3355:30;3352:2;;;3398:1;3395;3388:12;3352:2;3426:64;3482:7;3473:6;3462:9;3458:22;3426:64;;;3416:74;;;;3293:203;3118:388;;;;;;3513:263;;3628:2;3616:9;3607:7;3603:23;3599:32;3596:2;;;3644:1;3641;3634:12;3596:2;3679:1;3696:64;3752:7;3732:9;3696:64;;3783:142;3874:45;3913:5;3874:45;;;3869:3;3862:58;3856:69;;;3932:113;4015:24;4033:5;4015:24;;4052:110;4133:23;4150:5;4133:23;;4169:356;;4297:38;4329:5;4297:38;;;4347:88;4428:6;4423:3;4347:88;;;4340:95;;4440:52;4485:6;4480:3;4473:4;4466:5;4462:16;4440:52;;;4504:16;;;;;4277:248;-1:-1;;4277:248;4532:190;4647:69;4710:5;4647:69;;4729:113;4812:24;4830:5;4812:24;;4849:262;;4993:93;5082:3;5073:6;4993:93;;5118:229;5244:2;5229:18;;5258:79;5233:9;5310:6;5258:79;;5354:324;5500:2;5485:18;;5514:71;5489:9;5558:6;5514:71;;;5596:72;5664:2;5653:9;5649:18;5640:6;5596:72;;5685:675;5923:3;5908:19;;5938:71;5912:9;5982:6;5938:71;;;6020:72;6088:2;6077:9;6073:18;6064:6;6020:72;;;6103;6171:2;6160:9;6156:18;6147:6;6103:72;;;6186;6254:2;6243:9;6239:18;6230:6;6186:72;;;6269:81;6345:3;6334:9;6330:19;6321:6;6269:81;;6367:771;6625:3;6610:19;;6640:71;6614:9;6684:6;6640:71;;;6722:72;6790:2;6779:9;6775:18;6766:6;6722:72;;;6805;6873:2;6862:9;6858:18;6849:6;6805:72;;;6888;6956:2;6945:9;6941:18;6932:6;6888:72;;;6971:73;7039:3;7028:9;7024:19;7015:6;6971:73;;;7055;7123:3;7112:9;7108:19;7099:6;7055:73;;;6596:542;;;;;;;;;;7145:324;7291:2;7276:18;;7305:71;7280:9;7349:6;7305:71;;;7387:72;7455:2;7444:9;7440:18;7431:6;7387:72;;7476:209;7592:2;7577:18;;7606:69;7581:9;7648:6;7606:69;;7692:499;7898:2;7883:18;;7912:103;7887:9;7988:6;7912:103;;;8026:72;8094:2;8083:9;8079:18;8070:6;8026:72;;;8109;8177:2;8166:9;8162:18;8153:6;8109:72;;8198:213;8316:2;8301:18;;8330:71;8305:9;8374:6;8330:71;;8418:121;8505:12;;8476:63;8547:144;8682:3;8660:31;-1:-1;8660:31;8699:91;;8761:24;8779:5;8761:24;;8903:85;8969:13;8962:21;;8945:43;8995:72;9057:5;9040:27;9074:144;-1:-1;;;;;;9135:78;;9118:100;9225:174;9321:5;9327:67;9321:5;9327:67;;9406:121;-1:-1;;;;;9468:54;;9451:76;9613:129;;9700:37;9731:5;9700:37;;9749:174;;9860:58;9912:5;9860:58;;9930:121;;10009:37;10040:5;10009:37;;10174:268;10239:1;10246:101;10260:6;10257:1;10254:13;10246:101;;;10327:11;;;10321:18;10308:11;;;10301:39;10282:2;10275:10;10246:101;;;10362:6;10359:1;10356:13;10353:2;;;-1:-1;;10427:1;10409:16;;10402:27;10223:219;10450:125;10553:1;10546:5;10543:12;10533:2;;10559:9;10533:2;10527:48;;10582:117;10651:24;10669:5;10651:24;;;10644:5;10641:35;10631:2;;10690:1;10687;10680:12;10846:111;10912:21;10927:5;10912:21;;10964:117;11033:24;11051:5;11033:24;

Swarm Source

bzzr://88034d4797de50606fc409b29605aaee9470fadeaf51709766e29ede6c887d3c

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.