文件 1 的 1:SpiStake.sol
pragma solidity 0.6.12;
interface IBEP20 {
function totalSupply() external view returns (uint256);
function balanceOf(address who) external view returns (uint256);
function allowance(address owner, address spender)
external view returns (uint256);
function transfer(address to, uint256 value) external returns (bool);
function approve(address spender, uint256 value)
external returns (bool);
function transferFrom(address from, address to, uint256 value)
external returns (bool);
}
library SafeMath {
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b);
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a / b;
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
require(b <= a);
return a - b;
}
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a);
return c;
}
}
contract SPIStaking {
using SafeMath for uint256;
address payable internal owner;
IBEP20 internal spi = IBEP20(address(0x9B02dD390a603Add5c07f9fd9175b7DABE8D63B7));
uint256 constant internal MAGNITUDE = 2 ** 64;
uint32 constant private DROP_RATE = 165;
mapping(address => uint256) public stakedOf;
mapping(address => int256) private payoutsTo;
mapping(address => uint256) public claimedOf;
uint256 private profitPerShare;
uint256 private totalSupply;
uint256 public lastDripTime = now;
modifier onlyOwner() {
require(msg.sender == owner,"NO_AUTH");
_;
}
constructor() public {
owner = msg.sender;
}
modifier hasDripped(){
uint256 pool = getPool();
if(pool > 0 && totalSupply > 0){
uint256 cyclePassed = SafeMath.sub(now,lastDripTime);
uint256 dividends = cyclePassed*((pool * DROP_RATE) / 100000000);
if (dividends > pool) {
dividends = pool;
}
profitPerShare = SafeMath.add(profitPerShare, (dividends * MAGNITUDE) / totalSupply);
lastDripTime = now ;
}
_;
}
function stake(uint256 amount) hasDripped public
{
require(amount > 0);
uint256 currentBalance = spi.balanceOf(address(this));
spi.transferFrom(msg.sender, address(this), amount);
uint256 diff = spi.balanceOf(address(this)) - currentBalance;
require(diff > 0);
if(getPool() > 0){
lastDripTime = now;
}
totalSupply = SafeMath.add(totalSupply,diff);
stakedOf[msg.sender] = SafeMath.add(stakedOf[msg.sender], diff);
payoutsTo[msg.sender] += (int256) (profitPerShare * diff);
}
function unstake(uint256 _amount) hasDripped public
{
require(_amount <= stakedOf[msg.sender]);
totalSupply -= _amount;
stakedOf[msg.sender]= SafeMath.sub(stakedOf[msg.sender], _amount);
payoutsTo[msg.sender] -= (int256) (profitPerShare * _amount);
spi.transfer(msg.sender,_amount);
}
function claimEarning() hasDripped public {
uint256 divs = dividendsOf(msg.sender);
require(divs > 0 , "NO_DIV");
payoutsTo[msg.sender] += (int256) (divs * MAGNITUDE);
claimedOf[msg.sender] += divs;
spi.transfer(msg.sender,divs);
}
function getGlobalInfo() public view returns (uint256 ,uint256){
return (getPool(),totalSupply);
}
function estimateDividendsOf(address _customerAddress) public view returns (uint256) {
uint256 pool = getPool();
if(pool > 0 && totalSupply > 0){
uint256 _profitPerShare = profitPerShare;
uint256 cyclePassed = SafeMath.sub(now,lastDripTime);
uint256 dividends = cyclePassed*((pool * DROP_RATE) / 100000000);
if (dividends > pool) {
dividends = pool;
}
_profitPerShare = SafeMath.add(profitPerShare, (dividends * MAGNITUDE) / totalSupply);
return (uint256) ((int256) (_profitPerShare * stakedOf[_customerAddress]) - payoutsTo[_customerAddress]) / MAGNITUDE;
}else{
return 0;
}
}
function dividendsOf(address _customerAddress) public view returns (uint256) {
return (uint256) ((int256) (profitPerShare * stakedOf[_customerAddress]) - payoutsTo[_customerAddress]) / MAGNITUDE ;
}
function getPool() internal view returns (uint256) {
return spi.balanceOf(address(this)) - totalSupply;
}
}
{
"compilationTarget": {
"browser/SpiStake.sol": "SPIStaking"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}