contract Eth2DaiBridge is
    IERC20Bridge,
    IWallet
{
    /* Mainnet addresses */
    address constant public ETH2DAI_ADDRESS = 0x39755357759cE0d7f32dC8dC45414CCa409AE24e;

    /// @dev Callback for `IERC20Bridge`. Tries to buy `amount` of
    ///      `toTokenAddress` tokens by selling the entirety of the opposing asset
    ///      (DAI or WETH) to the Eth2Dai contract, then transfers the bought
    ///      tokens to `to`.
    /// @param toTokenAddress The token to give to `to` (either DAI or WETH).
    /// @param to The recipient of the bought tokens.
    /// @param amount Minimum amount of `toTokenAddress` tokens to buy.
    /// @param bridgeData The abi-encoeded "from" token address.
    /// @return success The magic bytes if successful.
    function bridgeTransferFrom(
        address toTokenAddress,
        address /* from */,
        address to,
        uint256 amount,
        bytes calldata bridgeData
    )
        external
        returns (bytes4 success)
    {
        // Decode the bridge data to get the `fromTokenAddress`.
        (address fromTokenAddress) = abi.decode(bridgeData, (address));

        IEth2Dai exchange = _getEth2DaiContract();
        // Grant an allowance to the exchange to spend `fromTokenAddress` token.
        LibERC20Token.approve(fromTokenAddress, address(exchange), uint256(-1));

        // Try to sell all of this contract's `fromTokenAddress` token balance.
        uint256 boughtAmount = _getEth2DaiContract().sellAllAmount(
            address(fromTokenAddress),
            IERC20Token(fromTokenAddress).balanceOf(address(this)),
            toTokenAddress,
            amount
        );
        // Transfer the converted `toToken`s to `to`.
        LibERC20Token.transfer(toTokenAddress, to, boughtAmount);
        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 Magic success bytes, always.
    function isValidSignature(
        bytes32,
        bytes calldata
    )
        external
        view
        returns (bytes4 magicValue)
    {
        return LEGACY_WALLET_MAGIC_VALUE;
    }

    /// @dev Overridable way to get the eth2dai contract.
    /// @return exchange The Eth2Dai exchange contract.
    function _getEth2DaiContract()
        internal
        view
        returns (IEth2Dai exchange)
    {
        return IEth2Dai(ETH2DAI_ADDRESS);
    }
}
// solhint-disable space-after-comma
function _getEth2DaiContract()
    internal
    view
    returns (IEth2Dai exchange)
{
    return IEth2Dai(ETH2DAI_ADDRESS);
}

/// @dev Overridable way to get the eth2dai contract.
/// @return exchange The Eth2Dai exchange contract.