// 合约地址:0xb4D95449F1D4a793C7D32aB23a52Ab58Af5FE095
pragma solidity ^0.4.18;
contract VerifyToken {
function totalSupply() public constant returns (uint);
function balanceOf(address tokenOwner) public constant returns (uint balance);
function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
function transfer(address to, uint tokens) public returns (bool success);
function approve(address spender, uint tokens) public returns (bool success);
function transferFrom(address from, address to, uint tokens) public returns (bool success);
bool public activated;
event Transfer(address indexed from, address indexed to, uint tokens);
event Approval(address indexed tokenOwner, address indexed spender, uint tokens);
}
contract ApproveAndCallFallBack {
function receiveApproval(address from, uint256 tokens, address token, bytes data) public;
}
contract EthVerifyCore{
mapping (address => bool) public verifiedUsers;
}
contract ShrimpFarmer is ApproveAndCallFallBack{
using SafeMath for uint;
address vrfAddress=0x5BD574410F3A2dA202bABBa1609330Db02aD64C2;
VerifyToken vrfcontract=VerifyToken(vrfAddress);
//257977574257854071311765966
// 10000000000
//uint256 EGGS_PER_SHRIMP_PER_SECOND=1;
uint256 public EGGS_TO_HATCH_1SHRIMP=86400;
uint public VRF_EGG_COST=(1000000000000000000*300)/EGGS_TO_HATCH_1SHRIMP;
uint256 public STARTING_SHRIMP=300;
uint256 PSN=100000000000000;
uint256 PSNH=50000000000000;
// 倒计时
uint public potDrainTime=2 hours;
// 倒计时增量
uint public POT_DRAIN_INCREMENT=1 hours;
// 倒计时最大值
uint public POT_DRAIN_MAX=3 days;
// 孵化冷却时间
uint public HATCH_COOLDOWN_MAX=6 hours;
// 初始化
bool public initialized=false;
//bool public completed=false;
// ceo地址
address public ceoAddress;
// 开发者地址
address public dev2;
// 用户的冷却时间表
mapping (address => uint256) public hatchCooldown;
// 虾的数量
mapping (address => uint256) public hatcheryShrimp;
// 蛋的数量
mapping (address => uint256) public claimedEggs;
// 最近的孵化时间
mapping (address => uint256) public lastHatch;
// 是否已申请免费
mapping (address => bool) public hasClaimedFree;
// 市场蛋的数量
uint256 public marketEggs;
// eth验证
EthVerifyCore public ethVerify=EthVerifyCore(0x1c307A39511C16F74783fCd0091a921ec29A0b51);
// 上次有人竞标底池
uint public lastBidTime;
// 当前的胜利者
address public currentWinner;
// eth 专门为底池预留的
uint public potEth=0;
// 虾的总量
uint public totalHatcheryShrimp=0;
// 奖励Eth
uint public prizeEth=0;
// 构造函数
function ShrimpFarmer() public{
ceoAddress=msg.sender;
dev2=address(0x95096780Efd48FA66483Bc197677e89f37Ca0CB5);
lastBidTime=now;
currentWinner=msg.sender;
}
// 结束
function finalizeIfNecessary() public{
if(lastBidTime.add(potDrainTime)<now){
//获胜者得到一切,即获胜者得到池子里面的Eth
currentWinner.transfer(this.balance);
initialized=false;
//completed=true;
}
}
// 获取底池消耗,1% totalHatcheryShrimp
function getPotCost() public view returns(uint){
return totalHatcheryShrimp.div(100);
}
// 偷底池:通过减少虾的代价来取消孵化时间
function stealPot() public {
if(initialized){
// 孵化蛋
_hatchEggs(0);
// 获取底池消耗
uint cost=getPotCost();
// 用户 消耗 1% totalHatcheryShrimp
hatcheryShrimp[msg.sender]=hatcheryShrimp[msg.sender].sub(cost);
// 虾池 消耗 1% totalHatcheryShrimp
totalHatcheryShrimp=totalHatcheryShrimp.sub(cost);
// 重置获胜者
setNewPotWinner();
// 用户孵化时间置 0
hatchCooldown[msg.sender]=0;
}
}
// 设置新的获胜者
function setNewPotWinner() private {
finalizeIfNecessary();
if(initialized && msg.sender!=currentWinner){
// 重置倒计时
potDrainTime=lastBidTime.add(potDrainTime).sub(now).add(POT_DRAIN_INCREMENT);
// 如果倒计时大于最大的倒计时,倒计时取最大倒计时
if(potDrainTime>POT_DRAIN_MAX){
potDrainTime=POT_DRAIN_MAX;
}
lastBidTime=now;
// 获胜者是当前用户
currentWinner=msg.sender;
}
}
// 该用户当前目前是不是孵化冷却状态
function isHatchOnCooldown() public view returns(bool){
return lastHatch[msg.sender].add(hatchCooldown[msg.sender])<now;
}
// 孵化蛋
function hatchEggs(address ref) public{
require(isHatchOnCooldown());
_hatchEggs(ref);
}
// 孵化蛋:每次孵化之前,先收蛋。把所有的蛋都孵化了
function _hatchEggs(address ref) private{
require(initialized);
// 收蛋
uint256 eggsUsed=getMyEggs();
// 计算现在蛋的总量,可以产多少只虾
uint256 newShrimp=SafeMath.div(eggsUsed,EGGS_TO_HATCH_1SHRIMP);
// 用户虾的数量增加
hatcheryShrimp[msg.sender]=SafeMath.add(hatcheryShrimp[msg.sender],newShrimp);
// 农场虾的总量也增加
totalHatcheryShrimp=totalHatcheryShrimp.add(newShrimp);
// 用户蛋的数量置 0
claimedEggs[msg.sender]=0;
// 用户的最后一次孵化时间置为当前时间
lastHatch[msg.sender]=now;
// 孵化冷却时间
hatchCooldown[msg.sender]=HATCH_COOLDOWN_MAX;
// eggsUsed处理,有 (100/7)%流向市场,导致市场的蛋通胀。
require(ref!=msg.sender);
if(ref!=0){
// 有推荐人就奖励推荐人,没有推荐人也得流到市场
claimedEggs[ref]=claimedEggs[ref].add(eggsUsed.div(7));
}
// 促进市场削弱虾囤积
marketEggs=SafeMath.add(marketEggs,SafeMath.div(eggsUsed,7));
}
// 计算孵化冷却时间
function getHatchCooldown(uint eggs) public view returns(uint){
// 市场蛋的数量的 2%
uint targetEggs=marketEggs.div(50);
// 孵化的蛋的数量 大于市场的2%
if(eggs>=targetEggs){
// 孵化时间置为最大值
return HATCH_COOLDOWN_MAX;
}
// 孵化的蛋的数量 小于市场的2%,孵化时间置为 HATCH_COOLDOWN_MAX * (eggs/(2%*marketEggs))
return (HATCH_COOLDOWN_MAX.mul(eggs)).div(targetEggs);
}
// 降低孵化冷却时间
function reduceHatchCooldown(address addr,uint eggs) private{
// 获取降低冷却时间的值
uint reduction=getHatchCooldown(eggs);
// 如果 降低冷却时间的值 比 用户当前的孵化冷却时间还要长
if(reduction>=hatchCooldown[addr]){
// 孵化时间赋值为0
hatchCooldown[addr]=0;
}
else{
// 否则,孵化时间减掉降低孵化冷却时间的值
hatchCooldown[addr]=hatchCooldown[addr].sub(reduction);
}
}
// 卖Egg
function sellEggs() public{
require(initialized);
// 计算当前的获胜者
finalizeIfNecessary();
// 计算用户蛋的总量
uint256 hasEggs=getMyEggs();
// Eth的数量
uint256 eggValue=calculateEggSell(hasEggs);
// 20%的费用
uint potfee=potFee(eggValue);
claimedEggs[msg.sender]=0;
lastHatch[msg.sender]=now;
// marketEggs 累加 hasEggs
marketEggs=SafeMath.add(marketEggs,hasEggs);
//ceoAddress.transfer(fee);
// 奖励的Eth累加,20%的费用
prizeEth=prizeEth.add(potfee);
// 实际得到的需要扣掉20%手续费
msg.sender.transfer(eggValue.sub(potfee));
}
// 买Egg
function buyEggs() public payable{
require(initialized);
// 得到买到的Egg的数量
uint256 eggsBought=calculateEggBuy(msg.value,SafeMath.sub(this.balance,msg.value));
// ********* 此处貌似逻辑错误,eggBought 和 手续费 比例对不上 *************
// 扣掉ceo的费用
eggsBought=eggsBought.sub(devFee(eggsBought));
// 扣掉 开发者的费用
eggsBought=eggsBought.sub(devFee2(eggsBought));
// 4%手续费转给ceo
ceoAddress.transfer(devFee(msg.value));
// 1%手续费转给开发者
dev2.transfer(devFee2(msg.value));
// 给用户添加蛋
claimedEggs[msg.sender]=SafeMath.add(claimedEggs[msg.sender],eggsBought);
// 根据购买的鸡蛋减少孵化冷却时间,买超过marketEgg的2%,取消冷却时间
reduceHatchCooldown(msg.sender,eggsBought);
//steal the pot if bought enough
uint potEggCost=getPotCost().mul(EGGS_TO_HATCH_1SHRIMP);//the equivalent number of eggs to the pot cost in shrimp
// 购买超过超过marketEgg的1%
if(eggsBought>potEggCost){
// 设置新的获胜者
setNewPotWinner();
}
}
// 供需平衡算法
function calculateTrade(uint256 rt,uint256 rs, uint256 bs) public view returns(uint256){
//(PSN*bs)/(PSNH+((PSN*rs+PSNH*rt)/rt)); PSN/PSNH == 1/2
// bs * (1/(1+(rs/rt)))
// 买入: marketEggs * 1/((1 + (this.balance/eth)))
// 卖出: this.balance * 1/((1 + (marketEggs/eggs)))
return SafeMath.div(SafeMath.mul(PSN,bs),SafeMath.add(PSNH,SafeMath.div(SafeMath.add(SafeMath.mul(PSN,rs),SafeMath.mul(PSNH,rt)),rt)));
}
// 返回Eth的数量
function calculateEggSell(uint256 eggs) public view returns(uint256){
return calculateTrade(eggs,marketEggs,this.balance.sub(prizeEth));
}
// 返回Egg的数量
function calculateEggBuy(uint256 eth,uint256 contractBalance) public view returns(uint256){
return calculateTrade(eth,contractBalance.sub(prizeEth),marketEggs);
}
// 简单计算蛋的购买量
function calculateEggBuySimple(uint256 eth) public view returns(uint256){
return calculateEggBuy(eth,this.balance);
}
// 20%费用
function potFee(uint amount) public view returns(uint){
return SafeMath.div(SafeMath.mul(amount,20),100);
}
// 4%手续费
function devFee(uint256 amount) public view returns(uint256){
return SafeMath.div(SafeMath.mul(amount,4),100);
}
// 1%手续费
function devFee2(uint256 amount) public view returns(uint256){
return SafeMath.div(amount,100);
}
// ceo启动市场
function seedMarket(uint256 eggs) public payable{
require(msg.sender==ceoAddress);
require(!initialized);
initialized=true;
marketEggs=eggs;
lastBidTime=now;
}
// Tokens are exchanged for shrimp by sending them to this contract with ApproveAndCall
function receiveApproval(address from, uint256 tokens, address token, bytes data) public{
require(!initialized);
require(msg.sender==vrfAddress);
require(ethVerify.verifiedUsers(from));//you must now be verified for this
require(claimedEggs[from].add(tokens.div(VRF_EGG_COST))<=1001*EGGS_TO_HATCH_1SHRIMP);//you may now trade for a max of 1000 eggs
vrfcontract.transferFrom(from,this,tokens);
claimedEggs[from]=claimedEggs[from].add(tokens.div(VRF_EGG_COST));
}
// 允许合约转eth
function () public payable {}
// 获取免费的egg
function claimFreeEggs() public{
// RE ENABLE THIS BEFORE DEPLOYING MAINNET
require(ethVerify.verifiedUsers(msg.sender));
require(initialized);
require(!hasClaimedFree[msg.sender]);
claimedEggs[msg.sender]=claimedEggs[msg.sender].add(getFreeEggs());
_hatchEggs(0);
hatchCooldown[msg.sender]=0;
hasClaimedFree[msg.sender]=true;
}
// 白嫖Egg,白嫖的数量为 当前合约账户余额的 0.25% 购买Egg数量 和 0.01ether 购买Egg数量 的最小值
function getFreeEggs() public view returns(uint){
return min(calculateEggBuySimple(this.balance.div(400)),calculateEggBuySimple(0.01 ether));
}
// 查看合约账户余额
function getBalance() public view returns(uint256){
return this.balance;
}
// 查看用户的虾
function getMyShrimp() public view returns(uint256){
return hatcheryShrimp[msg.sender];
}
// 收蛋
function getMyEggs() public view returns(uint256){
// 已有的蛋 + 这次收到的蛋
return SafeMath.add(claimedEggs[msg.sender],getEggsSinceLastHatch(msg.sender));
}
// 计算收多少蛋
function getEggsSinceLastHatch(address adr) public view returns(uint256){
// 每只虾每秒产 1 个蛋,超过一天没收蛋,按一天的时间计算
uint256 secondsPassed=min(EGGS_TO_HATCH_1SHRIMP,SafeMath.sub(now,lastHatch[adr]));
// 虾的数量 乘以 每只虾的产量
return SafeMath.mul(secondsPassed,hatcheryShrimp[adr]);
}
function min(uint256 a, uint256 b) private pure returns (uint256) {
return a < b ? a : b;
}
}
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return c;
}
/**
* @dev Substracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
assert(c >= a);
return c;
}
}
ShrimpFarmer 2 智能合约
最新推荐文章于 2024-10-02 21:45:19 发布