SushiToken继承标准的ERC20,在此基础上,又实现了代币的投票功能。
1、数据结构
/// @notice A record of each accounts delegate
mapping (address => address) internal _delegates;
/// @notice A checkpoint for marking number of votes from a given block
struct Checkpoint {
uint32 fromBlock;
uint256 votes;
}
/// @notice A record of votes checkpoints for each account, by index
mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;
/// @notice The number of checkpoints for each account
mapping (address => uint32) public numCheckpoints;
/// @notice The EIP-712 typehash for the contract's domain
bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
/// @notice The EIP-712 typehash for the delegation struct used by the contract
bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
/// @notice A record of states for signing / validating signatures
mapping (address => uint) public nonces;
_delegates表示代理,A->B的映射,表示B可以代替A行使投票。
Checkpoint是记录投票的数据结构,类似于一个快照,里面记录了用户在某个区块持有的投票数。
numCheckpoints记录的是快照的ID,每次有新的快照,这个ID都会自增。
checkpoints是用户所有的投票快照记录。
DOMAIN_TYPEHASH、DELEGATION_TYPEHASH和nonces都和EIP-712有关,这个EIP旨在提高链下消息签名对链上的可用性,具体可以看https://eips.ethereum.org/EIPS/eip-712
2、转移投票
function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
if (srcRep != dstRep && amount > 0) {
if (srcRep != address(0)) {
// decrease old representative
uint32 s