Slow lookup of part of primary key
Instead of depending on IODKU to update rows, do the messy work in the SELECT:

INSERT INTO `ballots` (voter_id, election_id, status)
    SELECT t.voter_id, e.election_id, MAX(t.status)
        FROM elections AS e
        JOIN temp_ballots AS t  USING(date)
        WHERE e.whose = 'state'
        GROUP BY t.voter_id, e.election_id


Or...

INSERT INTO `ballots` (voter_id, election_id, status)
    SELECT  voter_id,
            ( SELECT election_id FROM elections
                     WHERE date = t.date
                       AND whose = 'state' ) AS election_id,
            MAX(status)
        FROM temp_ballots AS t
        GROUP BY voter_id, election_id


Notes:


I think the first one might be better.
The first one designed to produce the rows in PK order.
I picked MAX to choose among the status values, since you did not have any way of picking among them.