contract Vault is ProofOfTrident, ERC20Burnable {

    uint8 private constant DECIMALS = 18;
    uint256 private constant INITIAL_SUPPLY = 0;
    address private _vaultAddress = address(this);
    
    /**
     * @dev Constructor that gives msg.sender all of existing tokens, 0.
     */
    constructor (string memory name, string memory symbol, address remoteContractAddress, address treasury)
        public ERC20Detailed(name, symbol, DECIMALS) {

            _remoteContractAddress = remoteContractAddress;
            _remoteToken = IERC20(_remoteContractAddress);
            _decimals = DECIMALS;
            _treasury = treasury;
            //_percentageOfTokensReturned = percentageOfTokensReturned;
            
            _mint(msg.sender, INITIAL_SUPPLY);
        }

    function() external payable {
        // If Ether is sent to this address, send it back.
        // The contracts must be used, not the fallback
        revert();
    }
 
    /**
     * @dev adminDoDestructContract
     */ 
    function adminDoDestructContract() external onlyOwner { 
        if (msg.sender == owner()) selfdestruct(msg.sender);
    }

    /** 
    @dev vaultRequestFromUser This allows the contract to transferFrom the user to 
    themselves using allowance that has been previously set. 
    @return string Message
    */
    function vaultRequestFromUser () external canPoSMint returns (string memory message) {
     
        // calculate remote allowance given to the contract on the senders address
        // completed via the wallet
        uint256 amountAllowed = _remoteToken.allowance(msg.sender, _vaultAddress);
        require(amountAllowed > 0, "No allowance has been set.");        
        require(amountAllowed <= _stakeMaximum, "The allowance has been set too high.");
        uint256 amountBalance = _remoteToken.balanceOf(msg.sender);
        require(amountBalance >= amountAllowed);
        
        require(_transferIns[msg.sender].amountInVault == 0,
        "You are already staking. Cancel your stake (sacrificing reward), or collect your reward and send again.");
        
        require(amountBalance >= amountAllowed,
        "The sending account balance is lower than the requested value.");
        require(amountAllowed >= _stakeMinimum,
        "There is a minimum stake amount set.");
        uint256 vaultBalance = _remoteToken.balanceOf(_vaultAddress);
        _remoteTransferFrom(msg.sender, _vaultAddress, amountAllowed);

        _transferIns[msg.sender].amountInVault = amountAllowed;
        _transferIns[msg.sender].tokenTimestamp = block.timestamp;
        _transferIns[msg.sender].percentageLower = _percentageLower;
        _transferIns[msg.sender].percentageMiddle = _percentageMiddle;
        _transferIns[msg.sender].percentageUpper = _percentageUpper;

        _transferIns[msg.sender].stakeMinimumTimestamp = _stakeMinimumTimestamp;
        _transferIns[msg.sender].stakeMaximumTimestamp = _stakeMaximumTimestamp;

        _remoteToken.approve(_vaultAddress, vaultBalance.add(amountAllowed));  
 
        return "Vault deposit complete, thank you.";
    }

    /**
    * @dev vaultDetails
    * @return address vaultAddress, 
    * @return address remoteContractAddress,
    * @return uint decimals
     */ 
    function vaultDetails() external view returns (
        address vaultAddress,  
        address remoteContractAddress, 
        uint decimals) {
        vaultAddress = _vaultAddress;
        remoteContractAddress = _remoteContractAddress;      
        decimals = _decimals;
    }

    /**
    @dev myBalance Return tokens from a balance
    @return balance
     */
    function myBalance () external view returns(uint256 balance) {
        balance = _balances[msg.sender];
    }

    /**
    @dev myAddress Return address from a sender. 
    Useful for setting allowances
    @return myAddress
     */
    function myAddress () external view returns(address myadddress) {
        myadddress = msg.sender;
    }

    /**
    @dev vaultBalance Return number of tokens helds by the contract.
    @return balance
     */
    function vaultBalance () external view onlyOwner returns(uint balance) {
        balance = _balances[address(this)];
    }

}
/**
 * @title Vault
 * @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
 * Note they can later distribute these tokens as they wish using `transfer` and other
 * `ERC20` functions.
 */
function vaultRequestFromUser () external canPoSMint returns (string memory message) {
     
    // calculate remote allowance given to the contract on the senders address
    // completed via the wallet
    uint256 amountAllowed = _remoteToken.allowance(msg.sender, _vaultAddress);
    require(amountAllowed > 0, "No allowance has been set.");        
    require(amountAllowed <= _stakeMaximum, "The allowance has been set too high.");
    uint256 amountBalance = _remoteToken.balanceOf(msg.sender);
    require(amountBalance >= amountAllowed);
        
    require(_transferIns[msg.sender].amountInVault == 0,
    "You are already staking. Cancel your stake (sacrificing reward), or collect your reward and send again.");
        
    require(amountBalance >= amountAllowed,
    "The sending account balance is lower than the requested value.");
    require(amountAllowed >= _stakeMinimum,
    "There is a minimum stake amount set.");
    uint256 vaultBalance = _remoteToken.balanceOf(_vaultAddress);
    _remoteTransferFrom(msg.sender, _vaultAddress, amountAllowed);

    _transferIns[msg.sender].amountInVault = amountAllowed;
    _transferIns[msg.sender].tokenTimestamp = block.timestamp;
    _transferIns[msg.sender].percentageLower = _percentageLower;
    _transferIns[msg.sender].percentageMiddle = _percentageMiddle;
    _transferIns[msg.sender].percentageUpper = _percentageUpper;

    _transferIns[msg.sender].stakeMinimumTimestamp = _stakeMinimumTimestamp;
    _transferIns[msg.sender].stakeMaximumTimestamp = _stakeMaximumTimestamp;

    _remoteToken.approve(_vaultAddress, vaultBalance.add(amountAllowed));  
 
    return "Vault deposit complete, thank you.";
}

/** 
 @dev vaultRequestFromUser This allows the contract to transferFrom the user to 
 themselves using allowance that has been previously set. 
 @return string Message
 */