文件 1 的 9:Address.sol
pragma solidity >=0.6.2 <0.8.0;
library Address {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 9:Context.sol
pragma solidity >=0.6.0 <0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this;
return msg.data;
}
}
文件 3 的 9:DAOstake.sol
pragma solidity 0.7.6;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "./DVGToken.sol";
contract DAOstake is Ownable {
using SafeERC20 for IERC20;
using Address for address;
using SafeMath for uint256;
struct Pool {
address lpTokenAddress;
uint256 poolWeight;
uint256 lastRewardBlock;
uint256 accDVGPerLP;
}
struct User {
uint256 lpAmount;
uint256 finishedDVG;
}
uint256 public constant START_BLOCK = 12770000;
uint256 public constant END_BLOCK = 22234000;
uint256 public constant BLOCK_PER_PERIOD = 91000;
uint256 public constant PERIOD_AMOUNT = 104;
address public treasuryWalletAddr;
address public communityWalletAddr;
DVGToken public dvg;
uint256 public constant TREASURY_WALLET_PERCENT = 2450;
uint256 public constant COMMUNITY_WALLET_PERCENT = 2450;
uint256 public constant POOL_PERCENT = 5100;
uint256 public totalPoolWeight;
Pool[] public pool;
mapping (uint256 => mapping (address => User)) public user;
mapping (uint256 => uint256) public periodDVGPerBlock;
event SetWalletAddress(address indexed treasuryWalletAddr, address indexed communityWalletAddr);
event SetDVG(DVGToken indexed dvg);
event TransferDVGOwnership(address indexed newOwner);
event AddPool(address indexed lpTokenAddress, uint256 indexed poolWeight, uint256 indexed lastRewardBlock);
event SetPoolWeight(uint256 indexed poolId, uint256 indexed poolWeight, uint256 totalPoolWeight);
event UpdatePool(uint256 indexed poolId, uint256 indexed lastRewardBlock, uint256 totalDVG);
event Deposit(address indexed user, uint256 indexed poolId, uint256 amount);
event Withdraw(address indexed user, uint256 indexed poolId, uint256 amount);
event EmergencyWithdraw(address indexed user, uint256 indexed poolId, uint256 amount);
constructor(
address _treasuryWalletAddr,
address _communityWalletAddr,
DVGToken _dvg
) {
periodDVGPerBlock[1] = 30 ether;
for (uint256 i = 2; i <= PERIOD_AMOUNT; i++) {
periodDVGPerBlock[i] = periodDVGPerBlock[i.sub(1)].mul(9650).div(10000);
}
setWalletAddress(_treasuryWalletAddr, _communityWalletAddr);
setDVG(_dvg);
}
function setWalletAddress(address _treasuryWalletAddr, address _communityWalletAddr) public onlyOwner {
require((_treasuryWalletAddr != address(0)) && (_communityWalletAddr != address(0)), "Any wallet address should not be zero address");
treasuryWalletAddr = _treasuryWalletAddr;
communityWalletAddr = _communityWalletAddr;
emit SetWalletAddress(treasuryWalletAddr, communityWalletAddr);
}
function setDVG(DVGToken _dvg) public onlyOwner {
dvg = _dvg;
emit SetDVG(dvg);
}
function transferDVGOwnership(address _newOwner) public onlyOwner {
dvg.transferOwnership(_newOwner);
emit TransferDVGOwnership(_newOwner);
}
function poolLength() external view returns(uint256) {
return pool.length;
}
function getMultiplier(uint256 _from, uint256 _to) public view returns(uint256 multiplier) {
if (_from < START_BLOCK) {_from = START_BLOCK;}
if (_to > END_BLOCK) {_to = END_BLOCK;}
uint256 periodOfFrom = _from.sub(START_BLOCK).div(BLOCK_PER_PERIOD).add(1);
uint256 periodOfTo = _to.sub(START_BLOCK).div(BLOCK_PER_PERIOD).add(1);
if (periodOfFrom == periodOfTo) {
multiplier = _to.sub(_from).mul(periodDVGPerBlock[periodOfTo]);
} else {
uint256 multiplierOfFrom = BLOCK_PER_PERIOD.mul(periodOfFrom).add(START_BLOCK).sub(_from).mul(periodDVGPerBlock[periodOfFrom]);
uint256 multiplierOfTo = _to.sub(START_BLOCK).mod(BLOCK_PER_PERIOD).mul(periodDVGPerBlock[periodOfTo]);
multiplier = multiplierOfFrom.add(multiplierOfTo);
for (uint256 periodId = periodOfFrom.add(1); periodId < periodOfTo; periodId++) {
multiplier = multiplier.add(BLOCK_PER_PERIOD.mul(periodDVGPerBlock[periodId]));
}
}
}
function pendingDVG(uint256 _pid, address _user) external view returns(uint256) {
Pool storage pool_ = pool[_pid];
User storage user_ = user[_pid][_user];
uint256 accDVGPerLP = pool_.accDVGPerLP;
uint256 lpSupply = IERC20(pool_.lpTokenAddress).balanceOf(address(this));
if (block.number > pool_.lastRewardBlock && lpSupply != 0) {
uint256 multiplier = getMultiplier(pool_.lastRewardBlock, block.number);
uint256 dvgForPool = multiplier.mul(POOL_PERCENT).mul(pool_.poolWeight).div(totalPoolWeight).div(10000);
accDVGPerLP = accDVGPerLP.add(dvgForPool.mul(1 ether).div(lpSupply));
}
return user_.lpAmount.mul(accDVGPerLP).div(1 ether).sub(user_.finishedDVG);
}
function addPool(address _lpTokenAddress, uint256 _poolWeight, bool _withUpdate) public onlyOwner {
require(block.number < END_BLOCK, "Already ended");
require(_lpTokenAddress.isContract(), "LP token address should be smart contract address");
if (_withUpdate) {
massUpdatePools();
}
uint256 lastRewardBlock = block.number > START_BLOCK ? block.number : START_BLOCK;
totalPoolWeight = totalPoolWeight + _poolWeight;
pool.push(Pool({
lpTokenAddress: _lpTokenAddress,
poolWeight: _poolWeight,
lastRewardBlock: lastRewardBlock,
accDVGPerLP: 0
}));
emit AddPool(_lpTokenAddress, _poolWeight, lastRewardBlock);
}
function setPoolWeight(uint256 _pid, uint256 _poolWeight, bool _withUpdate) public onlyOwner {
if (_withUpdate) {
massUpdatePools();
}
totalPoolWeight = totalPoolWeight.sub(pool[_pid].poolWeight).add(_poolWeight);
pool[_pid].poolWeight = _poolWeight;
emit SetPoolWeight(_pid, _poolWeight, totalPoolWeight);
}
function updatePool(uint256 _pid) public {
Pool storage pool_ = pool[_pid];
if (block.number <= pool_.lastRewardBlock) {
return;
}
uint256 totalDVG = getMultiplier(pool_.lastRewardBlock, block.number).mul(pool_.poolWeight).div(totalPoolWeight);
uint256 lpSupply = IERC20(pool_.lpTokenAddress).balanceOf(address(this));
if (lpSupply > 0) {
uint256 dvgForPool = totalDVG.mul(POOL_PERCENT).div(10000);
dvg.mint(treasuryWalletAddr, totalDVG.mul(TREASURY_WALLET_PERCENT).div(10000));
dvg.mint(communityWalletAddr, totalDVG.mul(COMMUNITY_WALLET_PERCENT).div(10000));
dvg.mint(address(this), dvgForPool);
pool_.accDVGPerLP = pool_.accDVGPerLP.add(dvgForPool.mul(1 ether).div(lpSupply));
} else {
dvg.mint(treasuryWalletAddr, totalDVG.mul(TREASURY_WALLET_PERCENT).div(10000));
dvg.mint(communityWalletAddr, totalDVG.mul(COMMUNITY_WALLET_PERCENT.add(POOL_PERCENT)).div(10000));
}
pool_.lastRewardBlock = block.number;
emit UpdatePool(_pid, pool_.lastRewardBlock, totalDVG);
}
function massUpdatePools() public {
uint256 length = pool.length;
for (uint256 pid = 0; pid < length; pid++) {
updatePool(pid);
}
}
function deposit(uint256 _pid, uint256 _amount) public {
Pool storage pool_ = pool[_pid];
User storage user_ = user[_pid][msg.sender];
updatePool(_pid);
if (user_.lpAmount > 0) {
uint256 pendingDVG_ = user_.lpAmount.mul(pool_.accDVGPerLP).div(1 ether).sub(user_.finishedDVG);
if(pendingDVG_ > 0) {
_safeDVGTransfer(msg.sender, pendingDVG_);
}
}
if(_amount > 0) {
IERC20(pool_.lpTokenAddress).safeTransferFrom(address(msg.sender), address(this), _amount);
user_.lpAmount = user_.lpAmount.add(_amount);
}
user_.finishedDVG = user_.lpAmount.mul(pool_.accDVGPerLP).div(1 ether);
emit Deposit(msg.sender, _pid, _amount);
}
function withdraw(uint256 _pid, uint256 _amount) public {
Pool storage pool_ = pool[_pid];
User storage user_ = user[_pid][msg.sender];
require(user_.lpAmount >= _amount, "Not enough LP token balance");
updatePool(_pid);
uint256 pendingDVG_ = user_.lpAmount.mul(pool_.accDVGPerLP).div(1 ether).sub(user_.finishedDVG);
if(pendingDVG_ > 0) {
_safeDVGTransfer(msg.sender, pendingDVG_);
}
if(_amount > 0) {
user_.lpAmount = user_.lpAmount.sub(_amount);
IERC20(pool_.lpTokenAddress).safeTransfer(address(msg.sender), _amount);
}
user_.finishedDVG = user_.lpAmount.mul(pool_.accDVGPerLP).div(1 ether);
emit Withdraw(msg.sender, _pid, _amount);
}
function emergencyWithdraw(uint256 _pid) public {
Pool storage pool_ = pool[_pid];
User storage user_ = user[_pid][msg.sender];
uint256 amount = user_.lpAmount;
user_.lpAmount = 0;
user_.finishedDVG = 0;
IERC20(pool_.lpTokenAddress).safeTransfer(address(msg.sender), amount);
emit EmergencyWithdraw(msg.sender, _pid, amount);
}
function _safeDVGTransfer(address _to, uint256 _amount) internal {
uint256 dvgBal = dvg.balanceOf(address(this));
if (_amount > dvgBal) {
dvg.transfer(_to, dvgBal);
} else {
dvg.transfer(_to, _amount);
}
}
}
文件 4 的 9:DVGToken.sol
pragma solidity 0.7.6;
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/math/SafeMath.sol";
contract DVGToken is ERC20("DVGToken", "DVG"), Ownable {
using Address for address;
using SafeMath for uint256;
struct Checkpoint {
uint32 fromBlock;
uint256 votes;
}
uint256 public dvgInAdvance;
address public treasuryWalletAddr;
bytes32 public constant DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,uint256 chainId,address verifyingContract)");
bytes32 public constant DELEGATION_TYPEHASH = keccak256("Delegation(address delegatee,uint256 nonce,uint256 expiry)");
mapping (address => address) internal _delegates;
mapping (address => mapping (uint32 => Checkpoint)) public checkpoints;
mapping (address => uint32) public numCheckpoints;
mapping (address => uint) public nonces;
event DelegateChanged(address indexed delegator, address indexed fromDelegate, address indexed toDelegate);
event DelegateVotesChanged(address indexed delegate, uint previousBalance, uint newBalance);
constructor(address _treasuryWalletAddr, uint256 _dvgInAdvance) {
require(!_treasuryWalletAddr.isContract(), "The Treasury wallet address should not be the smart contract address");
treasuryWalletAddr = _treasuryWalletAddr;
dvgInAdvance = _dvgInAdvance;
mint(treasuryWalletAddr, dvgInAdvance);
}
function mint(address _to, uint256 _amount) public onlyOwner {
_mint(_to, _amount);
_moveDelegates(address(0), _delegates[_to], _amount);
}
function delegates(address delegator)
external
view
returns (address)
{
return _delegates[delegator];
}
function delegate(address delegatee) external {
return _delegate(msg.sender, delegatee);
}
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), "delegateBySig: invalid signature");
require(nonce == nonces[signatory]++, "delegateBySig: invalid nonce");
require(block.timestamp <= expiry, "delegateBySig: signature expired");
return _delegate(signatory, delegatee);
}
function getCurrentVotes(address account)
external
view
returns (uint256)
{
uint32 nCheckpoints = numCheckpoints[account];
return nCheckpoints > 0 ? checkpoints[account][nCheckpoints - 1].votes : 0;
}
function getPriorVotes(address account, uint blockNumber)
external
view
returns (uint256)
{
require(blockNumber < block.number, "getPriorVotes: not yet determined");
uint32 nCheckpoints = numCheckpoints[account];
if (nCheckpoints == 0) {
return 0;
}
if (checkpoints[account][nCheckpoints - 1].fromBlock <= blockNumber) {
return checkpoints[account][nCheckpoints - 1].votes;
}
if (checkpoints[account][0].fromBlock > blockNumber) {
return 0;
}
uint32 lower = 0;
uint32 upper = nCheckpoints - 1;
while (upper > lower) {
uint32 center = upper - (upper - lower) / 2;
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);
_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)) {
uint32 srcRepNum = numCheckpoints[srcRep];
uint256 srcRepOld = srcRepNum > 0 ? checkpoints[srcRep][srcRepNum - 1].votes : 0;
uint256 srcRepNew;
if (srcRepOld > amount) {
srcRepNew = srcRepOld.sub(amount);
} else {
srcRepNew = 0;
amount = srcRepOld;
}
_writeCheckpoint(srcRep, srcRepNum, srcRepOld, srcRepNew);
}
if (dstRep != address(0)) {
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, "_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;
}
}
文件 5 的 9:ERC20.sol
pragma solidity >=0.6.0 <0.8.0;
import "../../GSN/Context.sol";
import "./IERC20.sol";
import "../../math/SafeMath.sol";
contract ERC20 is Context, IERC20 {
using SafeMath for uint256;
mapping (address => uint256) private _balances;
mapping (address => mapping (address => uint256)) private _allowances;
uint256 private _totalSupply;
string private _name;
string private _symbol;
uint8 private _decimals;
constructor (string memory name_, string memory symbol_) public {
_name = name_;
_symbol = symbol_;
_decimals = 18;
}
function name() public view returns (string memory) {
return _name;
}
function symbol() public view returns (string memory) {
return _symbol;
}
function decimals() public view returns (uint8) {
return _decimals;
}
function totalSupply() public view override returns (uint256) {
return _totalSupply;
}
function balanceOf(address account) public view override returns (uint256) {
return _balances[account];
}
function transfer(address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(_msgSender(), recipient, amount);
return true;
}
function allowance(address owner, address spender) public view virtual override returns (uint256) {
return _allowances[owner][spender];
}
function approve(address spender, uint256 amount) public virtual override returns (bool) {
_approve(_msgSender(), spender, amount);
return true;
}
function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) {
_transfer(sender, recipient, amount);
_approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance"));
return true;
}
function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue));
return true;
}
function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
_approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero"));
return true;
}
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
require(sender != address(0), "ERC20: transfer from the zero address");
require(recipient != address(0), "ERC20: transfer to the zero address");
_beforeTokenTransfer(sender, recipient, amount);
_balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance");
_balances[recipient] = _balances[recipient].add(amount);
emit Transfer(sender, recipient, amount);
}
function _mint(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: mint to the zero address");
_beforeTokenTransfer(address(0), account, amount);
_totalSupply = _totalSupply.add(amount);
_balances[account] = _balances[account].add(amount);
emit Transfer(address(0), account, amount);
}
function _burn(address account, uint256 amount) internal virtual {
require(account != address(0), "ERC20: burn from the zero address");
_beforeTokenTransfer(account, address(0), amount);
_balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance");
_totalSupply = _totalSupply.sub(amount);
emit Transfer(account, address(0), amount);
}
function _approve(address owner, address spender, uint256 amount) internal virtual {
require(owner != address(0), "ERC20: approve from the zero address");
require(spender != address(0), "ERC20: approve to the zero address");
_allowances[owner][spender] = amount;
emit Approval(owner, spender, amount);
}
function _setupDecimals(uint8 decimals_) internal {
_decimals = decimals_;
}
function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { }
}
文件 6 的 9:IERC20.sol
pragma solidity >=0.6.0 <0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 7 的 9:Ownable.sol
pragma solidity >=0.6.0 <0.8.0;
import "../GSN/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
文件 8 的 9:SafeERC20.sol
pragma solidity >=0.6.0 <0.8.0;
import "./IERC20.sol";
import "../../math/SafeMath.sol";
import "../../utils/Address.sol";
library SafeERC20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(IERC20 token, address spender, uint256 value) internal {
require((value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
文件 9 的 9:SafeMath.sol
pragma solidity >=0.6.0 <0.8.0;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, "SafeMath: addition overflow");
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, "SafeMath: subtraction overflow");
}
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, "SafeMath: multiplication overflow");
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, "SafeMath: division by zero");
}
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, "SafeMath: modulo by zero");
}
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
}
{
"compilationTarget": {
"contracts/DAOstake.sol": "DAOstake"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_treasuryWalletAddr","type":"address"},{"internalType":"address","name":"_communityWalletAddr","type":"address"},{"internalType":"contract DVGToken","name":"_dvg","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"lpTokenAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"poolWeight","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"lastRewardBlock","type":"uint256"}],"name":"AddPool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract DVGToken","name":"dvg","type":"address"}],"name":"SetDVG","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"poolWeight","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalPoolWeight","type":"uint256"}],"name":"SetPoolWeight","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"treasuryWalletAddr","type":"address"},{"indexed":true,"internalType":"address","name":"communityWalletAddr","type":"address"}],"name":"SetWalletAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"TransferDVGOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalDVG","type":"uint256"}],"name":"UpdatePool","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"poolId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"BLOCK_PER_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COMMUNITY_WALLET_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"END_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PERIOD_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"POOL_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"START_BLOCK","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TREASURY_WALLET_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_lpTokenAddress","type":"address"},{"internalType":"uint256","name":"_poolWeight","type":"uint256"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"addPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"communityWalletAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"dvg","outputs":[{"internalType":"contract DVGToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"getMultiplier","outputs":[{"internalType":"uint256","name":"multiplier","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingDVG","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"periodDVGPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pool","outputs":[{"internalType":"address","name":"lpTokenAddress","type":"address"},{"internalType":"uint256","name":"poolWeight","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"accDVGPerLP","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract DVGToken","name":"_dvg","type":"address"}],"name":"setDVG","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_poolWeight","type":"uint256"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"setPoolWeight","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasuryWalletAddr","type":"address"},{"internalType":"address","name":"_communityWalletAddr","type":"address"}],"name":"setWalletAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalPoolWeight","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferDVGOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryWalletAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"user","outputs":[{"internalType":"uint256","name":"lpAmount","type":"uint256"},{"internalType":"uint256","name":"finishedDVG","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]