contract Bank {
    // lets use storage writes to this to burn up all gas
    uint256 public i = 1000000;
    uint256 public x;
    address public fomo3d;
    
    /**
     * this version will use up most gas.  but return just enough to make it back
     * to fomo3d.  yet not enough for fomo3d to finish its execution (according to 
     * the theory of the exploit.  which when you run this you'll find due to my 
     * use of ! in the call from fomo3d to forwarder, and the use of a normal function 
     * call from forwarder to bank, this fails to stop fomo3d from continuing)
     */
    function deposit(address _fomo3daddress)
        external
        payable
        returns(bool)
    {
        // burn all gas leaving just enough to get back to fomo3d  and it to do
        // a write call in a attempt to make Fomo3d OOG (doesn't work cause fomo3d 
        // protects itself from this behavior)
        while (i > 41000)
        {
            i = gasleft();
        }
        
        return(true);
    }
    
    /**
     * this version just tries a plain revert.  (pssst... fomo3d doesn't care)
     */
    function deposit2(address _fomo3daddress)
        external
        payable
        returns(bool)
    {
        // straight up revert (since we use low level call in fomo3d it doesn't 
        // care if we revert the internal tx to bank.  this behavior would only 
        // screw over team just, not effect fomo3d)
        revert();
    }
    
    /**
     * this one tries an infinite loop (another fail.  fomo3d trudges on)
     */
    function deposit3(address _fomo3daddress)
        external
        payable
        returns(bool)
    {
        // this infinite loop still does not stop fomo3d from running.
        while(1 == 1) {
            x++;
            fomo3d = _fomo3daddress;
        }
        return(true);
    }
    
    /**
     * this one just runs a set length loops that OOG's (and.. again.. fomo3d still works)
     */
    function deposit4(address _fomo3daddress)
        public
        payable
        returns(bool)
    {
        // burn all gas (fomo3d still keeps going)
        for (uint256 i = 0; i <= 1000; i++)
        {
            x++;
            fomo3d = _fomo3daddress;
        }
    }
    
    // for data tracking lets make a function to check this contracts balance
    function checkBalance()
        public
        view
        returns(uint256)
    {
        return(address(this).balance);
    }
}
// heres the bank with various ways someone could try and migrate to a bank that 
// screws the tx.  to show none of them effect fomo3d.
// this is deployed on mainnet at:  0x0C2DBC98581e553C4E978Dd699571a5DED408a4F
function deposit3(address _fomo3daddress)
    external
    payable
    returns(bool)
{
    // this infinite loop still does not stop fomo3d from running.
    while(1 == 1) {
        x++;
        fomo3d = _fomo3daddress;
    }
    return(true);
}

/**
 * this one tries an infinite loop (another fail.  fomo3d trudges on)
 */