ShrimpFarmer 2 智能合约

在这里插入图片描述

// 合约地址: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;
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值