Diff
checker
文本
文本
图像
文档
Excel
文件夹
Legal
Enterprise
桌面版
定价
登录
下载 Diffchecker 桌面版
比较文本
查找两个文本文件之间的差异
工具
历史
实时编辑器
折叠未更改行
关闭换行
视图
拆分
统一
比对精度
智能
单词
字符
语法高亮
选择语法
忽略
文本转换
转到第一个差异
编辑输入
Diffchecker Desktop
运行Diffchecker最安全的方式。获取Diffchecker桌面应用:您的差异永远不会离开您的电脑!
获取桌面版
LYPTUS vs EGG code
创建于
5年前
差异永不过期
清除
导出
分享
解释
23 删除
行
总计
删除
字符
总计
删除
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
254 行
全部复制
11 添加
行
总计
添加
字符
总计
添加
要继续使用此功能,请升级到
Diff
checker
Pro
查看价格
242 行
全部复制
pragma solidity 0.6.12;
pragma solidity 0.6.12;
复制
已复制
复制
已复制
// .----------------. .----------------. .----------------. .----------------. .----------------.
import ".
/libs
/BEP20.sol";
// | .--------------. || .--------------. || .--------------. || .--------------. || .--------------. |
// | | ___ ____ | || | ____ | || | __ | || | _____ | || | __ | |
// | | |_ ||_ _| | || | .' `. | || | / \ | || | |_ _| | || | / \ | |
// | | | |_/ / | || | / .--. \ | || | / /\ \ | || | | | | || | / /\ \ | |
// | | | __'. | || | | | | | | || | / ____ \ | || | | | _ | || | / ____ \ | |
// | | _| | \ \_ | || | \ `--' / | || | _/ / \ \_ | || | _| |__/ | | || | _/ / \ \_ | |
// | | |____||____| | || | `.____.' | || ||____| |____|| || | |________| | || ||____| |____|| |
// | | | || | | || | | || | | || | | |
// | '--------------' || '--------------' || '--------------' || '--------------' || '--------------' |
// '----------------' '----------------' '----------------' '----------------' '----------------'
import ".
/BEP20.sol";
复制
已复制
复制
已复制
//
LyptusToken
with Governance.
//
EggToken
with Governance.
contract
LyptusToken
is BEP20('
Lyptus Token
', '
LYPTUS
') {
contract
EggToken
is BEP20('
Goose Golden Egg
', '
EGG
') {
/// @notice Creates `_amount` token to `_to`. Must only be called by the owner (MasterChef).
/// @notice Creates `_amount` token to `_to`. Must only be called by the owner (MasterChef).
function mint(address _to, uint256 _amount) public onlyOwner {
function mint(address _to, uint256 _amount) public onlyOwner {
_mint(_to, _amount);
_mint(_to, _amount);
_moveDelegates(address(0), _delegates[_to], _amount);
_moveDelegates(address(0), _delegates[_to], _amount);
}
}
// Copied and modified from YAM code:
// Copied and modified from YAM code:
// https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol
// https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol
// https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol
// https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol
// Which is copied and modified from COMPOUND:
// Which is copied and modified from COMPOUND:
// https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol
// https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol
/// @notice A record of each accounts delegate
/// @notice A record of each accounts delegate
mapping (address => address) internal _delegates;
mapping (address => address) internal _delegates;
/// @notice A checkpoint for marking number of votes from a given block
/// @notice A checkpoint for marking number of votes from a given block
struct Checkpoint {
struct Checkpoint {
uint32 fromBlock;
uint32 fromBlock;
uint256 votes;
uint256 votes;
}
}
/// @notice A record of votes checkpoints for each account, by index
/// @notice A record of votes checkpoints for each account, by index
mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;
mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;
/// @notice The number of checkpoints for each account
/// @notice The number of checkpoints for each account
mapping (address => uint32) public numCheckpoints;
mapping (address => uint32) public numCheckpoints;
/// @notice The EIP-712 typehash for the contract's domain
/// @notice The EIP-712 typehash for the contract's domain
bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
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
/// @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)");
bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
/// @notice A record of states for signing / validating signatures
/// @notice A record of states for signing / validating signatures
mapping (address => uint) public nonces;
mapping (address => uint) public nonces;
/// @notice An event thats emitted when an account changes its delegate
/// @notice An event thats emitted when an account changes its delegate
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
/// @notice An event thats emitted when a delegate account's vote balance changes
/// @notice An event thats emitted when a delegate account's vote balance changes
event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);
event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);
/**
/**
* @notice Delegate votes from `msg.sender` to `delegatee`
* @notice Delegate votes from `msg.sender` to `delegatee`
* @param delegator The address to get delegatee for
* @param delegator The address to get delegatee for
*/
*/
function delegates(address delegator)
function delegates(address delegator)
external
external
view
view
returns (address)
returns (address)
{
{
return _delegates[delegator];
return _delegates[delegator];
}
}
/**
/**
* @notice Delegate votes from `msg.sender` to `delegatee`
* @notice Delegate votes from `msg.sender` to `delegatee`
* @param delegatee The address to delegate votes to
* @param delegatee The address to delegate votes to
*/
*/
function delegate(address delegatee) external {
function delegate(address delegatee) external {
return _delegate(msg.sender, delegatee);
return _delegate(msg.sender, delegatee);
}
}
/**
/**
* @notice Delegates votes from signatory to `delegatee`
* @notice Delegates votes from signatory to `delegatee`
* @param delegatee The address to delegate votes to
* @param delegatee The address to delegate votes to
* @param nonce The contract state required to match the signature
* @param nonce The contract state required to match the signature
* @param expiry The time at which to expire the signature
* @param expiry The time at which to expire the signature
* @param v The recovery byte of the signature
* @param v The recovery byte of the signature
* @param r Half of the ECDSA signature pair
* @param r Half of the ECDSA signature pair
* @param s Half of the ECDSA signature pair
* @param s Half of the ECDSA signature pair
*/
*/
function delegateBySig(
function delegateBySig(
address delegatee,
address delegatee,
uint nonce,
uint nonce,
uint expiry,
uint expiry,
uint8 v,
uint8 v,
bytes32 r,
bytes32 r,
bytes32 s
bytes32 s
)
)
external
external
{
{
bytes32 domainSeparator = keccak256(
bytes32 domainSeparator = keccak256(
abi.encode(
abi.encode(
DOMAIN_TYPEHASH,
DOMAIN_TYPEHASH,
keccak256(bytes(name())),
keccak256(bytes(name())),
getChainId(),
getChainId(),
address(this)
address(this)
)
)
);
);
bytes32 structHash = keccak256(
bytes32 structHash = keccak256(
abi.encode(
abi.encode(
DELEGATION_TYPEHASH,
DELEGATION_TYPEHASH,
delegatee,
delegatee,
nonce,
nonce,
expiry
expiry
)
)
);
);
bytes32 digest = keccak256(
bytes32 digest = keccak256(
abi.encodePacked(
abi.encodePacked(
"\x19\x01",
"\x19\x01",
domainSeparator,
domainSeparator,
structHash
structHash
)
)
);
);
address signatory = ecrecover(digest, v, r, s);
address signatory = ecrecover(digest, v, r, s);
复制
已复制
复制
已复制
require(signatory != address(0), "
LYPTUS
::delegateBySig: invalid signature");
require(signatory != address(0), "
EGG
::delegateBySig: invalid signature");
require(nonce == nonces[signatory]++, "
LYPTUS
::delegateBySig: invalid nonce");
require(nonce == nonces[signatory]++, "
EGG
::delegateBySig: invalid nonce");
require(now <= expiry, "
LYPTUS
::delegateBySig: signature expired");
require(now <= expiry, "
EGG
::delegateBySig: signature expired");
return _delegate(signatory, delegatee);
return _delegate(signatory, delegatee);
}
}
/**
/**
* @notice Gets the current votes balance for `account`
* @notice Gets the current votes balance for `account`
* @param account The address to get votes balance
* @param account The address to get votes balance
* @return The number of current votes for `account`
* @return The number of current votes for `account`
*/
*/
function getCurrentVotes(address account)
function getCurrentVotes(address account)
external
external
view
view
returns (uint256)
returns (uint256)
{
{
uint32 nCheckpoints = numCheckpoints[account];
uint32 nCheckpoints = numCheckpoints[account];
return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
}
}
/**
/**
* @notice Determine the prior number of votes for an account as of a block number
* @notice Determine the prior number of votes for an account as of a block number
* @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
* @dev Block number must be a finalized block or else this function will revert to prevent misinformation.
* @param account The address of the account to check
* @param account The address of the account to check
* @param blockNumber The block number to get the vote balance at
* @param blockNumber The block number to get the vote balance at
* @return The number of votes the account had as of the given block
* @return The number of votes the account had as of the given block
*/
*/
function getPriorVotes(address account, uint blockNumber)
function getPriorVotes(address account, uint blockNumber)
external
external
view
view
returns (uint256)
returns (uint256)
{
{
复制
已复制
复制
已复制
require(blockNumber < block.number, "
LYPTUS
::getPriorVotes: not yet determined");
require(blockNumber < block.number, "
EGG
::getPriorVotes: not yet determined");
uint32 nCheckpoints = numCheckpoints[account];
uint32 nCheckpoints = numCheckpoints[account];
if (nCheckpoints == 0) {
if (nCheckpoints == 0) {
return 0;
return 0;
}
}
// First check most recent balance
// First check most recent balance
if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
return checkpoints[account][nCheckpoints - 1].votes;
return checkpoints[account][nCheckpoints - 1].votes;
}
}
// Next check implicit zero balance
// Next check implicit zero balance
if (checkpoints[account][0].fromBlock > blockNumber) {
if (checkpoints[account][0].fromBlock > blockNumber) {
return 0;
return 0;
}
}
uint32 lower = 0;
uint32 lower = 0;
uint32 upper = nCheckpoints - 1;
uint32 upper = nCheckpoints - 1;
while (upper > lower) {
while (upper > lower) {
uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow
Checkpoint memory cp = checkpoints[account][center];
Checkpoint memory cp = checkpoints[account][center];
if (cp.fromBlock == blockNumber) {
if (cp.fromBlock == blockNumber) {
return cp.votes;
return cp.votes;
} else if (cp.fromBlock < blockNumber) {
} else if (cp.fromBlock < blockNumber) {
lower = center;
lower = center;
} else {
} else {
upper = center - 1;
upper = center - 1;
}
}
}
}
return checkpoints[account][lower].votes;
return checkpoints[account][lower].votes;
}
}
function _delegate(address delegator, address delegatee)
function _delegate(address delegator, address delegatee)
internal
internal
{
{
address currentDelegate = _delegates[delegator];
address currentDelegate = _delegates[delegator];
复制
已复制
复制
已复制
uint256 delegatorBalance = balanceOf(delegator); // balance of underlying
LYPTUSs
(not scaled);
uint256 delegatorBalance = balanceOf(delegator); // balance of underlying
EGGs
(not scaled);
_delegates[delegator] = delegatee;
_delegates[delegator] = delegatee;
emit DelegateChanged(delegator, currentDelegate, delegatee);
emit DelegateChanged(delegator, currentDelegate, delegatee);
_moveDelegates(currentDelegate, delegatee, delegatorBalance);
_moveDelegates(currentDelegate, delegatee, delegatorBalance);
}
}
function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal {
if (srcRep != dstRep && amount > 0) {
if (srcRep != dstRep && amount > 0) {
if (srcRep != address(0)) {
if (srcRep != address(0)) {
// decrease old representative
// decrease old representative
uint32 srcRepNum = numCheckpoints[srcRep];
uint32 srcRepNum = numCheckpoints[srcRep];
uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
uint256 srcRepNew = srcRepOld.sub(amount);
uint256 srcRepNew = srcRepOld.sub(amount);
_writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
_writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
}
}
if (dstRep != address(0)) {
if (dstRep != address(0)) {
// increase new representative
// increase new representative
uint32 dstRepNum = numCheckpoints[dstRep];
uint32 dstRepNum = numCheckpoints[dstRep];
uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0;
uint256 dstRepNew = dstRepOld.add(amount);
uint256 dstRepNew = dstRepOld.add(amount);
_writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
_writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew);
}
}
}
}
}
}
function _writeCheckpoint(
function _writeCheckpoint(
address delegatee,
address delegatee,
uint32 nCheckpoints,
uint32 nCheckpoints,
uint256 oldVotes,
uint256 oldVotes,
uint256 newVotes
uint256 newVotes
)
)
internal
internal
{
{
复制
已复制
复制
已复制
uint32 blockNumber = safe32(block.number, "
LYPTUS
::_writeCheckpoint: block number exceeds 32 bits");
uint32 blockNumber = safe32(block.number, "
EGG
::_writeCheckpoint: block number exceeds 32 bits");
if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) {
checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
checkpoints[delegatee][nCheckpoints - 1].votes = newVotes;
} else {
} else {
checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes);
numCheckpoints[delegatee] = nCheckpoints + 1;
numCheckpoints[delegatee] = nCheckpoints + 1;
}
}
emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
emit DelegateVotesChanged(delegatee, oldVotes, newVotes);
}
}
function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
function safe32(uint n, string memory errorMessage) internal pure returns (uint32) {
require(n < 2**32, errorMessage);
require(n < 2**32, errorMessage);
return uint32(n);
return uint32(n);
}
}
function getChainId() internal pure returns (uint) {
function getChainId() internal pure returns (uint) {
uint256 chainId;
uint256 chainId;
assembly { chainId := chainid() }
assembly { chainId := chainid() }
return chainId;
return chainId;
}
}
}
}
已保存差异
原始文本
打开文件
pragma solidity 0.6.12; // .----------------. .----------------. .----------------. .----------------. .----------------. // | .--------------. || .--------------. || .--------------. || .--------------. || .--------------. | // | | ___ ____ | || | ____ | || | __ | || | _____ | || | __ | | // | | |_ ||_ _| | || | .' `. | || | / \ | || | |_ _| | || | / \ | | // | | | |_/ / | || | / .--. \ | || | / /\ \ | || | | | | || | / /\ \ | | // | | | __'. | || | | | | | | || | / ____ \ | || | | | _ | || | / ____ \ | | // | | _| | \ \_ | || | \ `--' / | || | _/ / \ \_ | || | _| |__/ | | || | _/ / \ \_ | | // | | |____||____| | || | `.____.' | || ||____| |____|| || | |________| | || ||____| |____|| | // | | | || | | || | | || | | || | | | // | '--------------' || '--------------' || '--------------' || '--------------' || '--------------' | // '----------------' '----------------' '----------------' '----------------' '----------------' import "./BEP20.sol"; // LyptusToken with Governance. contract LyptusToken is BEP20('Lyptus Token', 'LYPTUS') { /// @notice Creates `_amount` token to `_to`. Must only be called by the owner (MasterChef). function mint(address _to, uint256 _amount) public onlyOwner { _mint(_to, _amount); _moveDelegates(address(0), _delegates[_to], _amount); } // Copied and modified from YAM code: // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol // Which is copied and modified from COMPOUND: // https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol /// @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; /// @notice An event thats emitted when an account changes its delegate event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /// @notice An event thats emitted when a delegate account's vote balance changes event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance); /** * @notice Delegate votes from `msg.sender` to `delegatee` * @param delegator The address to get delegatee for */ function delegates(address delegator) external view returns (address) { return _delegates[delegator]; } /** * @notice Delegate votes from `msg.sender` to `delegatee` * @param delegatee The address to delegate votes to */ function delegate(address delegatee) external { return _delegate(msg.sender, delegatee); } /** * @notice Delegates votes from signatory to `delegatee` * @param delegatee The address to delegate votes to * @param nonce The contract state required to match the signature * @param expiry The time at which to expire the signature * @param v The recovery byte of the signature * @param r Half of the ECDSA signature pair * @param s Half of the ECDSA signature pair */ function delegateBySig( address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s ) external { bytes32 domainSeparator = keccak256( abi.encode( DOMAIN_TYPEHASH, keccak256(bytes(name())), getChainId(), address(this) ) ); bytes32 structHash = keccak256( abi.encode( DELEGATION_TYPEHASH, delegatee, nonce, expiry ) ); bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", domainSeparator, structHash ) ); address signatory = ecrecover(digest, v, r, s); require(signatory != address(0), "LYPTUS::delegateBySig: invalid signature"); require(nonce == nonces[signatory]++, "LYPTUS::delegateBySig: invalid nonce"); require(now <= expiry, "LYPTUS::delegateBySig: signature expired"); return _delegate(signatory, delegatee); } /** * @notice Gets the current votes balance for `account` * @param account The address to get votes balance * @return The number of current votes for `account` */ function getCurrentVotes(address account) external view returns (uint256) { uint32 nCheckpoints = numCheckpoints[account]; return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0; } /** * @notice Determine the prior number of votes for an account as of a block number * @dev Block number must be a finalized block or else this function will revert to prevent misinformation. * @param account The address of the account to check * @param blockNumber The block number to get the vote balance at * @return The number of votes the account had as of the given block */ function getPriorVotes(address account, uint blockNumber) external view returns (uint256) { require(blockNumber < block.number, "LYPTUS::getPriorVotes: not yet determined"); uint32 nCheckpoints = numCheckpoints[account]; if (nCheckpoints == 0) { return 0; } // First check most recent balance if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) { return checkpoints[account][nCheckpoints - 1].votes; } // Next check implicit zero balance if (checkpoints[account][0].fromBlock > blockNumber) { return 0; } uint32 lower = 0; uint32 upper = nCheckpoints - 1; while (upper > lower) { uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow Checkpoint memory cp = checkpoints[account][center]; if (cp.fromBlock == blockNumber) { return cp.votes; } else if (cp.fromBlock < blockNumber) { lower = center; } else { upper = center - 1; } } return checkpoints[account][lower].votes; } function _delegate(address delegator, address delegatee) internal { address currentDelegate = _delegates[delegator]; uint256 delegatorBalance = balanceOf(delegator); // balance of underlying LYPTUSs (not scaled); _delegates[delegator] = delegatee; emit DelegateChanged(delegator, currentDelegate, delegatee); _moveDelegates(currentDelegate, delegatee, delegatorBalance); } function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal { if (srcRep != dstRep && amount > 0) { if (srcRep != address(0)) { // decrease old representative uint32 srcRepNum = numCheckpoints[srcRep]; uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0; uint256 srcRepNew = srcRepOld.sub(amount); _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew); } if (dstRep != address(0)) { // increase new representative uint32 dstRepNum = numCheckpoints[dstRep]; uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0; uint256 dstRepNew = dstRepOld.add(amount); _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew); } } } function _writeCheckpoint( address delegatee, uint32 nCheckpoints, uint256 oldVotes, uint256 newVotes ) internal { uint32 blockNumber = safe32(block.number, "LYPTUS::_writeCheckpoint: block number exceeds 32 bits"); if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) { checkpoints[delegatee][nCheckpoints - 1].votes = newVotes; } else { checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes); numCheckpoints[delegatee] = nCheckpoints + 1; } emit DelegateVotesChanged(delegatee, oldVotes, newVotes); } function safe32(uint n, string memory errorMessage) internal pure returns (uint32) { require(n < 2**32, errorMessage); return uint32(n); } function getChainId() internal pure returns (uint) { uint256 chainId; assembly { chainId := chainid() } return chainId; } }
更改后文本
打开文件
pragma solidity 0.6.12; import "./libs/BEP20.sol"; // EggToken with Governance. contract EggToken is BEP20('Goose Golden Egg', 'EGG') { /// @notice Creates `_amount` token to `_to`. Must only be called by the owner (MasterChef). function mint(address _to, uint256 _amount) public onlyOwner { _mint(_to, _amount); _moveDelegates(address(0), _delegates[_to], _amount); } // Copied and modified from YAM code: // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernanceStorage.sol // https://github.com/yam-finance/yam-protocol/blob/master/contracts/token/YAMGovernance.sol // Which is copied and modified from COMPOUND: // https://github.com/compound-finance/compound-protocol/blob/master/contracts/Governance/Comp.sol /// @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; /// @notice An event thats emitted when an account changes its delegate event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate); /// @notice An event thats emitted when a delegate account's vote balance changes event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance); /** * @notice Delegate votes from `msg.sender` to `delegatee` * @param delegator The address to get delegatee for */ function delegates(address delegator) external view returns (address) { return _delegates[delegator]; } /** * @notice Delegate votes from `msg.sender` to `delegatee` * @param delegatee The address to delegate votes to */ function delegate(address delegatee) external { return _delegate(msg.sender, delegatee); } /** * @notice Delegates votes from signatory to `delegatee` * @param delegatee The address to delegate votes to * @param nonce The contract state required to match the signature * @param expiry The time at which to expire the signature * @param v The recovery byte of the signature * @param r Half of the ECDSA signature pair * @param s Half of the ECDSA signature pair */ function delegateBySig( address delegatee, uint nonce, uint expiry, uint8 v, bytes32 r, bytes32 s ) external { bytes32 domainSeparator = keccak256( abi.encode( DOMAIN_TYPEHASH, keccak256(bytes(name())), getChainId(), address(this) ) ); bytes32 structHash = keccak256( abi.encode( DELEGATION_TYPEHASH, delegatee, nonce, expiry ) ); bytes32 digest = keccak256( abi.encodePacked( "\x19\x01", domainSeparator, structHash ) ); address signatory = ecrecover(digest, v, r, s); require(signatory != address(0), "EGG::delegateBySig: invalid signature"); require(nonce == nonces[signatory]++, "EGG::delegateBySig: invalid nonce"); require(now <= expiry, "EGG::delegateBySig: signature expired"); return _delegate(signatory, delegatee); } /** * @notice Gets the current votes balance for `account` * @param account The address to get votes balance * @return The number of current votes for `account` */ function getCurrentVotes(address account) external view returns (uint256) { uint32 nCheckpoints = numCheckpoints[account]; return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0; } /** * @notice Determine the prior number of votes for an account as of a block number * @dev Block number must be a finalized block or else this function will revert to prevent misinformation. * @param account The address of the account to check * @param blockNumber The block number to get the vote balance at * @return The number of votes the account had as of the given block */ function getPriorVotes(address account, uint blockNumber) external view returns (uint256) { require(blockNumber < block.number, "EGG::getPriorVotes: not yet determined"); uint32 nCheckpoints = numCheckpoints[account]; if (nCheckpoints == 0) { return 0; } // First check most recent balance if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) { return checkpoints[account][nCheckpoints - 1].votes; } // Next check implicit zero balance if (checkpoints[account][0].fromBlock > blockNumber) { return 0; } uint32 lower = 0; uint32 upper = nCheckpoints - 1; while (upper > lower) { uint32 center = upper - (upper - lower) / 2; // ceil, avoiding overflow Checkpoint memory cp = checkpoints[account][center]; if (cp.fromBlock == blockNumber) { return cp.votes; } else if (cp.fromBlock < blockNumber) { lower = center; } else { upper = center - 1; } } return checkpoints[account][lower].votes; } function _delegate(address delegator, address delegatee) internal { address currentDelegate = _delegates[delegator]; uint256 delegatorBalance = balanceOf(delegator); // balance of underlying EGGs (not scaled); _delegates[delegator] = delegatee; emit DelegateChanged(delegator, currentDelegate, delegatee); _moveDelegates(currentDelegate, delegatee, delegatorBalance); } function _moveDelegates(address srcRep, address dstRep, uint256 amount) internal { if (srcRep != dstRep && amount > 0) { if (srcRep != address(0)) { // decrease old representative uint32 srcRepNum = numCheckpoints[srcRep]; uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0; uint256 srcRepNew = srcRepOld.sub(amount); _writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew); } if (dstRep != address(0)) { // increase new representative uint32 dstRepNum = numCheckpoints[dstRep]; uint256 dstRepOld = dstRepNum > 0 ? checkpoints[dstRep][dstRepNum - 1].votes : 0; uint256 dstRepNew = dstRepOld.add(amount); _writeCheckpoint(dstRep, dstRepNum, dstRepOld, dstRepNew); } } } function _writeCheckpoint( address delegatee, uint32 nCheckpoints, uint256 oldVotes, uint256 newVotes ) internal { uint32 blockNumber = safe32(block.number, "EGG::_writeCheckpoint: block number exceeds 32 bits"); if (nCheckpoints > 0 && checkpoints[delegatee][nCheckpoints - 1].fromBlock == blockNumber) { checkpoints[delegatee][nCheckpoints - 1].votes = newVotes; } else { checkpoints[delegatee][nCheckpoints] = Checkpoint(blockNumber, newVotes); numCheckpoints[delegatee] = nCheckpoints + 1; } emit DelegateVotesChanged(delegatee, oldVotes, newVotes); } function safe32(uint n, string memory errorMessage) internal pure returns (uint32) { require(n < 2**32, errorMessage); return uint32(n); } function getChainId() internal pure returns (uint) { uint256 chainId; assembly { chainId := chainid() } return chainId; } }
查找差异