Recently, spammers have been targeting the governance system of the Cosmos Hub, as well as other Cosmos chains. They create governance proposals containing malicious links in the hopes that someone will click on them.
With spam, the name of the game is exposure. Get your malicious content in front of as many people as possible, and some small percentage of them will click on it. Unfortunately, spammers have discovered that they can use the Cosmos governance system to trick prominent websites like block explorers and wallets into displaying spam.
How does this work? In Cosmos governance, anyone can submit a proposal with any text that they want. There is also a deposit attached to the proposal. If the deposit is below 250 Atom (~$3k), then the proposal is considered to be in the “deposit period”. If the deposit is above 250 Atom, the proposal is in the “voting period”. Once the proposal is in the voting period, if it is vetoed, the deposit is burned.
Cosmos full nodes have an API endpoint called gov/proposals which displays proposals. Wallets and block explorers turn this endpoint into webpages which they display to the public. They will generally allow users to filter to view only deposit period proposals or only voting period proposals.
The intended operation of Cosmos governance is that while spammers could create spam proposals, they will not want to deposit enough Atoms to put them into the voting period. The idea is that although there may be spam proposals in the deposit period, nobody will look at these.
The spammers first tried just creating spam for free in the deposit period. This worked for a short while, but websites just stopped displaying deposit period proposals prominently. Even so, the Cosmos Hub and many other chains are rolling out upgrades to make it so that even deposit period proposals must have a minimum deposit.
But now, the spammers have started supplying the full deposit amount along with their proposals. Apparently they are making enough money that burning 250 Atoms is worthwhile, or they have some other motivation. We don’t think that raising the deposit amount is a good idea. 250 Atom is already a high bar for community members who want to make their ideas heard, and it’s unclear how high it would need to be raised to make things unprofitable for spammers.
We think there’s a better solution. What is the thing that spammers want to accomplish? They want to get their spam proposal displayed prominently. The key here is that it is not useful to spammers if their proposal is buried on an internal page like https://www.mintscan.io/cosmos/proposals/647. A link to their proposal must be visible on a prominent page like https://www.mintscan.io/cosmos/proposals.
So to fix the spam problem, without impacting the ability for community members to submit legitimate proposals, it is simply necessary for websites to filter their main proposal list. By performing extra filtering on the output of gov/proposals, websites can remove almost all spam proposals. Spam proposals could still be created, and can even still be displayed on their individual pages, but they will not appear in the prominent front page proposals list.
But what criteria should be filtered by? One thing that spam proposals all have in common is that they have an extremely high rate of “No With Veto” votes. Anyone seeing a spam proposal votes No With Veto immediately.
To filter out spam proposals it is sufficient to filter the proposals list to remove all proposals with a No With Veto rate of more than 90%. This should probably be calculated differently than it usually is, to exclude “Abstain” votes from the proposal, since many accounts abstain automatically on every proposal.
This may still allow spam proposals to be visible immediately after they have been created, when there hasn’t been a chance for a lot of people to veto them yet. For this reason, we can add an additional rule, which excludes proposals that have less than 1% of Atoms voting.
We finally filter out proposals that have less than 10 Atoms deposited. These deposit period proposals can still be created, but they won’t be displayed prominently.
We may add these rules directly to the full node API in an upcoming release, but websites can easily implement them right now. Here’s some code showing how:
1let proposals_displayed = proposals_loaded.filter((proposal) => { 2 // Filter out proposals with more than 90% no with veto votes, 3 // excluding abstain from the calculation 4 let total_votes = 5 proposal.tally.yes + 6 proposal.tally.no + 7 proposal.tally.no_with_veto; 8 9 let percentage_nwv = proposal.tally.no_with_veto / total_votes; 10 if (percentage_nwv > 0.9) { 11 return false; 12 } 13 14 // Filter out proposals with less than 1% of Atoms voting 15 let percentage_voting = total_votes / bank_atoms; 16 17 if (percentage_voting < 0.01) { 18 return false; 19 } 20 21 // Filter out proposals with less than 10 Atoms deposited to 22 // deal with deposit period spam 23 if (proposal.total_deposit[0].amount < 10000000) { 24 return false; 25 } 26 27 // Otherwise display the proposal 28 return true; 29});
Mintscan has implemented these rules, and as a result they are now spam free. Keplr is using a different system (which predates this blog post) to eliminate spam, and that’s also working well. We urge any other websites, apps, and chatbots that display governance proposals to implement these rules to stop spam.