This requires loading all campaign data up front (oof) OR moving logic to contract. Probably should go for the second one.