编译器
0.6.12+commit.27d51765
文件 1 的 5:Context.sol
pragma solidity ^0.6.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;
}
}
文件 2 的 5:IERC20.sol
pragma solidity ^0.6.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);
}
文件 3 的 5:Ownable.sol
pragma solidity ^0.6.0;
import "./Context.sol";
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;
}
}
文件 4 的 5:PinknodeLiquidityMining.sol
pragma solidity ^0.6.0;
import "./Ownable.sol";
import "./SafeMath.sol";
import "./IERC20.sol";
contract PinknodeLiquidityMining is Ownable {
using SafeMath for uint;
event Deposit(uint256 _timestmap, address indexed _address, uint256 indexed _pid, uint256 _amount);
event Withdraw(uint256 _timestamp, address indexed _address, uint256 indexed _pid, uint256 _amount);
event EmergencyWithdraw(uint256 _timestamp, address indexed _address, uint256 indexed _pid, uint256 _amount);
IERC20 public constant PNODE = IERC20(0xAF691508BA57d416f895e32a1616dA1024e882D2);
address public fundingAddress = 0xF7897E58A72dFf79Ab8538647A62fecEf8344ffe;
struct LPInfo {
IERC20 lpToken;
uint256 rewardPerBlock;
uint256 lastRewardBlock;
uint256 accRewardPerShare;
}
struct Staker {
uint256 amountStaked;
uint256 rewardDebt;
}
LPInfo[] public liquidityPools;
mapping (uint256 => mapping (address => Staker)) public stakers;
uint256 public startBlock;
uint256 public endBlock;
constructor(uint256 _startBlock) public {
startBlock = _startBlock;
}
function updateFundingAddress(address _address) public onlyOwner {
fundingAddress = _address;
}
function updateStartBlock(uint256 _startBlock) public onlyOwner {
require(startBlock > block.number, "Mining has started, unable to update startBlock");
require(_startBlock > block.number, "startBlock has to be in the future");
for (uint256 i = 0; i < liquidityPools.length; i++) {
LPInfo storage pool = liquidityPools[i];
pool.lastRewardBlock = _startBlock;
}
startBlock = _startBlock;
}
function updateEndBlock(uint256 _endBlock) public onlyOwner {
require(endBlock > block.number || endBlock == 0, "Mining has ended, unable to update endBlock");
require(_endBlock > block.number, "endBlock has to be in the future");
endBlock = _endBlock;
}
function addLiquidityPool(IERC20 _lpToken, uint256 _rewardPerBlock) public onlyOwner {
uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock;
liquidityPools.push(LPInfo({
lpToken: _lpToken,
rewardPerBlock: _rewardPerBlock,
lastRewardBlock: lastRewardBlock,
accRewardPerShare: 0
}));
}
function updateRewardPerBlock(uint256 _pid, uint256 _rewardPerBlock) public onlyOwner {
updatePoolRewards(_pid);
liquidityPools[_pid].rewardPerBlock = _rewardPerBlock;
}
function updatePoolRewards(uint256 _pid) public {
LPInfo storage pool = liquidityPools[_pid];
if (block.number <= pool.lastRewardBlock) {
return;
}
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
if (lpSupply == 0) {
pool.lastRewardBlock = block.number;
return;
}
uint256 blockElapsed = 0;
if (block.number < endBlock || endBlock == 0) {
blockElapsed = (block.number).sub(pool.lastRewardBlock);
} else if (endBlock >= pool.lastRewardBlock) {
blockElapsed = endBlock.sub(pool.lastRewardBlock);
}
uint256 totalReward = blockElapsed.mul(pool.rewardPerBlock);
pool.accRewardPerShare = pool.accRewardPerShare.add(totalReward.mul(1e12).div(lpSupply));
pool.lastRewardBlock = block.number;
}
function deposit(uint256 _pid, uint256 _amount) public {
require(block.number < endBlock || endBlock == 0);
LPInfo storage pool = liquidityPools[_pid];
Staker storage user = stakers[_pid][msg.sender];
updatePoolRewards(_pid);
if (user.amountStaked > 0) {
uint256 pending = user.amountStaked.mul(pool.accRewardPerShare).div(1e12).sub(user.rewardDebt);
if(pending > 0) {
_issueRewards(msg.sender, pending);
}
}
if(_amount > 0) {
require(pool.lpToken.transferFrom(msg.sender, address(this), _amount));
user.amountStaked = user.amountStaked.add(_amount);
}
user.rewardDebt = user.amountStaked.mul(pool.accRewardPerShare).div(1e12);
emit Deposit(block.timestamp, msg.sender, _pid, _amount);
}
function withdraw(uint256 _pid, uint256 _amount) public {
LPInfo storage pool = liquidityPools[_pid];
Staker storage user = stakers[_pid][msg.sender];
require(user.amountStaked >= _amount, "Amount to withdraw more than amount staked");
updatePoolRewards(_pid);
if (user.amountStaked > 0) {
uint256 pending = user.amountStaked.mul(pool.accRewardPerShare).div(1e12).sub(user.rewardDebt);
if(pending > 0) {
_issueRewards(msg.sender, pending);
}
}
if(_amount > 0) {
user.amountStaked = user.amountStaked.sub(_amount);
require(pool.lpToken.transfer(msg.sender, _amount));
}
user.rewardDebt = user.amountStaked.mul(pool.accRewardPerShare).div(1e12);
emit Withdraw(block.timestamp, msg.sender, _pid, _amount);
}
function emergencyWithdraw(uint256 _pid) public {
LPInfo storage pool = liquidityPools[_pid];
Staker storage user = stakers[_pid][msg.sender];
uint256 amount = user.amountStaked;
user.amountStaked = 0;
user.rewardDebt = 0;
require(pool.lpToken.transfer(msg.sender, amount));
emit EmergencyWithdraw(block.timestamp, msg.sender, _pid, amount);
}
function _issueRewards(address _to, uint256 _amount) internal {
require(PNODE.transferFrom(fundingAddress, address(this), _amount));
require(PNODE.transfer(_to, _amount));
}
function pendingRewards(uint256 _pid, address _user) external view returns (uint256) {
LPInfo storage pool = liquidityPools[_pid];
Staker storage user = stakers[_pid][_user];
uint256 accRewardPerShare = pool.accRewardPerShare;
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
if (block.number > pool.lastRewardBlock && lpSupply != 0) {
uint256 blockElapsed = 0;
if (block.number < endBlock || endBlock == 0) {
blockElapsed = (block.number).sub(pool.lastRewardBlock);
} else if (endBlock >= pool.lastRewardBlock) {
blockElapsed = endBlock.sub(pool.lastRewardBlock);
}
uint256 totalReward = blockElapsed.mul(pool.rewardPerBlock);
accRewardPerShare = accRewardPerShare.add(totalReward.mul(1e12).div(lpSupply));
}
return user.amountStaked.mul(accRewardPerShare).div(1e12).sub(user.rewardDebt);
}
}
文件 5 的 5:SafeMath.sol
pragma solidity ^0.6.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/PinknodeLiquidityMining.sol": "PinknodeLiquidityMining"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"uint256","name":"_startBlock","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_timestmap","type":"uint256"},{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":true,"internalType":"uint256","name":"_pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_timestamp","type":"uint256"},{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":true,"internalType":"uint256","name":"_pid","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":false,"internalType":"uint256","name":"_timestamp","type":"uint256"},{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":true,"internalType":"uint256","name":"_pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"PNODE","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_lpToken","type":"address"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"}],"name":"addLiquidityPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fundingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"liquidityPools","outputs":[{"internalType":"contract IERC20","name":"lpToken","type":"address"},{"internalType":"uint256","name":"rewardPerBlock","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"accRewardPerShare","type":"uint256"}],"stateMutability":"view","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":"pendingRewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"stakers","outputs":[{"internalType":"uint256","name":"amountStaked","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_endBlock","type":"uint256"}],"name":"updateEndBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"updateFundingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePoolRewards","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_rewardPerBlock","type":"uint256"}],"name":"updateRewardPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startBlock","type":"uint256"}],"name":"updateStartBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]