// Contract: VetherPools
// Target function: function stake(uint inputVether, uint inputAsset, address pool) public payable returns (uint units)
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.6.11;
pragma experimental ABIEncoderV2;

// ERC20 Interface
interface ERC20 {
    function totalSupply() external view returns (uint);
    function balanceOf(address account) external view returns (uint);
    function transfer(address, uint) external returns (bool);
    function allowance(address owner, address spender) external view returns (uint);
    function approve(address, uint) external returns (bool);
    function transferFrom(address, address, uint) external returns (bool);
}
interface POOLS {
    function stakeForMember(uint inputVether, uint inputAsset, address pool, address member) external payable returns (uint units);
}
// Safe Math
library SafeMath {
    function sub(uint a, uint b) internal pure returns (uint) {
        assert(b <= a);
        return a - b;
    }

    function add(uint a, uint b) internal pure returns (uint)   {
        uint c = a + b;
        assert(c >= a);
        return c;
    }

    function mul(uint a, uint b) internal pure returns (uint) {
        if (a == 0) {
            return 0;
        }
        uint c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    function div(uint a, uint b) internal pure returns (uint) {
        require(b > 0, "SafeMath: division by zero");
        uint c = a / b;
        return c;
    }
}

contract VetherPools {
    using SafeMath for uint;

    address public VETHER;
    uint public one = 10**18;
    uint public ETHCAP = 10 * one;
    uint public DAY = 86400;
    uint public DAYCAP = 30*DAY;

    address[] public arrayPools;
    uint public poolCount;
    mapping(address => address[]) public mapPoolStakers;
    mapping(address => PoolData) public poolData;
    struct PoolData {
        bool listed;
        uint genesis;
        uint vether;
        uint asset;
        uint vetherStaked;
        uint assetStaked;
        uint stakerCount;
        uint poolUnits;
        uint fees;
        uint volume;
        uint txCount;
    }
    
    address[] public arrayMembers;
    uint public memberCount;
    mapping(address => MemberData) public memberData;
    struct MemberData {
        address[] arrayPools;
        uint poolCount;
        mapping(address => StakeData) stakeData;
    }

    struct StakeData {
        uint vether;
        uint asset;
        uint stakeUnits;
    }
   
    event Staked(address pool, address member, uint inputAsset, uint inputVether, uint unitsIssued);
    event Unstaked(address pool, address member, uint outputAsset, uint outputVether, uint unitsClaimed);
    event Swapped(address assetFrom, address assetTo, uint inputAmount, uint transferAmount, uint outPutAmount, uint fee, address recipient);

    constructor () public payable {
        VETHER = 0x4Ba6dDd7b89ed838FEd25d208D4f644106E34279;
    }

    receive() external payable {
        buyAsset(address(0), msg.value);
    }