// Contract: MigrationContract
// Target function: function MigrateV1toV2tokens() external
/**
°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
°°°°°__This migration contract is deployed to migrate BGLD v1 to v2__°°°°°°
°°°                                                                     °°°
---------->> Check out the website for migration instructions! <<----------
°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°°
-->> BGLD contract address (v2): 0x4b4fa17f83c09873cb5b4e0023f25d4f533fc9ba
***************************************************************************
---------------->>  Telegram:https://t.me/BGLDofficial  <<----------------
---------------->>  Website: https://www.BGLD.it  <<-----------------------
---------------->>  Twitter: https://twitter.com/Basedgoldbgld  <<---------
***************************************************************************
***************************************************************************
Links to Based Gold v2:
https://etherscan.io/address/0x4b4fa17f83c09873cb5b4e0023f25d4f533fc9ba
https://www.dextools.io/app/ether/pair-explorer/0x4233b83f3D5Bc39770fb7a456EF85B7eEC26fe14


███╗   ███╗██╗ ██████╗ ██████╗  █████╗ ████████╗██╗ ██████╗ ███╗   ██╗        
████╗ ████║██║██╔════╝ ██╔══██╗██╔══██╗╚══██╔══╝██║██╔═══██╗████╗  ██║        
██╔████╔██║██║██║  ███╗██████╔╝███████║   ██║   ██║██║   ██║██╔██╗ ██║        
██║╚██╔╝██║██║██║   ██║██╔══██╗██╔══██║   ██║   ██║██║   ██║██║╚██╗██║        
██║ ╚═╝ ██║██║╚██████╔╝██║  ██║██║  ██║   ██║   ██║╚██████╔╝██║ ╚████║        
╚═╝     ╚═╝╚═╝ ╚═════╝ ╚═╝  ╚═╝╚═╝  ╚═╝   ╚═╝   ╚═╝ ╚═════╝ ╚═╝  ╚═══╝        
                                                                              
██████╗  █████╗ ███████╗███████╗██████╗      ██████╗  ██████╗ ██╗     ██████╗ 
██╔══██╗██╔══██╗██╔════╝██╔════╝██╔══██╗    ██╔════╝ ██╔═══██╗██║     ██╔══██╗
██████╔╝███████║███████╗█████╗  ██║  ██║    ██║  ███╗██║   ██║██║     ██║  ██║
██╔══██╗██╔══██║╚════██║██╔══╝  ██║  ██║    ██║   ██║██║   ██║██║     ██║  ██║
██████╔╝██║  ██║███████║███████╗██████╔╝    ╚██████╔╝╚██████╔╝███████╗██████╔╝
╚═════╝ ╚═╝  ╚═╝╚══════╝╚══════╝╚═════╝      ╚═════╝  ╚═════╝ ╚══════╝╚═════╝ 
                                                                              
██████╗  ██████╗ ██╗     ██████╗                                              
██╔══██╗██╔════╝ ██║     ██╔══██╗                                             
██████╔╝██║  ███╗██║     ██║  ██║                                             
██╔══██╗██║   ██║██║     ██║  ██║                                             
██████╔╝╚██████╔╝███████╗██████╔╝                                             
╚═════╝  ╚═════╝ ╚══════╝╚═════╝                                              
                                                                              
██╗   ██╗ ██╗         ██╗      ██╗   ██╗██████╗                               
██║   ██║███║         ╚██╗     ██║   ██║╚════██╗                              
██║   ██║╚██║    █████╗╚██╗    ██║   ██║ █████╔╝                              
╚██╗ ██╔╝ ██║    ╚════╝██╔╝    ╚██╗ ██╔╝██╔═══╝                               
 ╚████╔╝  ██║         ██╔╝      ╚████╔╝ ███████╗                              
  ╚═══╝   ╚═╝         ╚═╝        ╚═══╝  ╚══════╝                              
                                                                              
*/

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.10;                                                      

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
    function transfer(address recipient, uint256 amount) external returns (bool);
}

library TransferHelper {
    function safeTransfer(address token, address to, uint256 value) internal {
        (bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
        require(success && (data.length == 0 || abi.decode(data, (bool))), "TransferHelper: TRANSFER_FAILED");
    }

    function safeTransferETH(address to, uint256 value) internal {
        (bool success, ) = to.call{value: value}(new bytes(0));
        require(success, "TransferHelper: ETH_TRANSFER_FAILED");
    }
}

contract MigrationContract {                                            
    address private _owner;

    address public tokenV1 = 0xbA7970f10D9f0531941DcEd1dda7ef3016B24e5b; // BGLD V1
    address public tokenV2 = 0x4B4Fa17F83c09873cb5b4e0023f25d4f533Fc9Ba; // BGLD V2

    // "Migration wallet"
    // Address where V1 tokens will be send to for collection/LP draining 
    // and where V2 tokens will be send from in return
    // if collectAddress is not this contract's address:
    // APPROVE this contract from the collectAddress to access V2 tokens!
    // Also exclude the collectAddress from Fees in v2 contract & must be capable to transfer before trading is open
    address public collectAddress = 0xF5eaDdc6AC4Da273338b726b0646a9bc07B449B4;

    // Swap ratio = 1:1
    uint256 public tokenMultiplyRatio = 1;
    uint256 public tokenDivideRatio = 1;

    // Minimum balance to migrate = 0.000 000 000 000 000 001 token!
    uint256 public minimumV1Balance;
    uint256 public minimumV2Balance;

    bool public migrationEnabled;     
    bool public whitelistEnabled = true;
    bool public enableV2toV1;

    mapping (address => bool) private _isBlacklisted;
    mapping (address => uint256) private _isWhitelisted;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
    event V1TokensMigratedToV2(address indexed account, uint256 amountV1, uint256 amountV2);
    event V2TokensMigratedToV1(address indexed account, uint256 amountV1, uint256 amountV2);

    modifier onlyOwner() {
        require(_owner == msg.sender, "MigrationContract: caller is not the owner");
        _;
    }

    constructor() {
        _owner = msg.sender; 
    }

    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "MigrationContract: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }