To solve this optimization problem, we first need to define the decision variables and the objective function. Let's denote the number of controllers sold as \(C\) and the number of speakers sold as \(S\).

The objective is to maximize profit. The profit from selling a controller is $70, and the profit from selling a speaker is $20. Therefore, the total profit can be represented as \(70C + 20S\).

There are several constraints:
1. The cost constraint: The store spends at most $50,000 on controllers and speakers. Given that a controller costs $150 and a speaker costs $100, this constraint can be written as \(150C + 100S \leq 50000\).
2. The minimum and maximum sales of controllers: The store sells at least 15 but no more than 60 controllers, which gives us the constraints \(15 \leq C \leq 60\).
3. The relationship between speakers and controllers sold: The number of speakers sold is at most four times the number of controllers sold, so \(S \leq 4C\).

Now, let's translate these into Gurobi code in Python:

```python
from gurobipy import *

# Create a model
m = Model("Iota_Game_Profit_Optimization")

# Decision variables
C = m.addVar(vtype=GRB.INTEGER, name="controllers", lb=15, ub=60)  # Number of controllers sold
S = m.addVar(vtype=GRB.INTEGER, name="speakers")  # Number of speakers sold

# Objective function: Maximize profit
m.setObjective(70*C + 20*S, GRB.MAXIMIZE)

# Constraints
m.addConstr(150*C + 100*S <= 50000, name="budget_constraint")
m.addConstr(S <= 4*C, name="speakers_vs_controllers")

# Optimize model
m.optimize()

# Print solution
if m.status == GRB.OPTIMAL:
    print(f"Optimal solution: Sell {C.x} controllers and {S.x} speakers.")
    print(f"Maximum profit: ${70*C.x + 20*S.x}")
else:
    print("No optimal solution found")

```