// Contract: Vether
// Target function: function transferFrom(address from, address to, uint256 value) public override returns (bool success)
pragma solidity 0.6.4;
//ERC20 Interface
interface ERC20 {
    function totalSupply() external view returns (uint256);
    function balanceOf(address account) external view returns (uint256);
    function transfer(address, uint256) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint256);
    function approve(address, uint256) external returns (bool);
    function transferFrom(address, address, uint256) external returns (bool);
    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);
    }
// Uniswap Factory Interface
interface UniswapFactory {
    function getExchange(address token) external view returns (address exchange);
    }
// Uniswap Exchange Interface
interface UniswapExchange {
    function tokenToEthTransferInput(uint256 tokens_sold,uint256 min_eth,uint256 deadline, address recipient) external returns (uint256  eth_bought);
    }
    //======================================VETHER=========================================//
contract Vether is ERC20 {
    // ERC-20 Parameters
    string public name; string public symbol;
    uint256 public decimals; uint256 public override totalSupply;
    // ERC-20 Mappings
    mapping(address => uint256) public override balanceOf;
    mapping(address => mapping(address => uint256)) public override allowance;
    // Public Parameters
    uint256 public emission;
    uint256 public currentEra; uint256 public currentDay;
    uint256 public daysPerEra; uint256 public secondsPerDay;
    uint256 public genesis; uint256 public nextEraTime; uint256 public nextDayTime;
    address payable public burnAddress;
    address[2] public registryAddrArray; bool public lockMutable;
    uint256 public totalFees; uint256 public totalBurnt;
    // Public Mappings
    mapping(uint256=>uint256) public mapEra_Emission;                                           // Era->Emission
    mapping(uint256=>mapping(uint256=>uint256)) public mapEraDay_Units;                         // Era,Days->Units
    mapping(uint256=>mapping(uint256=>uint256)) public mapEraDay_UnitsRemaining;                // Era,Days->TotalUnits
    mapping(uint256=>mapping(uint256=>uint256)) public mapEraDay_Emission;                      // Era,Days->Emission
    mapping(uint256=>mapping(uint256=>uint256)) public mapEraDay_EmissionRemaining;             // Era,Days->Emission
    mapping(uint256=>mapping(uint256=>mapping(address=>uint256))) public mapEraDay_MemberUnits; // Era,Days,Member->Units
    mapping(address=>mapping(uint256=>uint[])) public mapMemberEra_Days;                        // Member,Era->Days[]
    mapping(address=>bool) public mapAddress_Excluded;                                          // Address->Excluded
    // Events
    event NewEra(uint256 era, uint256 emission, uint256 time);
    event NewDay(uint256 era, uint256 day, uint256 time);
    event Burn(address indexed payer, address indexed member, uint256 era, uint256 day, uint256 units);
    event Withdrawal(address indexed caller, address indexed member, uint256 era, uint256 day, uint256 value);

    //=====================================CREATION=========================================//
    // Constructor
    constructor() public {
        name = "value-test"; symbol = "val"; decimals = 18; totalSupply = 1000000*10**decimals;
        emission = 2048*10**decimals; currentEra = 1; currentDay = 1;                       // Set emission, Era and Day
        genesis = now; daysPerEra = 4; secondsPerDay = 60;                                  // Set genesis time
        burnAddress = 0x000000000000000000000000000000000000dEaD;                           // Set Burn Address
        registryAddrArray[0] = 0xf5D915570BC477f9B8D6C0E980aA81757A3AaC36;                  // Set UniSwap V1 Mainnet
        registryAddrArray[0] = 0xfB02641a0752B4d53DAbB8B2d75C92C1858a7a4E;                  // Set UniSwap V1 Mainnet
        
        balanceOf[address(this)] = totalSupply; 
        emit Transfer(address(0), address(this), totalSupply);                              // Mint the total supply to this address
        nextEraTime = genesis + (secondsPerDay * daysPerEra);                               // Set next time for coin era
        nextDayTime = genesis + secondsPerDay;                                              // Set next time for coin day
        mapAddress_Excluded[address(this)] = true; lockMutable = true;                      // Add this address to be excluded from fees
        mapEra_Emission[currentEra] = emission;                                             // Map Starting emission
        mapEraDay_EmissionRemaining[currentEra][currentDay] = emission; 
        mapEraDay_Emission[currentEra][currentDay] = emission;
    }
    //========================================ERC20=========================================//
    // ERC20 Transfer function
    function transfer(address to, uint256 value) public override returns (bool success) {
        _transfer(msg.sender, to, value);
        return true;
    }
    // ERC20 Approve function
    function approve(address spender, uint256 value) public override returns (bool success) {
        allowance[msg.sender][spender] = value;
        emit Approval(msg.sender, spender, value);
        return true;
    }