// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* This test is non-exhaustive, and there may be false-negatives: during the
* execution of a contract's constructor, its address will be reported as
* not containing a contract.
*
* IMPORTANT: It is unsafe to assume that an address for which this
* function returns false is an externally-owned account (EOA) and not a
* contract.
*/
function isContract(address account) internal view returns (bool) {
// This method relies in extcodesize, which returns 0 for contracts in
// construction, since the code is only stored at the end of the
// constructor execution.
// According to EIP-1052, 0x0 is the value returned for not-yet created accounts
// and 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470 is returned
// for accounts without code, i.e. `keccak256('')`
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
// solhint-disable-next-line no-inline-assembly
assembly { codehash := extcodehash(account) }
return (codehash != 0x0 && codehash != accountHash);
}
/**
* @dev Converts an `address` into `address payable`. Note that this is
* simply a type cast: the actual underlying value is not changed.
*
* _Available since v2.4.0._
*/
function toPayable(address account) internal pure returns (address payable) {
return address(uint160(account));
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*
* _Available since v2.4.0._
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
// solhint-disable-next-line avoid-call-value
(bool success, ) = recipient.call{value:amount}(new bytes(0));
require(success, "Address: unable to send value, recipient may have reverted");
}
}
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
interface IERC1155 {
// Events
/**
* @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
* Operator MUST be msg.sender
* When minting/creating tokens, the `_from` field MUST be set to `0x0`
* When burning/destroying tokens, the `_to` field MUST be set to `0x0`
* The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
* To broadcast the existence of a token ID with no initial balance, the contract SHOULD emit the TransferSingle event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
*/
event TransferSingle(address indexed _operator, address indexed _from, address indexed _to, uint256 _id, uint256 _amount);
/**
* @dev Either TransferSingle or TransferBatch MUST emit when tokens are transferred, including zero amount transfers as well as minting or burning
* Operator MUST be msg.sender
* When minting/creating tokens, the `_from` field MUST be set to `0x0`
* When burning/destroying tokens, the `_to` field MUST be set to `0x0`
* The total amount transferred from address 0x0 minus the total amount transferred to 0x0 may be used by clients and exchanges to be added to the "circulating supply" for a given token ID
* To broadcast the existence of multiple token IDs with no initial balance, this SHOULD emit the TransferBatch event from `0x0` to `0x0`, with the token creator as `_operator`, and a `_amount` of 0
*/
event TransferBatch(address indexed _operator, address indexed _from, address indexed _to, uint256[] _ids, uint256[] _amounts);
/**
* @dev MUST emit when an approval is updated
*/
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
/**
* @dev MUST emit when the URI is updated for a token ID
* URIs are defined in RFC 3986
* The URI MUST point a JSON file that conforms to the "ERC-1155 Metadata JSON Schema"
*/
event URI(string _amount, uint256 indexed _id);
/**
* @notice Transfers amount of an _id from the _from address to the _to address specified
* @dev MUST emit TransferSingle event on success
* Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
* MUST throw if `_to` is the zero address
* MUST throw if balance of sender for token `_id` is lower than the `_amount` sent
* MUST throw on any other error
* When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155Received` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
* @param _from Source address
* @param _to Target address
* @param _id ID of the token type
* @param _amount Transfered amount
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeTransferFrom(address _from, address _to, uint256 _id, uint256 _amount, bytes calldata _data) external;
/**
* @notice Send multiple types of Tokens from the _from address to the _to address (with safety call)
* @dev MUST emit TransferBatch event on success
* Caller must be approved to manage the _from account's tokens (see isApprovedForAll)
* MUST throw if `_to` is the zero address
* MUST throw if length of `_ids` is not the same as length of `_amounts`
* MUST throw if any of the balance of sender for token `_ids` is lower than the respective `_amounts` sent
* MUST throw on any other error
* When transfer is complete, this function MUST check if `_to` is a smart contract (code size > 0). If so, it MUST call `onERC1155BatchReceived` on `_to` and revert if the return amount is not `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
* Transfers and events MUST occur in the array order they were submitted (_ids[0] before _ids[1], etc)
* @param _from Source addresses
* @param _to Target addresses
* @param _ids IDs of each token type
* @param _amounts Transfer amounts per token type
* @param _data Additional data with no specified format, sent in call to `_to`
*/
function safeBatchTransferFrom(address _from, address _to, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external;
/**
* @notice Get the balance of an account's Tokens
* @param _owner The address of the token holder
* @param _id ID of the Token
* @return The _owner's balance of the Token type requested
*/
function balanceOf(address _owner, uint256 _id) external view returns (uint256);
/**
* @notice Get the balance of multiple account/token pairs
* @param _owners The addresses of the token holders
* @param _ids ID of the Tokens
* @return The _owner's balance of the Token types requested (i.e. balance for each (owner, id) pair)
*/
function balanceOfBatch(address[] calldata _owners, uint256[] calldata _ids) external view returns (uint256[] memory);
/**
* @notice Enable or disable approval for a third party ("operator") to manage all of caller's tokens
* @dev MUST emit the ApprovalForAll event on success
* @param _operator Address to add to the set of authorized operators
* @param _approved True if the operator is approved, false to revoke approval
*/
function setApprovalForAll(address _operator, bool _approved) external;
function isApprovedForAll(address _owner, address _operator) external view returns (bool isOperator);
}
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
/**
* @dev ERC-1155 interface for accepting safe transfers.
*/
interface IERC1155TokenReceiver {
/**
* @notice Handle the receipt of a single ERC1155 token type
* @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeTransferFrom` after the balance has been updated
* This function MAY throw to revert and reject the transfer
* Return of other amount than the magic value MUST result in the transaction being reverted
* Note: The token contract address is always the message sender
* @param _operator The address which called the `safeTransferFrom` function
* @param _from The address which previously owned the token
* @param _id The id of the token being transferred
* @param _amount The amount of tokens being transferred
* @param _data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
*/
function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _amount, bytes calldata _data) external returns(bytes4);
/**
* @notice Handle the receipt of multiple ERC1155 token types
* @dev An ERC1155-compliant smart contract MUST call this function on the token recipient contract, at the end of a `safeBatchTransferFrom` after the balances have been updated
* This function MAY throw to revert and reject the transfer
* Return of other amount than the magic value WILL result in the transaction being reverted
* Note: The token contract address is always the message sender
* @param _operator The address which called the `safeBatchTransferFrom` function
* @param _from The address which previously owned the token
* @param _ids An array containing ids of each token being transferred
* @param _amounts An array containing amounts of each token being transferred
* @param _data Additional data with no specified format
* @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
*/
function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _amounts, bytes calldata _data) external returns(bytes4);
/**
* @notice Indicates whether a contract implements the `ERC1155TokenReceiver` functions and so can accept ERC1155 token types.
* @param interfaceID The ERC-165 interface ID that is queried for support.s
* @dev This function MUST return true if it implements the ERC1155TokenReceiver interface and ERC-165 interface.
* This function MUST NOT consume more than 5,000 gas.
* @return Wheter ERC-165 or ERC1155TokenReceiver interfaces are supported.
*/
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./SafeMath.sol";
import "./IERC1155.sol";
import "./IERC1155TokenReceiver.sol";
import "./Ownable.sol";
import "./Address.sol";
// sns: [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17]
// ids:[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18]
// fertilities:[1,2,5,10,30,100,1,2,5,10,30,100,10,20,50,100,300,1000]
// carries:[0,0,0,0,0,0,10,20,50,100,300,1000,1,2,5,10,30,100]
interface MiningPool{
function users(address userAddress) external view returns(uint256 id,uint256 investment,uint256 freezeTime);
function balanceOf(address userAddress) external view returns (address[2] memory,uint256[2] memory balances);
function totalSupply() external view returns (uint256);
function stakeAmount() external view returns (uint256);
function duration() external view returns (uint256);
function token() external view returns (address);
function deposit(uint256[2] calldata amounts) external returns(bool);
function allot(address userAddress,uint256[2] calldata amounts) external returns(bool);
function lock(address holder, address locker, uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) external;
function lockStatus(address userAddress) external view returns(bool);
}
interface IUniswapPair {
function setFeeOwner(address _feeOwner) external;
}
interface IUniswapFactory {
function getPair(address token0,address token1) external returns(address);
}
abstract contract ERC1155TokenReceiver is IERC1155TokenReceiver{
bytes4 constant internal ERC1155_RECEIVED_VALUE = 0xf23a6e61;
bytes4 constant internal ERC1155_BATCH_RECEIVED_VALUE = 0xbc197c81;
//-------------------------------------ERC1155---------------------------------------------------------------------
function onERC1155Received(address _operator, address _from, uint256 _id, uint256 _value, bytes calldata _data) external override returns(bytes4) {
uint256[] memory _values = new uint256[](1);
uint256[] memory _ids = new uint256[](1);
_ids[0] = _id;
_values[0] = _value;
operateToken1155(msg.sender,_operator,_from,_ids,_values,_data);
return ERC1155_RECEIVED_VALUE;
}
function onERC1155BatchReceived(address _operator, address _from, uint256[] calldata _ids, uint256[] calldata _values, bytes calldata _data) external override returns(bytes4) {
operateToken1155(msg.sender,_operator,_from,_ids,_values,_data);
return ERC1155_BATCH_RECEIVED_VALUE;
}
// ERC165 interface support
function supportsInterface(bytes4 interfaceID) external override pure returns (bool) {
return interfaceID == 0x01ffc9a7 || // ERC165
interfaceID == 0x4e2312e0; // ERC1155_ACCEPTED ^ ERC1155_BATCH_ACCEPTED;
}
function operateToken1155(address msgSender, address _operator, address _from, uint256[] memory _ids, uint256[] memory _values, bytes calldata _data) internal virtual;
}
contract Config{
uint256 public constant ONE_DAY = 1 days;
uint256[10] public RANKING_AWARD_PERCENT = [10,5,3,1,1,1,1,1,1,1];
uint256 public constant LAST_STRAW_PERCNET = 5;
uint256[2] public OUT_RATE = [1,1];
}
contract MiningCore is Config, Ownable, ERC1155TokenReceiver {
using SafeMath for uint256;
constructor(MiningPool _pool,IERC1155 _token1155,address payable _developer) {
pool = _pool;
token1155 = _token1155;
developer = _developer;
}
MiningPool public pool;
IERC1155 public token1155;
uint256 public ORE_AMOUNT = 250000000;
struct Record{
//提现状态
bool drawStatus;
//挖矿总量
uint256 digGross;
//最后一击
bool lastStraw;
mapping(uint256=>uint256) disCars;
}
struct Pair {
uint256[2] amounts;
//挖矿总量
uint256 complete;
//实际挖矿量
uint256 actual;
uint256 oracleAmount;
address lastStraw;
}
struct Car{
uint256 sn;
uint256 fertility;
uint256 carry;
}
//address[] callHelper;
address payable developer;
uint256 public version;
//User acquisition record
//mapping(uint256=>mapping(address=>bool)) public obtainLogs;
mapping(uint256=>mapping(address=>Record)) public records;
//Record of each mining period
mapping(uint256=>Pair) public history;
//Daily output
mapping(uint256=>uint256) public dailyOutput;
//The number corresponds to the carIndex
uint256[] public carIndex;
//Each ID corresponds to a car attribute
mapping(uint256=>Car) public cars;
mapping(uint256=> address[10]) public rank;
event ObtainCar(address indexed userAddress,uint256 indexed _version,uint256 amount );
event Mining(address indexed userAddress,uint256 indexed _version,uint256[] ,uint256[],uint256 amount);
event WithdrawAward(address indexed userAddress,uint256 indexed _version,uint256[2] amounts);
event UpdateRank(address indexed operator);
event DeveloperFee(uint256 fee1,uint256 fee2);
event SetCarIndex(uint256 sn,uint256 id,uint256 fertility,uint256 carry);
event LastStraw(address indexed userAddress,uint256 _version,uint256,uint256,uint256);
function init() public onlyOwner {
uint256[18] memory _ids = [uint256(1),2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18];
uint256[18] memory _fertilities = [uint256(1),2,5,10,30,100,1,2,5,10,30,100,10,20,50,100,300,1000];
uint256[18] memory _carries = [uint256(1),2,5,10,30,100,10,20,50,100,300,1000,1,2,5,10,30,100];
setCarIndexs(_ids,_fertilities,_carries);
}
//Set vehicle properties
function setCarIndex(uint256 sn,uint256 id,uint256 fertility,uint256 carry) public onlyOwner{
if(sn+1>carIndex.length){
carIndex.push(id);
//callHelper.push(address(this));
}else{
carIndex[sn] = id;
}
cars[id] = Car(sn,fertility,carry);
emit SetCarIndex( sn, id, fertility, carry);
}
//Batch set vehicle properties
function setCarIndexs(uint256[18] memory ids,uint256[18] memory fertilities,uint256[18] memory carries) private {
for(uint256 i=0;i<ids.length;i++){
setCarIndex(i,ids[i],fertilities[i],carries[i]);
}
}
function setFeeOwner(address _feeOwner,address factory) external onlyOwner {
(address[2] memory tokens,) = pool.balanceOf(address(0));
address pair = IUniswapFactory(factory).getPair(tokens[0],tokens[1]);
IUniswapPair(pair).setFeeOwner(_feeOwner);
}
function setOracle(uint256 _ORE_AMOUNT) public onlyOwner {
ORE_AMOUNT = _ORE_AMOUNT;
}
function operateToken1155(address msgSender,address _operator, address _from, uint256[] memory _ids, uint256[] memory _values, bytes calldata) internal override virtual{
require(address(token1155)==msgSender,"not allowed");
require(!Address.isContract(_operator),"Contract invocation is not allowed");
if(_from!=address(0x0)){
mining(_from,_ids,_values);
}
}
function obtainCar(uint256 nonce, uint256 expiry, bool allowed, uint8 v, bytes32 r, bytes32 s) public {
require(!pool.lockStatus(msg.sender),"Have been received");
(,uint256[] memory counts,uint256 len,uint256 token1155Amount,uint256 quantity) = cat(msg.sender);
if(dailyOutput[pool.duration()]==0){
dailyOutput[pool.duration()] = token1155Amount;
}
pool.lock(msg.sender,address(this),nonce,expiry,allowed,v,r,s);
//token1155.safeBatchTransferFrom(address(this),msg.sender,carIndex,carUsable,"success");
}
function withdrawAward(uint256 _version) public {
require(!records[_version][msg.sender].drawStatus,"have withdrawal");
require(_version<version,"Event not over");
(uint256[2] memory amounts) = getVersionAward(_version,msg.sender);
records[_version][msg.sender].drawStatus = true;
pool.allot(msg.sender,amounts);
emit WithdrawAward(msg.sender,_version,amounts);
}
function getVersionAward(uint256 _version,address userAddress) public view returns(uint256[2] memory amounts){
Pair memory pair = history[_version];
return getPredictAward(_version,userAddress,pair);
}
function getPredictAward(uint256 _version,address userAddress,Pair memory pair) internal view returns(uint256[2] memory amounts){
Record storage record = records[_version][userAddress];
uint256 ranking = getRanking(userAddress,_version);
for(uint8 i = 0;i<2;i++){
uint256 baseAmount = pair.amounts[i].mul(70).div(100);
uint256 awardAmount = pair.amounts[i].mul(30).div(100);
amounts[i] = amounts[i].add(baseAmount.mul(record.digGross).div(pair.oracleAmount==0?ORE_AMOUNT:pair.oracleAmount));
if(ranking<10){
amounts[i] = amounts[i].add(awardAmount.mul(RANKING_AWARD_PERCENT[ranking]).div(30));
}
if(record.lastStraw){
amounts[i] = amounts[i].add(awardAmount.mul(LAST_STRAW_PERCNET).div(30));
}
}
}
function getGlobalStats(uint256 _version) external view returns (uint256[5] memory stats,address lastStrawUser) {
Pair memory pair = history[_version];
if(_version==version){
(,uint256[2] memory balances) = pool.balanceOf(address(this));
pair.amounts = balances;
}
stats[0] = pair.amounts[0];
stats[1] = pair.amounts[1];
stats[2] = pair.complete;
stats[3] = pair.actual;
stats[4] = (pool.duration()+1)*ONE_DAY;
lastStrawUser = pair.lastStraw;
}
function crown(uint256 _version) external view returns (address[10] memory ranking,uint256[10] memory digGross){
ranking = sortRank(_version);
for(uint8 i =0;i<ranking.length;i++){
digGross[i] = getDigGross(ranking[i],_version);
}
}
function getPersonalStats(uint256 _version,address userAddress) external view returns (uint256[8] memory stats,bool[3] memory stats2,uint256[] memory departs){
Record storage record = records[_version][userAddress];
(uint256 id,uint256 investment,uint256 freezeTime) = pool.users(userAddress);
stats[0] = investment;
stats[1] = record.digGross;
Pair memory pair = history[_version];
if(_version==version){
(,uint256[2] memory balances) = pool.balanceOf(address(this));
pair.amounts = balances;
}
uint256[2] memory amounts = getPredictAward(_version,userAddress,pair);
stats[2] = amounts[1];
stats[3] = amounts[0];
stats[4] = id;
stats[5] = freezeTime;
stats[6] = getRanking(userAddress,_version)+1;
stats2[0] = record.drawStatus;
stats2[1] = record.lastStraw;
stats2[2] = pool.lockStatus(userAddress);
departs = new uint256[](kinds());
uint256 total;
for(uint256 i =0;i<kinds();i++){
uint256 depart = getDepartCars(_version,userAddress,carIndex[i]);
departs[i] = depart;
total = total.add(depart);
}
stats[7] = total;
}
function getDepartCars(uint256 _version,address userAddress,uint256 _carId) public view returns(uint256){
return records[_version][userAddress].disCars[_carId];
}
function mining(address userAddress,uint256[] memory ids,uint256[] memory amounts) internal returns(uint256){
Pair storage pair = history[version];
require(ids.length>0&&ids.length == amounts.length,"error");
uint256 carFertility;
uint256 carCarry;
Record storage record = records[version][userAddress];
uint256 output;
for(uint256 i = 0;i<ids.length;i++){
Car memory car = cars[ids[i]];
carFertility = carFertility.add(car.fertility.mul(amounts[i]));
carCarry = carCarry.add(car.carry.mul(amounts[i]));
record.disCars[ids[i]] = record.disCars[ids[i]].add(amounts[i]);
}
if(carFertility>carCarry){
output = carCarry;
}else{
output = carFertility;
}
uint256 miningQuantity = pair.complete.add(carFertility);
if(pair.complete.add(output)>ORE_AMOUNT){
output = ORE_AMOUNT>pair.complete?ORE_AMOUNT-pair.complete:0;
}
record.digGross = record.digGross.add(output);
pair.complete = pair.complete.add(carFertility);
pair.actual = pair.actual.add(output);
updateRank(userAddress);
if(miningQuantity>=ORE_AMOUNT){
emit LastStraw(userAddress,version,carFertility,carCarry,output);
lastStraw(userAddress,pair);
}
token1155.safeBatchTransferFrom(address(this),owner(),ids,amounts,"success");
emit Mining(userAddress,version,ids,amounts,output);
return output;
}
function getRanking(address userAddress,uint256 _version) public view returns(uint256){
address[10] memory rankingList = sortRank(_version);
uint256 ranking = 10;
for(uint8 i =0;i<rankingList.length;i++){
if(userAddress == rankingList[i]){
ranking = i;
break;
}
}
return ranking;
}
function pickUp(address[10] memory rankingList,address userAddress) internal view returns (uint256 sn,uint256 minDig){
minDig = getDigGross(rankingList[0]);
for(uint8 i =0;i<rankingList.length;i++){
if(rankingList[i]==userAddress){
return (rankingList.length,0);
}
if(getDigGross(rankingList[i])<minDig){
minDig = getDigGross(rankingList[i]);
sn = i;
}
}
return (sn,minDig);
}
function updateRank(address userAddress) internal {
address[10] memory rankingList = rank[version];
(uint256 sn,uint256 minDig) = pickUp(rankingList,userAddress);
if(sn!=rankingList.length){
if(minDig< getDigGross(userAddress)){
rankingList[sn] = userAddress;
}
rank[version] = rankingList;
emit UpdateRank(userAddress);
}
}
function sortRank(uint256 _version) public view returns(address[10] memory ranking){
ranking = rank[_version];
address tmp;
for(uint8 i = 1;i<5;i++){
for(uint8 j = 0;j<5-i;j++){
if(getDigGross(ranking[j],_version)<getDigGross(ranking[j+1],_version)){
tmp = ranking[j];
ranking[j] = ranking[j+1];
ranking[j+1] = tmp;
}
}
}
return ranking;
}
function getDigGross(address userAddress) internal view returns(uint256){
return getDigGross(userAddress,version);
}
function getDigGross(address userAddress,uint256 _version) internal view returns(uint256){
return records[_version][userAddress].digGross;
}
function lastStraw(address userAddress,Pair storage pair) internal{
(address[2] memory tokens,uint256[2] memory amounts) = pool.balanceOf(address(this));
for(uint8 i;i<amounts.length;i++){
TransferHelper.safeApprove(tokens[i],address(pool),amounts[i]);
}
pool.deposit(amounts);
pair.amounts = amounts;
pair.lastStraw = userAddress;
pair.oracleAmount = ORE_AMOUNT;
records[version][userAddress].lastStraw = true;
developerFee(pair);
version++;
}
//项目方收款
function developerFee(Pair storage pair) internal{
uint256[2] memory amounts;
address[10] memory rankingList = rank[version];
uint count;
for(uint i = 0;i<rankingList.length;i++) {
if(rankingList[i]==address(0)) {
count++;
}
}
uint used;
for(uint j = 0;j<count;j++){
used+=RANKING_AWARD_PERCENT[j];
}
for(uint256 i = 0;i<amounts.length;i++){
uint waste = pair.amounts[i].mul(70).mul(pair.oracleAmount.sub(pair.actual)).div(ORE_AMOUNT).div(100);
uint rest = pair.amounts[i].mul(30).mul(uint256(25).sub(used)).div(30).div(100);
amounts[i] = waste+rest;
}
pool.allot(developer,amounts);
emit DeveloperFee(amounts[0],amounts[1]);
}
function cat(address userAddress) public view returns(uint256[] memory,uint256[] memory counts,uint256 len,uint256 token1155Amount,uint256 quantity){
( ,uint256 investment, ) = pool.users(userAddress);
(counts,token1155Amount) = determinate();
uint256 dailyTokenAmount = dailyOutput[pool.duration()];
if(dailyTokenAmount==0){
dailyTokenAmount = token1155Amount;
}
uint256 totalSupply = pool.totalSupply();
quantity = investment.mul(dailyTokenAmount).div(totalSupply);
return (carIndex,counts,kinds(),token1155Amount,quantity);
}
function determinate() public view returns(uint256[] memory counts,uint256 token1155Amount){
address _owner = owner();
counts = new uint256[](kinds());
for(uint8 i = 0;i<kinds();i++){
uint256 count = token1155.balanceOf(_owner,carIndex[i]);
counts[i] = count;
token1155Amount+=count;
}
for(uint8 i = 0;i<kinds();i++){
token1155Amount+=counts[i];
}
}
function kinds() internal view returns (uint256) {
return carIndex.length;
}
}
// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
function safeApprove(address token, address to, uint value) internal {
// bytes4(keccak256(bytes('approve(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x095ea7b3, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: APPROVE_FAILED');
}
function safeTransfer(address token, address to, uint value) internal {
// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0xa9059cbb, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FAILED');
}
function safeTransferFrom(address token, address from, address to, uint value) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(abi.encodeWithSelector(0x23b872dd, from, to, value));
require(success && (data.length == 0 || abi.decode(data, (bool))), 'TransferHelper: TRANSFER_FROM_FAILED');
}
function safeTransferETH(address to, uint value) internal {
(bool success,) = to.call{value:value}(new bytes(0));
require(success, 'TransferHelper: ETH_TRANSFER_FAILED');
}
}
// SPDX-License-Identifier: MIT
pragma solidity >=0.6.0 <0.8.0;
import "./SafeMath.sol";
contract Context {
constructor () { }
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this;
return msg.data;
}
}
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor () {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(isOwner(), "Ownable: caller is not the owner");
_;
}
function isOwner() public view returns (bool) {
return _msgSender() == _owner;
}
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
// SPDX-License-Identifier: MIT
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": {
"MiningCore.sol": "MiningCore"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"contract MiningPool","name":"_pool","type":"address"},{"internalType":"contract IERC1155","name":"_token1155","type":"address"},{"internalType":"address payable","name":"_developer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"fee1","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee2","type":"uint256"}],"name":"DeveloperFee","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"_version","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"LastStraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"_version","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Mining","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"_version","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ObtainCar","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":"sn","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fertility","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"carry","type":"uint256"}],"name":"SetCarIndex","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"}],"name":"UpdateRank","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"userAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"_version","type":"uint256"},{"indexed":false,"internalType":"uint256[2]","name":"amounts","type":"uint256[2]"}],"name":"WithdrawAward","type":"event"},{"inputs":[],"name":"LAST_STRAW_PERCNET","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ONE_DAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORE_AMOUNT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"OUT_RATE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"RANKING_AWARD_PERCENT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"carIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"cars","outputs":[{"internalType":"uint256","name":"sn","type":"uint256"},{"internalType":"uint256","name":"fertility","type":"uint256"},{"internalType":"uint256","name":"carry","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"cat","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"counts","type":"uint256[]"},{"internalType":"uint256","name":"len","type":"uint256"},{"internalType":"uint256","name":"token1155Amount","type":"uint256"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_version","type":"uint256"}],"name":"crown","outputs":[{"internalType":"address[10]","name":"ranking","type":"address[10]"},{"internalType":"uint256[10]","name":"digGross","type":"uint256[10]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"dailyOutput","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"determinate","outputs":[{"internalType":"uint256[]","name":"counts","type":"uint256[]"},{"internalType":"uint256","name":"token1155Amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_version","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"_carId","type":"uint256"}],"name":"getDepartCars","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_version","type":"uint256"}],"name":"getGlobalStats","outputs":[{"internalType":"uint256[5]","name":"stats","type":"uint256[5]"},{"internalType":"address","name":"lastStrawUser","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_version","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"}],"name":"getPersonalStats","outputs":[{"internalType":"uint256[8]","name":"stats","type":"uint256[8]"},{"internalType":"bool[3]","name":"stats2","type":"bool[3]"},{"internalType":"uint256[]","name":"departs","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"_version","type":"uint256"}],"name":"getRanking","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_version","type":"uint256"},{"internalType":"address","name":"userAddress","type":"address"}],"name":"getVersionAward","outputs":[{"internalType":"uint256[2]","name":"amounts","type":"uint256[2]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"history","outputs":[{"internalType":"uint256","name":"complete","type":"uint256"},{"internalType":"uint256","name":"actual","type":"uint256"},{"internalType":"uint256","name":"oracleAmount","type":"uint256"},{"internalType":"address","name":"lastStraw","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isOwner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"uint256","name":"expiry","type":"uint256"},{"internalType":"bool","name":"allowed","type":"bool"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"obtainCar","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256[]","name":"_ids","type":"uint256[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operator","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_id","type":"uint256"},{"internalType":"uint256","name":"_value","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"contract MiningPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"rank","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"records","outputs":[{"internalType":"bool","name":"drawStatus","type":"bool"},{"internalType":"uint256","name":"digGross","type":"uint256"},{"internalType":"bool","name":"lastStraw","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"sn","type":"uint256"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"fertility","type":"uint256"},{"internalType":"uint256","name":"carry","type":"uint256"}],"name":"setCarIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeOwner","type":"address"},{"internalType":"address","name":"factory","type":"address"}],"name":"setFeeOwner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ORE_AMOUNT","type":"uint256"}],"name":"setOracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_version","type":"uint256"}],"name":"sortRank","outputs":[{"internalType":"address[10]","name":"ranking","type":"address[10]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceID","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"token1155","outputs":[{"internalType":"contract IERC1155","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_version","type":"uint256"}],"name":"withdrawAward","outputs":[],"stateMutability":"nonpayable","type":"function"}]