IIRC, the Spamcop update of March 2011 was advertised as providing for future support for IPv6.
Immediately after this update, I started receiving bounces for spam containing IPv6 loopback addresses, which had never been rejected prior to this update. I went back through my spam archives, and verified that I had submitted spam containing IPv6 loopback addresses several time during the previous month, none of which had been rejected.
My assumption, based on observed Spamcop behavior before and after that update, is that code to detect IPv6 was added during that update, and that instead of using that code to gather data, or as a step-by-step sanity check, it was instead used as a cop-out.
My comments on the "right way" and the "wrong way" are based on one assumption about the parsing process, namely that the process works from the recipient back towards the sender.
This is the logical method, since Spamcop needs to eliminate hosts within your MX path, so as not to report your receiving server as the spam source, which of course it is not.
The host immediately upstream of your receiving server is the last host which can be properly verified, since all headers upstream of that point can be forged. If Spamcop trusts the header upstream of that point, it is only because Spamcop trusts the upstream ISP (such as Yahoo/Google/AOL/etc), and has decided that the internal headers added by those ISP's are trustworthy.
Given that the parsing process needs to work backwards, it is logical that sanity check for IPv6 headers should be done at each step in the parsing process, which would eliminate all of the problems with IPv6 loopback addresses in the first hop, forged IPv6 headers, IPv6 tunnels and 6-to-4 gateways prior to the upstream server. This would not eliminate the problems with IPv6 use at the receiving site, or actual IPv6 transit between the receiving server and the host immediately upstream, but it would eliminate the vast majority of the current set of problems, since the spam source would be reached, and parsing terminated, prior to an IPv6 address being encountered.
Instead, what I have observed is that the parser looks for IPv6 addresses anywhere in the header as the first step, and pukes if any IPv6 addresses are found, instead of actually attempting to parse the headers in proper sequence, and only puking if an IPv6 address is encountered prior to determining the spam source.