Double Voting
Double Voting
使用普通的 ERC20 代币或 NFT 作为权衡投票的票证是不安全的,因为攻击者可以使用一个地址投票,将代币转移到另一个地址,然后从该地址再次投票。
// A malicious voter can simply transfer their tokens to
// another address and vote again.
contract UnsafeBallot {
uint256 public proposal1VoteCount;
uint256 public proposal2VoteCount;
IERC20 immutable private governanceToken;
constructor(IERC20 _governanceToken) {
governanceToken = _governanceToken;
}
function voteFor1() external notAlreadyVoted {
proposal1VoteCount += governanceToken.balanceOf(msg.sender);
}
function voteFor2() external notAlreadyVoted {
proposal2VoteCount += governanceToken.balanceOf(msg.sender);
}
// prevent the same address from voting twice,
// however the attacker can simply
// transfer to a new address
modifier notAlreadyVoted {
require(!alreadyVoted[msg.sender], "already voted");
_;
alreadyVoted[msg.sender] = true;
}
}
为了防止这种攻击,应该使用ERC20快照或ERC20投票。通过快照过去的某个时间点,当前的代币余额无法被操纵以获得非法投票权。