├── README.md ├── .gitignore ├── contracts ├── Migrations.sol ├── utils │ ├── IERC165.sol │ ├── Item.sol │ ├── Address.sol │ ├── IERC721Receiver.sol │ ├── IERC721.sol │ ├── SafeMath.sol │ ├── IUniswapV2Router02.sol │ └── ERC721.sol ├── Goverance.sol ├── newPlanet │ ├── Shit.Sol │ ├── vrf_on_bsc_testnet.sol │ ├── IUniswapV2Router02.sol │ ├── ShitBox.sol │ └── Staking.sol ├── vrf_on_bsc_testnet.sol ├── shitbox.sol ├── ShitNFT.sol ├── shit.sol └── staking.sol ├── abi ├── stake.abi ├── shit.abi └── shitbox.abi └── verifyContract └── shit.sol /README.md: -------------------------------------------------------------------------------- 1 | # ShitPlanetContract -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | */.DS_Store 3 | -------------------------------------------------------------------------------- /contracts/Migrations.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | pragma solidity >=0.4.22 <0.8.0; 3 | 4 | contract Migrations { 5 | address public owner = msg.sender; 6 | uint public last_completed_migration; 7 | 8 | modifier restricted() { 9 | require( 10 | msg.sender == owner, 11 | "This function is restricted to the contract's owner" 12 | ); 13 | _; 14 | } 15 | 16 | function setCompleted(uint completed) public restricted { 17 | last_completed_migration = completed; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /contracts/utils/IERC165.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | /** 4 | * @title IERC165 5 | * @dev https://github.com/ethereum/EIPs/blob/master/EIPS/eip-165.md 6 | */ 7 | interface IERC165 { 8 | 9 | /** 10 | * @notice Query if a contract implements an interface 11 | * @param interfaceId The interface identifier, as specified in ERC-165 12 | * @dev Interface identification is specified in ERC-165. This function 13 | * uses less than 30,000 gas. 14 | */ 15 | function supportsInterface(bytes4 interfaceId) 16 | external 17 | view 18 | returns (bool); 19 | } 20 | -------------------------------------------------------------------------------- /contracts/utils/Item.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | contract Item is ERC721{ 4 | 5 | struct Item{ 6 | string name; // Name of the Item 7 | uint level; // Item Level 8 | uint rarityLevel; // 1 = normal, 2 = rare, 3 = epic, 4 = legendary 9 | } 10 | 11 | Item[] public items; // First Item has Index 0 12 | address public owner; 13 | 14 | function Item() public { 15 | owner = msg.sender; // The Sender is the Owner; Ethereum Address of the Owner 16 | } 17 | 18 | function createItem(string _name, address _to) public{ 19 | require(owner == msg.sender); // Only the Owner can create Items 20 | uint id = items.length; // Item ID = Length of the Array Items 21 | items.push(Item(_name,5,1)) // Item ("Sword",5,1) 22 | _mint(_to,id); // Assigns the Token to the Ethereum Address that is specified 23 | } 24 | 25 | } -------------------------------------------------------------------------------- /contracts/utils/Address.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | /** 4 | * Utility library of inline functions on addresses 5 | */ 6 | library Address { 7 | 8 | /** 9 | * Returns whether the target address is a contract 10 | * @dev This function will return false if invoked during the constructor of a contract, 11 | * as the code is not actually created until after the constructor finishes. 12 | * @param account address of the account to check 13 | * @return whether the target address is a contract 14 | */ 15 | function isContract(address account) internal view returns (bool) { 16 | uint256 size; 17 | // XXX Currently there is no better way to check if there is a contract in an address 18 | // than to check the size of the code at that address. 19 | // See https://ethereum.stackexchange.com/a/14016/36603 20 | // for more details about how this works. 21 | // TODO Check this again before the Serenity release, because all addresses will be 22 | // contracts then. 23 | // solium-disable-next-line security/no-inline-assembly 24 | assembly { size := extcodesize(account) } 25 | return size > 0; 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /contracts/utils/IERC721Receiver.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | /** 4 | * @title ERC721 token receiver interface 5 | * @dev Interface for any contract that wants to support safeTransfers 6 | * from ERC721 asset contracts. 7 | */ 8 | contract IERC721Receiver { 9 | /** 10 | * @notice Handle the receipt of an NFT 11 | * @dev The ERC721 smart contract calls this function on the recipient 12 | * after a `safeTransfer`. This function MUST return the function selector, 13 | * otherwise the caller will revert the transaction. The selector to be 14 | * returned can be obtained as `this.onERC721Received.selector`. This 15 | * function MAY throw to revert and reject the transfer. 16 | * Note: the ERC721 contract address is always the message sender. 17 | * @param operator The address which called `safeTransferFrom` function 18 | * @param from The address which previously owned the token 19 | * @param tokenId The NFT identifier which is being transferred 20 | * @param data Additional data with no specified format 21 | * @return `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` 22 | */ 23 | function onERC721Received( 24 | address operator, 25 | address from, 26 | uint256 tokenId, 27 | bytes data 28 | ) 29 | public 30 | returns(bytes4); 31 | } 32 | -------------------------------------------------------------------------------- /contracts/utils/IERC721.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | import "./IERC165.sol"; 4 | 5 | /** 6 | * @title ERC721 Non-Fungible Token Standard basic interface 7 | * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md 8 | */ 9 | contract IERC721 is IERC165 { 10 | 11 | event Transfer( 12 | address indexed from, 13 | address indexed to, 14 | uint256 indexed tokenId 15 | ); 16 | event Approval( 17 | address indexed owner, 18 | address indexed approved, 19 | uint256 indexed tokenId 20 | ); 21 | event ApprovalForAll( 22 | address indexed owner, 23 | address indexed operator, 24 | bool approved 25 | ); 26 | 27 | function balanceOf(address owner) public view returns (uint256 balance); 28 | function ownerOf(uint256 tokenId) public view returns (address owner); 29 | 30 | function approve(address to, uint256 tokenId) public; 31 | function getApproved(uint256 tokenId) 32 | public view returns (address operator); 33 | 34 | function setApprovalForAll(address operator, bool _approved) public; 35 | function isApprovedForAll(address owner, address operator) 36 | public view returns (bool); 37 | 38 | function transferFrom(address from, address to, uint256 tokenId) public; 39 | function safeTransferFrom(address from, address to, uint256 tokenId) 40 | public; 41 | 42 | function safeTransferFrom( 43 | address from, 44 | address to, 45 | uint256 tokenId, 46 | bytes data 47 | ) 48 | public; 49 | } -------------------------------------------------------------------------------- /contracts/Goverance.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.8.0; 4 | 5 | import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; 6 | import "@openzeppelin/contracts/utils/Address.sol"; 7 | 8 | contract ShitToken is ERC20{ 9 | 10 | using Address for address; 11 | 12 | address public governance; 13 | mapping (address => bool) public shitTokens; 14 | mapping (address => address) public bridges; 15 | 16 | address[] public shitTokenList; 17 | 18 | constructor(uint256 initialSupply) ERC20("ShitPlanet","SHIT"){ 19 | governance = tx.origin; 20 | _mint(msg.sender, initialSupply); 21 | } 22 | 23 | function addShitToken(address tokenAddress, address bridge) public { 24 | require(msg.sender == governance, "!governance"); 25 | shitTokens[tokenAddress] = true; 26 | bridges[tokenAddress] = bridge; 27 | shitTokenList.push(tokenAddress); 28 | } 29 | 30 | function getShitTokenList() public view returns(address[] memory) { 31 | return shitTokenList; 32 | } 33 | 34 | function getBridgeToken(address tokenAddress) public view returns(address) { 35 | return bridges[tokenAddress]; 36 | } 37 | 38 | function removeShitToken(address tokenAddress) public { 39 | require(msg.sender == governance, "!governance"); 40 | shitTokens[tokenAddress] = false; 41 | bridges[tokenAddress] = address(0); 42 | } 43 | 44 | function isShitToken(address tokenAddress) public view returns (bool) { 45 | return shitTokens[tokenAddress]; 46 | } 47 | 48 | function setGovernance(address _governance) public { 49 | require(msg.sender == governance, "!governance"); 50 | governance = _governance; 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /contracts/utils/SafeMath.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | /** 4 | * @title SafeMath 5 | * @dev Math operations with safety checks that revert on error 6 | */ 7 | library SafeMath { 8 | 9 | /** 10 | * @dev Multiplies two numbers, reverts on overflow. 11 | */ 12 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 13 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 14 | // benefit is lost if 'b' is also tested. 15 | // See: https://github.com/OpenZeppelin/openzeppelin-solidity/pull/522 16 | if (a == 0) { 17 | return 0; 18 | } 19 | 20 | uint256 c = a * b; 21 | require(c / a == b); 22 | 23 | return c; 24 | } 25 | 26 | /** 27 | * @dev Integer division of two numbers truncating the quotient, reverts on division by zero. 28 | */ 29 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 30 | require(b > 0); // Solidity only automatically asserts when dividing by 0 31 | uint256 c = a / b; 32 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 33 | 34 | return c; 35 | } 36 | 37 | /** 38 | * @dev Subtracts two numbers, reverts on overflow (i.e. if subtrahend is greater than minuend). 39 | */ 40 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 41 | require(b <= a); 42 | uint256 c = a - b; 43 | 44 | return c; 45 | } 46 | 47 | /** 48 | * @dev Adds two numbers, reverts on overflow. 49 | */ 50 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 51 | uint256 c = a + b; 52 | require(c >= a); 53 | 54 | return c; 55 | } 56 | 57 | /** 58 | * @dev Divides two numbers and returns the remainder (unsigned integer modulo), 59 | * reverts when dividing by zero. 60 | */ 61 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 62 | require(b != 0); 63 | return a % b; 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /contracts/newPlanet/Shit.Sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/ERC20.sol"; 6 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/utils/Address.sol"; 7 | 8 | contract Shit is ERC20{ 9 | 10 | using Address for address; 11 | 12 | address public governance; 13 | mapping (address => bool) public shitTokens; 14 | mapping (address => address) public bridges; 15 | 16 | address[] public shitTokenList; 17 | 18 | uint256[] public rangeValue = [1, 10, 100, 1000, 10000, 100000]; 19 | 20 | constructor() public ERC20("ShitPlanet","SHIT"){ 21 | governance = tx.origin; 22 | _mint(msg.sender, 100000000000000000000000000); 23 | } 24 | 25 | function addShitToken(address tokenAddress, address bridge) public { 26 | require(msg.sender == governance, "!governance"); 27 | shitTokens[tokenAddress] = true; 28 | bridges[tokenAddress] = bridge; 29 | shitTokenList.push(tokenAddress); 30 | } 31 | 32 | function getShitTokenList() public view returns(address[] memory) { 33 | return shitTokenList; 34 | } 35 | 36 | function getBridgeToken(address tokenAddress) public view returns(address) { 37 | return bridges[tokenAddress]; 38 | } 39 | 40 | function removeShitToken(address tokenAddress) public { 41 | require(msg.sender == governance, "!governance"); 42 | shitTokens[tokenAddress] = false; 43 | bridges[tokenAddress] = address(0); 44 | } 45 | 46 | function isShitToken(address tokenAddress) public view returns (bool) { 47 | return shitTokens[tokenAddress]; 48 | } 49 | 50 | function setGovernance(address _governance) public { 51 | require(msg.sender == governance, "!governance"); 52 | governance = _governance; 53 | } 54 | 55 | function getRange() public view returns (uint[] memory){ 56 | return rangeValue; 57 | } 58 | } -------------------------------------------------------------------------------- /contracts/vrf_on_bsc_testnet.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.0; 4 | 5 | import "@chainlink/contracts/src/v0.6/VRFConsumerBase.sol"; 6 | 7 | // need deposit some LINK token into this contract 8 | contract RandomNumberConsumer is VRFConsumerBase { 9 | bytes32 internal keyHash; 10 | uint256 internal fee; 11 | uint256 public randomResult; 12 | 13 | /** 14 | * Constructor inherits VRFConsumerBase 15 | * 16 | * Network: BSC Testnet 17 | * Chainlink VRF Coordinator address: 0xa555fC018435bef5A13C6c6870a9d4C11DEC329C 18 | * LINK token address: 0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06 19 | * Key Hash: 0xcaf3c3727e033261d383b315559476f48034c13b18f8cafed4d871abe5049186 20 | */ 21 | constructor() 22 | VRFConsumerBase( 23 | 0xa555fC018435bef5A13C6c6870a9d4C11DEC329C, // VRF Coordinator 24 | 0xa36085F69e2889c224210F603D836748e7dC0088 // LINK Token 25 | ) public 26 | { 27 | keyHash = 0xcaf3c3727e033261d383b315559476f48034c13b18f8cafed4d871abe5049186; 28 | fee = 0.1 * 10 ** 18; // 0.1 LINK on BSC testnet(Varies by network) 29 | } 30 | 31 | /** 32 | * Requests randomness from a user-provided seed 33 | */ 34 | function getRandomNumber(uint256 userProvidedSeed) public returns (bytes32 requestId) { 35 | require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet"); 36 | return requestRandomness(keyHash, fee, userProvidedSeed); // return type: uint256 37 | } 38 | 39 | /** 40 | * Callback function used by VRF Coordinator, not invoked by hand 41 | */ 42 | function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override { 43 | randomResult = randomness; 44 | } 45 | 46 | // get multiple random value 47 | function expand(uint256 randomValue, uint256 n) public pure returns (uint256[] memory expandedValues) { 48 | expandedValues = new uint256[](n); 49 | for (uint256 i = 0; i < n; i++) { 50 | expandedValues[i] = uint256(keccak256(abi.encode(randomValue, i))); 51 | } 52 | return expandedValues; 53 | } 54 | 55 | // TODO 56 | // function withdrawLink() external {} - Implement a withdraw function to avoid locking your LINK in the contract 57 | } 58 | -------------------------------------------------------------------------------- /contracts/newPlanet/vrf_on_bsc_testnet.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | import "@chainlink/contracts/src/v0.6/VRFConsumerBase.sol"; 6 | 7 | // need deposit some LINK token into this contract 8 | contract RandomNumberConsumer is VRFConsumerBase { 9 | bytes32 internal keyHash; 10 | uint256 internal fee; 11 | uint256 public randomResult; 12 | 13 | /** 14 | * Constructor inherits VRFConsumerBase 15 | * 16 | * Network: BSC Testnet 17 | * Chainlink VRF Coordinator address: 0xa555fC018435bef5A13C6c6870a9d4C11DEC329C 18 | * LINK token address: 0x84b9B910527Ad5C03A9Ca831909E21e236EA7b06 19 | * Key Hash: 0xcaf3c3727e033261d383b315559476f48034c13b18f8cafed4d871abe5049186 20 | */ 21 | constructor() 22 | VRFConsumerBase( 23 | 0xa555fC018435bef5A13C6c6870a9d4C11DEC329C, // VRF Coordinator 24 | 0xa36085F69e2889c224210F603D836748e7dC0088 // LINK Token 25 | ) public 26 | { 27 | keyHash = 0xcaf3c3727e033261d383b315559476f48034c13b18f8cafed4d871abe5049186; 28 | fee = 0.1 * 10 ** 18; // 0.1 LINK on BSC testnet(Varies by network) 29 | } 30 | 31 | /** 32 | * Requests randomness from a user-provided seed 33 | */ 34 | function getRandomNumber(uint256 userProvidedSeed) public returns (bytes32 requestId) { 35 | require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet"); 36 | return requestRandomness(keyHash, fee, userProvidedSeed); // return type: uint256 37 | } 38 | 39 | /** 40 | * Callback function used by VRF Coordinator, not invoked by hand 41 | */ 42 | function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override { 43 | randomResult = randomness; 44 | } 45 | 46 | // get multiple random value 47 | function expand(uint256 randomValue, uint256 n) public pure returns (uint256[] memory expandedValues) { 48 | expandedValues = new uint256[](n); 49 | for (uint256 i = 0; i < n; i++) { 50 | expandedValues[i] = uint256(keccak256(abi.encode(randomValue, i))); 51 | } 52 | return expandedValues; 53 | } 54 | 55 | // TODO 56 | // function withdrawLink() external {} - Implement a withdraw function to avoid locking your LINK in the contract 57 | } 58 | -------------------------------------------------------------------------------- /contracts/utils/IUniswapV2Router02.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.0; 2 | 3 | interface IUniswapV2Router01 { 4 | function factory() external pure returns (address); 5 | function WETH() external pure returns (address); 6 | 7 | function addLiquidity( 8 | address tokenA, 9 | address tokenB, 10 | uint amountADesired, 11 | uint amountBDesired, 12 | uint amountAMin, 13 | uint amountBMin, 14 | address to, 15 | uint deadline 16 | ) external returns (uint amountA, uint amountB, uint liquidity); 17 | function addLiquidityETH( 18 | address token, 19 | uint amountTokenDesired, 20 | uint amountTokenMin, 21 | uint amountETHMin, 22 | address to, 23 | uint deadline 24 | ) external payable returns (uint amountToken, uint amountETH, uint liquidity); 25 | function removeLiquidity( 26 | address tokenA, 27 | address tokenB, 28 | uint liquidity, 29 | uint amountAMin, 30 | uint amountBMin, 31 | address to, 32 | uint deadline 33 | ) external returns (uint amountA, uint amountB); 34 | function removeLiquidityETH( 35 | address token, 36 | uint liquidity, 37 | uint amountTokenMin, 38 | uint amountETHMin, 39 | address to, 40 | uint deadline 41 | ) external returns (uint amountToken, uint amountETH); 42 | function removeLiquidityWithPermit( 43 | address tokenA, 44 | address tokenB, 45 | uint liquidity, 46 | uint amountAMin, 47 | uint amountBMin, 48 | address to, 49 | uint deadline, 50 | bool approveMax, uint8 v, bytes32 r, bytes32 s 51 | ) external returns (uint amountA, uint amountB); 52 | function removeLiquidityETHWithPermit( 53 | address token, 54 | uint liquidity, 55 | uint amountTokenMin, 56 | uint amountETHMin, 57 | address to, 58 | uint deadline, 59 | bool approveMax, uint8 v, bytes32 r, bytes32 s 60 | ) external returns (uint amountToken, uint amountETH); 61 | function swapExactTokensForTokens( 62 | uint amountIn, 63 | uint amountOutMin, 64 | address[] calldata path, 65 | address to, 66 | uint deadline 67 | ) external returns (uint[] memory amounts); 68 | function swapTokensForExactTokens( 69 | uint amountOut, 70 | uint amountInMax, 71 | address[] calldata path, 72 | address to, 73 | uint deadline 74 | ) external returns (uint[] memory amounts); 75 | function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) 76 | external 77 | payable 78 | returns (uint[] memory amounts); 79 | function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) 80 | external 81 | returns (uint[] memory amounts); 82 | function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) 83 | external 84 | returns (uint[] memory amounts); 85 | function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) 86 | external 87 | payable 88 | returns (uint[] memory amounts); 89 | 90 | function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); 91 | function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external view returns (uint amountOut); 92 | function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external view returns (uint amountIn); 93 | function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); 94 | function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); 95 | } 96 | 97 | interface IUniswapV2Router02 is IUniswapV2Router01 { 98 | function removeLiquidityETHSupportingFeeOnTransferTokens( 99 | address token, 100 | uint liquidity, 101 | uint amountTokenMin, 102 | uint amountETHMin, 103 | address to, 104 | uint deadline 105 | ) external returns (uint amountETH); 106 | function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( 107 | address token, 108 | uint liquidity, 109 | uint amountTokenMin, 110 | uint amountETHMin, 111 | address to, 112 | uint deadline, 113 | bool approveMax, uint8 v, bytes32 r, bytes32 s 114 | ) external returns (uint amountETH); 115 | 116 | function swapExactTokensForTokensSupportingFeeOnTransferTokens( 117 | uint amountIn, 118 | uint amountOutMin, 119 | address[] calldata path, 120 | address to, 121 | uint deadline 122 | ) external; 123 | function swapExactETHForTokensSupportingFeeOnTransferTokens( 124 | uint amountOutMin, 125 | address[] calldata path, 126 | address to, 127 | uint deadline 128 | ) external payable; 129 | function swapExactTokensForETHSupportingFeeOnTransferTokens( 130 | uint amountIn, 131 | uint amountOutMin, 132 | address[] calldata path, 133 | address to, 134 | uint deadline 135 | ) external; 136 | } -------------------------------------------------------------------------------- /contracts/newPlanet/IUniswapV2Router02.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.0; 2 | 3 | interface IUniswapV2Router01 { 4 | function factory() external pure returns (address); 5 | function WETH() external pure returns (address); 6 | 7 | function addLiquidity( 8 | address tokenA, 9 | address tokenB, 10 | uint amountADesired, 11 | uint amountBDesired, 12 | uint amountAMin, 13 | uint amountBMin, 14 | address to, 15 | uint deadline 16 | ) external returns (uint amountA, uint amountB, uint liquidity); 17 | function addLiquidityETH( 18 | address token, 19 | uint amountTokenDesired, 20 | uint amountTokenMin, 21 | uint amountETHMin, 22 | address to, 23 | uint deadline 24 | ) external payable returns (uint amountToken, uint amountETH, uint liquidity); 25 | function removeLiquidity( 26 | address tokenA, 27 | address tokenB, 28 | uint liquidity, 29 | uint amountAMin, 30 | uint amountBMin, 31 | address to, 32 | uint deadline 33 | ) external returns (uint amountA, uint amountB); 34 | function removeLiquidityETH( 35 | address token, 36 | uint liquidity, 37 | uint amountTokenMin, 38 | uint amountETHMin, 39 | address to, 40 | uint deadline 41 | ) external returns (uint amountToken, uint amountETH); 42 | function removeLiquidityWithPermit( 43 | address tokenA, 44 | address tokenB, 45 | uint liquidity, 46 | uint amountAMin, 47 | uint amountBMin, 48 | address to, 49 | uint deadline, 50 | bool approveMax, uint8 v, bytes32 r, bytes32 s 51 | ) external returns (uint amountA, uint amountB); 52 | function removeLiquidityETHWithPermit( 53 | address token, 54 | uint liquidity, 55 | uint amountTokenMin, 56 | uint amountETHMin, 57 | address to, 58 | uint deadline, 59 | bool approveMax, uint8 v, bytes32 r, bytes32 s 60 | ) external returns (uint amountToken, uint amountETH); 61 | function swapExactTokensForTokens( 62 | uint amountIn, 63 | uint amountOutMin, 64 | address[] calldata path, 65 | address to, 66 | uint deadline 67 | ) external returns (uint[] memory amounts); 68 | function swapTokensForExactTokens( 69 | uint amountOut, 70 | uint amountInMax, 71 | address[] calldata path, 72 | address to, 73 | uint deadline 74 | ) external returns (uint[] memory amounts); 75 | function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) 76 | external 77 | payable 78 | returns (uint[] memory amounts); 79 | function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) 80 | external 81 | returns (uint[] memory amounts); 82 | function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) 83 | external 84 | returns (uint[] memory amounts); 85 | function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) 86 | external 87 | payable 88 | returns (uint[] memory amounts); 89 | 90 | function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); 91 | function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external view returns (uint amountOut); 92 | function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external view returns (uint amountIn); 93 | function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); 94 | function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); 95 | } 96 | 97 | interface IUniswapV2Router02 is IUniswapV2Router01 { 98 | function removeLiquidityETHSupportingFeeOnTransferTokens( 99 | address token, 100 | uint liquidity, 101 | uint amountTokenMin, 102 | uint amountETHMin, 103 | address to, 104 | uint deadline 105 | ) external returns (uint amountETH); 106 | function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( 107 | address token, 108 | uint liquidity, 109 | uint amountTokenMin, 110 | uint amountETHMin, 111 | address to, 112 | uint deadline, 113 | bool approveMax, uint8 v, bytes32 r, bytes32 s 114 | ) external returns (uint amountETH); 115 | 116 | function swapExactTokensForTokensSupportingFeeOnTransferTokens( 117 | uint amountIn, 118 | uint amountOutMin, 119 | address[] calldata path, 120 | address to, 121 | uint deadline 122 | ) external; 123 | function swapExactETHForTokensSupportingFeeOnTransferTokens( 124 | uint amountOutMin, 125 | address[] calldata path, 126 | address to, 127 | uint deadline 128 | ) external payable; 129 | function swapExactTokensForETHSupportingFeeOnTransferTokens( 130 | uint amountIn, 131 | uint amountOutMin, 132 | address[] calldata path, 133 | address to, 134 | uint deadline 135 | ) external; 136 | } -------------------------------------------------------------------------------- /contracts/shitbox.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.0; 2 | 3 | import './utils/ERC721.sol'; 4 | import './utils/SafeMath.sol'; 5 | import './utils/IUniswapV2Router02.sol'; 6 | import './shit.sol'; 7 | 8 | interface IERC20 { 9 | function totalSupply() external view returns (uint); 10 | function balanceOf(address account) external view returns (uint); 11 | function transfer(address recipient, uint amount) external returns (bool); 12 | function allowance(address owner, address spender) external view returns (uint); 13 | function approve(address spender, uint amount) external returns (bool); 14 | function transferFrom(address sender, address recipient, uint amount) external returns (bool); 15 | event Transfer(address indexed from, address indexed to, uint value); 16 | event Approval(address indexed owner, address indexed spender, uint value); 17 | } 18 | 19 | contract ShitBox is ERC721 { 20 | using SafeMath for uint256; 21 | 22 | address usdtAddress = 0x0; 23 | address shitAddress = 0x0; 24 | address pancakeFactoryAddr = 0x0; 25 | address pancakeRouterAddr = 0x0; 26 | uint256 upgradePrice = 10000000000000000000; // 10 $SHIT 27 | 28 | Shit shit = Shit(shitAddress); 29 | IERC20 usdt = IERC20(usdtAddress); 30 | IUniswapV2Router02 router = IUniswapV2Router02(pancakeRouterAddr); 31 | 32 | struct Box { 33 | uint256 id; 34 | address shiter; 35 | address tokenAddress; 36 | uint256 amount; 37 | 38 | uint256 miningPower; 39 | } 40 | mapping(uint256 => Box) boxes; 41 | 42 | constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) public { 43 | shit.approve(pancakeRouterAddr, uint(-1)); 44 | usdt.approve(pancakeRouterAddr, uint(-1)); 45 | } 46 | 47 | function getMiningPower(uint256 boxId) public view returns (uint256) { 48 | return boxes[boxId].miningPower; 49 | } 50 | 51 | function mintShitBox(address tokenAddress, uint256 amount) public { 52 | require(shit.isShitToken(tokenAddress)); 53 | 54 | ERC20 token = ERC20(tokenAddress); 55 | require(token.transferFrom(msg.sender, address(this), amount), "Insufficient funds"); 56 | 57 | // burn 50%, swap 25% to $SHIT, 25% to USDT, add liquidity for $SHIT 58 | uint256 miningPower = _magic(tokenAddress, amount); 59 | 60 | uint256 boxId = _getNextBoxId(); 61 | boxes[boxId] = Box(boxId, msg.sender, tokenAddress, amount, miningPower); 62 | _mint(msg.sender, boxId); 63 | } 64 | 65 | function upgradeShitBox(uint256 boxId) public { 66 | require(shit.transferFrom(msg.sender, address(0xdead), upgradePrice), "insufficient shit"); 67 | require(boxes[boxId].shiter != 0x0); 68 | 69 | uint256 rand = _getRandom(); 70 | uint256 currentMiningPower = boxes[boxId].miningPower; 71 | boxes[boxId].miningPower = currentMiningPower.add(rand); 72 | } 73 | 74 | // TODO: replace this with chainlink VRF 75 | function _getRandom() private view returns (uint256) { 76 | return 0; 77 | } 78 | 79 | function _magic(address tokenAddress, uint256 amount) private returns (uint256) { 80 | // transfer 50% to 0xdead 81 | uint256 burnAmount = amount.mul(50).div(100); 82 | require(token.transfer(address(0xdead), burnAmount), "Insufficient funds"); 83 | // swap 50% to USDT 84 | address bridgeToken = shit.getBridgeToken(tokenAddress); 85 | address[] memory path; 86 | path.push(tokenAddress); 87 | if(bridgeToken != usdtAddress) { 88 | path.push(bridgeToken); 89 | } 90 | path.push(usdtAddress); 91 | IERC20 token = IERC20(tokenAddress); 92 | token.approve(pancakeRouterAddr, uint(-1)); 93 | router.swapExactTokensForTokensSupportingFeeOnTransferTokens(amount.sub(burnAmount), 0, path, address(this), block.timestamp + 500); 94 | uint256 usdtValue = usdt.balanceOf(address(this)); 95 | // swap 25% to $SHIT 96 | address[] memory path1; 97 | path1.push(usdtAddress); 98 | path1.push(shitAddress); 99 | router.swapExactTokensForTokensSupportingFeeOnTransferTokens(usdtValue.mul(50).div(100), 0, path1, address(this), block.timestamp + 500); 100 | uint256 usdtBalance = usdt.balanceOf(address(this)); 101 | uint256 shitBalance = shit.balanceOf(address(this)); 102 | // add liquidity for SHIT/USDT 103 | router.addLiquidity(tokenAddress, usdtAddress, usdtBalance, shitBalance, 0, 0, address(0xdead), block.timestamp + 500); 104 | 105 | return usdtValue; 106 | } 107 | 108 | function skim(address tokenAddress) public { 109 | IERC20 token = IERC20(tokenAddress); 110 | token.transfer(msg.sender, token.balanceOf(address(this))); 111 | } 112 | 113 | function _getNextBoxId() private view returns (uint256) { 114 | return totalSupply().add(1).add(burnedCounter); 115 | } 116 | 117 | function _burn(address _owner, uint256 _tokenId) internal { 118 | super._burn(_owner, _tokenId); 119 | burnedCounter++; 120 | } 121 | 122 | function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { 123 | uint256 tokenCount = balanceOf(_owner); 124 | 125 | if (tokenCount == 0) { 126 | return new uint256[](0); 127 | } else { 128 | uint256[] memory result = new uint256[](tokenCount); 129 | uint256 resultIndex = 0; 130 | uint256 _tokenIdx; 131 | for (_tokenIdx = 0; _tokenIdx < tokenCount; _tokenIdx++) { 132 | result[resultIndex] = tokenOfOwnerByIndex(_owner, _tokenIdx); 133 | resultIndex++; 134 | } 135 | return result; 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /contracts/ShitNFT.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.0; 4 | 5 | import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; 6 | import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; 7 | import "./Goverance.sol"; 8 | import "./utils/IUniswapV2Router02.sol"; 9 | import "@openzeppelin/contracts/utils/math/SafeMath.sol"; 10 | import "./vrf_on_bsc_testnet.sol"; 11 | 12 | contract ShitNFT is ERC721{ 13 | 14 | using SafeMath for uint256; 15 | 16 | address usdtAddress = address(0x0); 17 | address shitAddress = address(0x0); 18 | address pancakeFactoryAddr = address(0x0); 19 | address pancakeRouterAddr = address(0x0); 20 | uint256 upgradePrice = 10000000000000000000; // 10 $SHIT 21 | uint256 burnedCounter = 0; 22 | mapping(address => uint256[]) tokens; 23 | 24 | ShitToken shit = ShitToken(shitAddress); 25 | IERC20 usdt = IERC20(usdtAddress); 26 | IUniswapV2Router02 router = IUniswapV2Router02(pancakeRouterAddr); 27 | 28 | struct Box { 29 | uint256 id; 30 | address shiter; 31 | address tokenAddress; 32 | uint256 amount; 33 | 34 | uint256 miningPower; 35 | } 36 | mapping(uint256 => Box) boxes; 37 | 38 | constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) { 39 | // TODO uint(-1) 40 | shit.approve(pancakeRouterAddr, uint(-1)); 41 | usdt.approve(pancakeRouterAddr, uint(-1)); 42 | } 43 | 44 | function getMiningPower(uint256 boxId) public view returns (uint256) { 45 | return boxes[boxId].miningPower; 46 | } 47 | 48 | function mintShitBox(address tokenAddress, uint256 amount) public { 49 | require(shit.isShitToken(tokenAddress)); 50 | 51 | ERC20 token = ERC20(tokenAddress); 52 | require(token.transferFrom(msg.sender, address(this), amount), "Insufficient funds"); 53 | 54 | // burn 50%, swap 25% to $SHIT, 25% to USDT, add liquidity for $SHIT 55 | uint256 miningPower = _magic(tokenAddress, amount); 56 | 57 | uint256 boxId = _getNextBoxId(); 58 | boxes[boxId] = Box(boxId, msg.sender, tokenAddress, amount, miningPower); 59 | _mint(msg.sender, boxId); 60 | tokens[msg.sender].push(boxId); 61 | } 62 | 63 | function upgradeShitBox(uint256 boxId) public { 64 | require(shit.transferFrom(msg.sender, address(0xdead), upgradePrice), "insufficient shit"); 65 | require(boxes[boxId].shiter != address(0x0)); 66 | 67 | uint256 rand = _getRandom(); 68 | uint256 currentMiningPower = boxes[boxId].miningPower; 69 | boxes[boxId].miningPower = currentMiningPower.add(rand); 70 | } 71 | 72 | // TODO: replace this with chainlink VRF 73 | function _getRandom(uint256 userProvidedSeed, address vrfContractAddress) private view returns (uint256) { 74 | RandomNumberConsumer randomNumberConsumer = RandomNumberConsumer(vrfContractAddress); 75 | uint256 randomResult = randomNumberConsumer.getRandomNumber(userProvidedSeed); 76 | return randomResult; 77 | } 78 | 79 | function _magic(address tokenAddress, uint256 amount) private returns (uint256) { 80 | // transfer 50% to 0xdead 81 | IERC20 token = IERC20(tokenAddress); 82 | uint256 burnAmount = amount.mul(50).div(100); 83 | require(token.transfer(address(0xdead), burnAmount), "Insufficient funds"); 84 | // swap 50% to USDT 85 | address bridgeToken = shit.getBridgeToken(tokenAddress); 86 | address[] memory path = new address[](2); 87 | path[0] = tokenAddress; 88 | if(bridgeToken != usdtAddress) { 89 | path[1] = bridgeToken; 90 | }else{ 91 | path[1] = usdtAddress; 92 | } 93 | // TODO uint(-1) 94 | token.approve(pancakeRouterAddr, uint(1)); 95 | router.swapExactTokensForTokensSupportingFeeOnTransferTokens(amount.sub(burnAmount), 0, path, address(this), block.timestamp + 500); 96 | uint256 usdtValue = usdt.balanceOf(address(this)); 97 | // swap 25% to $SHIT 98 | address[] memory path1 = new address[](2); 99 | path1[0] = usdtAddress; 100 | path1[1] = shitAddress; 101 | router.swapExactTokensForTokensSupportingFeeOnTransferTokens(usdtValue.mul(50).div(100), 0, path1, address(this), block.timestamp + 500); 102 | uint256 usdtBalance = usdt.balanceOf(address(this)); 103 | uint256 shitBalance = shit.balanceOf(address(this)); 104 | // add liquidity for SHIT/USDT 105 | router.addLiquidity(tokenAddress, usdtAddress, usdtBalance, shitBalance, 0, 0, address(0xdead), block.timestamp + 500); 106 | 107 | return usdtValue; 108 | } 109 | 110 | function skim(address tokenAddress) public { 111 | IERC20 token = IERC20(tokenAddress); 112 | token.transfer(msg.sender, token.balanceOf(address(this))); 113 | } 114 | 115 | function _getNextBoxId() private view returns (uint256) { 116 | return shit.totalSupply().add(1).add(burnedCounter); 117 | } 118 | 119 | function _burn(address _owner, uint256 _tokenId) internal { 120 | super._burn(_tokenId); 121 | burnedCounter++; 122 | } 123 | 124 | function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { 125 | // uint256 tokenCount = balanceOf(_owner); 126 | return tokens[_owner]; 127 | // if (tokenCount == 0) { 128 | // return new uint256[](0); 129 | // } else { 130 | // uint256[] memory result = new uint256[](tokenCount); 131 | // uint256 resultIndex = 0; 132 | // uint256 _tokenIdx; 133 | // for (_tokenIdx = 0; _tokenIdx < tokenCount; _tokenIdx++) { 134 | // result[resultIndex] = tokenOfOwnerByIndex(_owner, _tokenIdx); 135 | // resultIndex++; 136 | // } 137 | // return result; 138 | // } 139 | } 140 | 141 | } -------------------------------------------------------------------------------- /abi/stake.abi: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "stateMutability": "nonpayable", 5 | "type": "constructor" 6 | }, 7 | { 8 | "inputs": [ 9 | { 10 | "internalType": "uint256", 11 | "name": "", 12 | "type": "uint256" 13 | } 14 | ], 15 | "name": "_ownerOf", 16 | "outputs": [ 17 | { 18 | "internalType": "address", 19 | "name": "", 20 | "type": "address" 21 | } 22 | ], 23 | "stateMutability": "view", 24 | "type": "function" 25 | }, 26 | { 27 | "inputs": [ 28 | { 29 | "internalType": "address", 30 | "name": "account", 31 | "type": "address" 32 | } 33 | ], 34 | "name": "balanceOf", 35 | "outputs": [ 36 | { 37 | "internalType": "uint256", 38 | "name": "", 39 | "type": "uint256" 40 | } 41 | ], 42 | "stateMutability": "view", 43 | "type": "function" 44 | }, 45 | { 46 | "inputs": [ 47 | { 48 | "internalType": "address", 49 | "name": "account", 50 | "type": "address" 51 | } 52 | ], 53 | "name": "earned", 54 | "outputs": [ 55 | { 56 | "internalType": "uint256", 57 | "name": "", 58 | "type": "uint256" 59 | } 60 | ], 61 | "stateMutability": "view", 62 | "type": "function" 63 | }, 64 | { 65 | "inputs": [], 66 | "name": "exit", 67 | "outputs": [], 68 | "stateMutability": "nonpayable", 69 | "type": "function" 70 | }, 71 | { 72 | "inputs": [], 73 | "name": "getReward", 74 | "outputs": [], 75 | "stateMutability": "nonpayable", 76 | "type": "function" 77 | }, 78 | { 79 | "inputs": [], 80 | "name": "getRewardForDuration", 81 | "outputs": [ 82 | { 83 | "internalType": "uint256", 84 | "name": "", 85 | "type": "uint256" 86 | } 87 | ], 88 | "stateMutability": "view", 89 | "type": "function" 90 | }, 91 | { 92 | "inputs": [], 93 | "name": "lastTimeRewardApplicable", 94 | "outputs": [ 95 | { 96 | "internalType": "uint256", 97 | "name": "", 98 | "type": "uint256" 99 | } 100 | ], 101 | "stateMutability": "view", 102 | "type": "function" 103 | }, 104 | { 105 | "inputs": [], 106 | "name": "lastUpdateTime", 107 | "outputs": [ 108 | { 109 | "internalType": "uint256", 110 | "name": "", 111 | "type": "uint256" 112 | } 113 | ], 114 | "stateMutability": "view", 115 | "type": "function" 116 | }, 117 | { 118 | "inputs": [ 119 | { 120 | "internalType": "uint256", 121 | "name": "reward", 122 | "type": "uint256" 123 | } 124 | ], 125 | "name": "notifyRewardAmount", 126 | "outputs": [], 127 | "stateMutability": "nonpayable", 128 | "type": "function" 129 | }, 130 | { 131 | "inputs": [ 132 | { 133 | "internalType": "uint256", 134 | "name": "boxId", 135 | "type": "uint256" 136 | } 137 | ], 138 | "name": "ownerOf", 139 | "outputs": [ 140 | { 141 | "internalType": "address", 142 | "name": "", 143 | "type": "address" 144 | } 145 | ], 146 | "stateMutability": "view", 147 | "type": "function" 148 | }, 149 | { 150 | "inputs": [], 151 | "name": "periodFinish", 152 | "outputs": [ 153 | { 154 | "internalType": "uint256", 155 | "name": "", 156 | "type": "uint256" 157 | } 158 | ], 159 | "stateMutability": "view", 160 | "type": "function" 161 | }, 162 | { 163 | "inputs": [ 164 | { 165 | "internalType": "address", 166 | "name": "tokenAddress", 167 | "type": "address" 168 | }, 169 | { 170 | "internalType": "uint256", 171 | "name": "tokenAmount", 172 | "type": "uint256" 173 | } 174 | ], 175 | "name": "recoverERC20", 176 | "outputs": [], 177 | "stateMutability": "nonpayable", 178 | "type": "function" 179 | }, 180 | { 181 | "inputs": [], 182 | "name": "rewardPerToken", 183 | "outputs": [ 184 | { 185 | "internalType": "uint256", 186 | "name": "", 187 | "type": "uint256" 188 | } 189 | ], 190 | "stateMutability": "view", 191 | "type": "function" 192 | }, 193 | { 194 | "inputs": [], 195 | "name": "rewardPerTokenStored", 196 | "outputs": [ 197 | { 198 | "internalType": "uint256", 199 | "name": "", 200 | "type": "uint256" 201 | } 202 | ], 203 | "stateMutability": "view", 204 | "type": "function" 205 | }, 206 | { 207 | "inputs": [], 208 | "name": "rewardRate", 209 | "outputs": [ 210 | { 211 | "internalType": "uint256", 212 | "name": "", 213 | "type": "uint256" 214 | } 215 | ], 216 | "stateMutability": "view", 217 | "type": "function" 218 | }, 219 | { 220 | "inputs": [ 221 | { 222 | "internalType": "address", 223 | "name": "", 224 | "type": "address" 225 | } 226 | ], 227 | "name": "rewards", 228 | "outputs": [ 229 | { 230 | "internalType": "uint256", 231 | "name": "", 232 | "type": "uint256" 233 | } 234 | ], 235 | "stateMutability": "view", 236 | "type": "function" 237 | }, 238 | { 239 | "inputs": [], 240 | "name": "rewardsDuration", 241 | "outputs": [ 242 | { 243 | "internalType": "uint256", 244 | "name": "", 245 | "type": "uint256" 246 | } 247 | ], 248 | "stateMutability": "view", 249 | "type": "function" 250 | }, 251 | { 252 | "inputs": [], 253 | "name": "rewardsToken", 254 | "outputs": [ 255 | { 256 | "internalType": "contract IERC20", 257 | "name": "", 258 | "type": "address" 259 | } 260 | ], 261 | "stateMutability": "view", 262 | "type": "function" 263 | }, 264 | { 265 | "inputs": [ 266 | { 267 | "internalType": "uint256", 268 | "name": "_rewardsDuration", 269 | "type": "uint256" 270 | } 271 | ], 272 | "name": "setRewardsDuration", 273 | "outputs": [], 274 | "stateMutability": "nonpayable", 275 | "type": "function" 276 | }, 277 | { 278 | "inputs": [], 279 | "name": "shitboxAddress", 280 | "outputs": [ 281 | { 282 | "internalType": "address", 283 | "name": "", 284 | "type": "address" 285 | } 286 | ], 287 | "stateMutability": "view", 288 | "type": "function" 289 | }, 290 | { 291 | "inputs": [ 292 | { 293 | "internalType": "uint256", 294 | "name": "boxId", 295 | "type": "uint256" 296 | } 297 | ], 298 | "name": "stake", 299 | "outputs": [], 300 | "stateMutability": "nonpayable", 301 | "type": "function" 302 | }, 303 | { 304 | "inputs": [ 305 | { 306 | "internalType": "address", 307 | "name": "owner", 308 | "type": "address" 309 | } 310 | ], 311 | "name": "tokensOfOwner", 312 | "outputs": [ 313 | { 314 | "internalType": "uint256[]", 315 | "name": "ownerTokens", 316 | "type": "uint256[]" 317 | } 318 | ], 319 | "stateMutability": "view", 320 | "type": "function" 321 | }, 322 | { 323 | "inputs": [], 324 | "name": "totalSupply", 325 | "outputs": [ 326 | { 327 | "internalType": "uint256", 328 | "name": "", 329 | "type": "uint256" 330 | } 331 | ], 332 | "stateMutability": "view", 333 | "type": "function" 334 | }, 335 | { 336 | "inputs": [ 337 | { 338 | "internalType": "uint256", 339 | "name": "timestamp", 340 | "type": "uint256" 341 | } 342 | ], 343 | "name": "updatePeriodFinish", 344 | "outputs": [], 345 | "stateMutability": "nonpayable", 346 | "type": "function" 347 | }, 348 | { 349 | "inputs": [ 350 | { 351 | "internalType": "address", 352 | "name": "", 353 | "type": "address" 354 | } 355 | ], 356 | "name": "userRewardPerTokenPaid", 357 | "outputs": [ 358 | { 359 | "internalType": "uint256", 360 | "name": "", 361 | "type": "uint256" 362 | } 363 | ], 364 | "stateMutability": "view", 365 | "type": "function" 366 | }, 367 | { 368 | "inputs": [ 369 | { 370 | "internalType": "uint256", 371 | "name": "boxId", 372 | "type": "uint256" 373 | } 374 | ], 375 | "name": "withdraw", 376 | "outputs": [], 377 | "stateMutability": "nonpayable", 378 | "type": "function" 379 | } 380 | ] -------------------------------------------------------------------------------- /contracts/newPlanet/ShitBox.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | pragma experimental ABIEncoderV2; 5 | 6 | import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC721/ERC721.sol'; 7 | import 'https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/math/SafeMath.sol'; 8 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/ERC20.sol"; 9 | import './IUniswapV2Router02.sol'; 10 | import './Shit.sol'; 11 | import "./vrf_on_bsc_testnet.sol"; 12 | 13 | contract ShitBox is ERC721 { 14 | using SafeMath for uint256; 15 | 16 | address public usdtAddress = 0x55d398326f99059fF775485246999027B3197955; 17 | address public shitAddress = 0xa63190F5da411fFE60c0a70E9EAc95cCD5e626be; 18 | address public pancakeRouterAddr = 0x10ED43C718714eb63d5aA57B78B54704E256024E; 19 | address public vrfAddr = address(0x0); 20 | uint256 public upgradePrice = 100000000000000000000; // 100 $SHIT 21 | uint256 public burnedCounter = 0; 22 | 23 | Shit shit = Shit(shitAddress); 24 | ERC20 usdt = ERC20(usdtAddress); 25 | IUniswapV2Router02 router = IUniswapV2Router02(pancakeRouterAddr); 26 | 27 | struct Box { 28 | uint256 id; 29 | address shiter; 30 | address tokenAddress; 31 | uint256 amount; 32 | uint256 initUSDValue; 33 | uint256 quality; 34 | 35 | uint256 bonusPower; 36 | uint256 miningPower; 37 | uint256 timestamp; 38 | } 39 | mapping(uint256 => Box) public boxes; 40 | 41 | constructor(string memory _name, string memory _symbol) ERC721(_name, _symbol) public { 42 | shit.approve(pancakeRouterAddr, uint(-1)); 43 | usdt.approve(pancakeRouterAddr, uint(-1)); 44 | } 45 | 46 | function getMiningPower(uint256 boxId) public view returns (uint256) { 47 | return boxes[boxId].miningPower; 48 | } 49 | 50 | function getBoxInfo(uint256 boxId) public view returns(Box memory) { 51 | return boxes[boxId]; 52 | } 53 | 54 | function getBoxToken(uint256 boxId) public view returns(address) { 55 | return boxes[boxId].tokenAddress; 56 | } 57 | 58 | function getBoxTokenAmount(uint256 boxId) public view returns(uint256) { 59 | return boxes[boxId].amount; 60 | } 61 | function getBoxTokenUSDValue(uint256 boxId) public view returns(uint256) { 62 | return boxes[boxId].initUSDValue; 63 | } 64 | function getBoxQuality(uint256 boxId) public view returns(uint256) { 65 | return boxes[boxId].quality; 66 | } 67 | function getBoxBonusPower(uint256 boxId) public view returns(uint256) { 68 | return boxes[boxId].bonusPower; 69 | } 70 | function getBoxTimestamp(uint256 boxId) public view returns(uint256) { 71 | return boxes[boxId].timestamp; 72 | } 73 | 74 | function mintShitBox(address tokenAddress, uint256 amount) public { 75 | require(shit.isShitToken(tokenAddress)); 76 | 77 | ERC20 token = ERC20(tokenAddress); 78 | require(token.transferFrom(msg.sender, address(this), amount), "Insufficient funds"); 79 | 80 | // burn 50%, swap 25% to $SHIT, 25% to USDT, add liquidity for $SHIT 81 | uint256 miningPower = _magic(tokenAddress, amount); 82 | // VRF 83 | uint256 rand = _getRand(); 84 | rand = rand.mod(100); 85 | uint256 quality = 0; 86 | 87 | if (rand > 95) quality = 5; 88 | else if (rand > 85) quality = 4; 89 | else if (rand > 65) quality = 3; 90 | else if (rand > 35) quality = 2; 91 | else quality = 1; 92 | 93 | uint256 boxId = _getNextBoxId(); 94 | boxes[boxId] = Box(boxId, msg.sender, tokenAddress, amount, miningPower, quality, 0, miningPower.mul(quality), block.timestamp); 95 | _mint(msg.sender, boxId); 96 | } 97 | 98 | function upgradeShitBox(uint256 boxId) public { 99 | require(msg.sender == tx.origin); // ban contract call 100 | require(shit.transferFrom(msg.sender, address(0xdead), upgradePrice), "insufficient shit"); 101 | require(boxes[boxId].shiter != address(0x0)); 102 | 103 | // Link VRF Supported next version 104 | 105 | uint256 rand = uint256(blockhash(block.number-1)).mod(1000); 106 | 107 | uint256 bonus = 0; 108 | 109 | if (rand > 998) bonus = 100000; 110 | else if (rand > 979) bonus = 10000; 111 | else if (rand > 800) bonus = 1000; 112 | else bonus = 100; 113 | 114 | uint256 currentMiningPower = boxes[boxId].miningPower; 115 | uint256 currentBonusPower = boxes[boxId].bonusPower; 116 | boxes[boxId].miningPower = currentMiningPower.add(bonus.mul(10**18)); 117 | boxes[boxId].bonusPower = currentBonusPower.add(bonus.mul(10**18)); 118 | } 119 | 120 | function _getRand() private returns (uint) { 121 | // return _getRandom(block.timestamp, vrfAddr); 122 | return uint(blockhash(block.number - 1)); 123 | } 124 | 125 | // TODO: replace this with chainlink VRF 126 | function _getRandom(uint256 userProvidedSeed, address vrfContractAddress) private returns (uint256) { 127 | RandomNumberConsumer randomNumberConsumer = RandomNumberConsumer(vrfContractAddress); 128 | uint256 randomResult = uint256(randomNumberConsumer.getRandomNumber(userProvidedSeed)); 129 | return randomResult; 130 | } 131 | 132 | function _magic(address tokenAddress, uint256 amount) private returns (uint256) { 133 | // transfer 50% to 0xdead 134 | ERC20 token = ERC20(tokenAddress); 135 | uint256 burnAmount = amount.mul(50).div(100); 136 | require(token.transfer(address(0xdead), burnAmount), "Insufficient funds"); 137 | // swap 50% to USDT 138 | address bridgeToken = shit.getBridgeToken(tokenAddress); 139 | address[] memory path00 = new address[](2); 140 | address[] memory path01 = new address[](3); 141 | path00[0] = tokenAddress; 142 | path00[1] = usdtAddress; 143 | 144 | path01[0] = tokenAddress; 145 | path01[1] = bridgeToken; 146 | path01[2] = usdtAddress; 147 | 148 | token.approve(pancakeRouterAddr, uint(-1)); 149 | if(bridgeToken == usdtAddress) { 150 | router.swapExactTokensForTokens(amount.sub(burnAmount), 0, path00, address(this), block.timestamp + 500); 151 | } else { 152 | router.swapExactTokensForTokens(amount.sub(burnAmount), 0, path01, address(this), block.timestamp + 500); 153 | } 154 | uint256 usdtValue = usdt.balanceOf(address(this)); 155 | // swap 25% to $SHIT 156 | address[] memory path1 = new address[](2); 157 | path1[0] = usdtAddress; 158 | path1[1] = shitAddress; 159 | router.swapExactTokensForTokens(usdtValue.mul(50).div(100), 0, path1, address(this), block.timestamp + 500); 160 | uint256 usdtBalance = usdt.balanceOf(address(this)); 161 | uint256 shitBalance = shit.balanceOf(address(this)); 162 | // add liquidity for SHIT/USDT 163 | router.addLiquidity(usdtAddress, shitAddress, usdtBalance, shitBalance, 0, 0, address(0xdead), block.timestamp + 500); 164 | 165 | return usdtValue; 166 | } 167 | 168 | function skim(address tokenAddress) public { 169 | ERC20 token = ERC20(tokenAddress); 170 | token.transfer(msg.sender, token.balanceOf(address(this))); 171 | } 172 | 173 | function _getNextBoxId() private view returns (uint256) { 174 | return totalSupply().add(1).add(burnedCounter); 175 | } 176 | 177 | function _burn(address _owner, uint256 _tokenId) internal { 178 | super._burn(_tokenId); 179 | burnedCounter++; 180 | } 181 | 182 | function tokensOfOwner(address _owner) external view returns(uint256[] memory ownerTokens) { 183 | uint256 tokenCount = balanceOf(_owner); 184 | 185 | if (tokenCount == 0) { 186 | return new uint256[](0); 187 | } else { 188 | uint256[] memory result = new uint256[](tokenCount); 189 | uint256 resultIndex = 0; 190 | uint256 _tokenIdx; 191 | for (_tokenIdx = 0; _tokenIdx < tokenCount; _tokenIdx++) { 192 | result[resultIndex] = tokenOfOwnerByIndex(_owner, _tokenIdx); 193 | resultIndex++; 194 | } 195 | return result; 196 | } 197 | } 198 | } 199 | -------------------------------------------------------------------------------- /contracts/newPlanet/Staking.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.6.2; 2 | 3 | import './ShitBox.sol'; 4 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/SafeERC20.sol"; 5 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/token/ERC20/IERC20.sol"; 6 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/math/SafeMath.sol"; 7 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/math/Math.sol"; 8 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/access/Ownable.sol"; 9 | import "https://github.com/OpenZeppelin/openzeppelin-contracts/blob/v3.3.0/contracts/utils/EnumerableSet.sol"; 10 | 11 | 12 | interface IStakingRewards { 13 | // Views 14 | function lastTimeRewardApplicable() external view returns (uint256); 15 | 16 | function rewardPerToken() external view returns (uint256); 17 | 18 | function earned(address account) external view returns (uint256); 19 | 20 | function getRewardForDuration() external view returns (uint256); 21 | 22 | function totalSupply() external view returns (uint256); 23 | 24 | function balanceOf(address account) external view returns (uint256); 25 | 26 | // Mutative 27 | 28 | function stake(uint256 amount) external; 29 | 30 | function withdraw(uint256 amount) external; 31 | 32 | function getReward() external; 33 | 34 | function exit() external; 35 | } 36 | 37 | // https://docs.synthetix.io/contracts/source/contracts/stakingrewards 38 | contract StakingRewards is IStakingRewards { 39 | using SafeMath for uint256; 40 | using SafeERC20 for IERC20; 41 | using EnumerableSet for EnumerableSet.UintSet; 42 | 43 | /* ========== STATE VARIABLES ========== */ 44 | 45 | address public shitboxAddress = 0xe16DE80288618D6c159aDa57E32247114B185aD0; 46 | ShitBox shitbox = ShitBox(shitboxAddress); 47 | 48 | // TODO 49 | address _rewardsToken = address(0xa63190F5da411fFE60c0a70E9EAc95cCD5e626be); 50 | IERC20 public rewardsToken = IERC20(_rewardsToken); 51 | uint256 public periodFinish = 0; 52 | uint256 public rewardRate = 0; 53 | uint256 public rewardsDuration = 365 days; 54 | uint256 public lastUpdateTime; 55 | uint256 public rewardPerTokenStored; 56 | 57 | mapping(address => uint256) public userRewardPerTokenPaid; 58 | mapping(address => uint256) public rewards; 59 | 60 | uint256 private _totalMiningPower; 61 | mapping(address => uint256) private _balances; 62 | mapping(uint256 => address) public _ownerOf; 63 | 64 | mapping (address => EnumerableSet.UintSet) private _holderTokens; 65 | 66 | 67 | /* ========== CONSTRUCTOR ========== */ 68 | address owner = address(0x0); 69 | 70 | modifier onlyOwner(){ 71 | require(msg.sender == owner, "!owner"); 72 | _; 73 | } 74 | 75 | constructor( 76 | ) public { 77 | owner = msg.sender; 78 | } 79 | 80 | /* ========== VIEWS ========== */ 81 | 82 | function exit() external override{ 83 | 84 | } 85 | 86 | function ownerOf(uint256 boxId) public view returns(address) { 87 | return _ownerOf[boxId]; 88 | } 89 | 90 | function tokensOfOwner(address owner) public view returns(uint256[] memory ownerTokens) { 91 | uint256 tokenCount = _holderTokens[owner].length(); 92 | 93 | if (tokenCount == 0) { 94 | return new uint256[](0); 95 | } else { 96 | uint256[] memory result = new uint256[](tokenCount); 97 | uint256 resultIndex = 0; 98 | uint256 _tokenIdx; 99 | for (_tokenIdx = 0; _tokenIdx < tokenCount; _tokenIdx++) { 100 | result[resultIndex] = _holderTokens[owner].at(_tokenIdx); 101 | resultIndex++; 102 | } 103 | return result; 104 | } 105 | } 106 | 107 | function totalSupply() external override view returns (uint256) { 108 | return _totalMiningPower; 109 | } 110 | 111 | function balanceOf(address account) external override view returns (uint256) { 112 | return _balances[account]; 113 | } 114 | 115 | function lastTimeRewardApplicable() public override view returns (uint256) { 116 | return Math.min(block.timestamp, periodFinish); 117 | } 118 | 119 | function rewardPerToken() public override view returns (uint256) { 120 | if (_totalMiningPower == 0) { 121 | return rewardPerTokenStored; 122 | } 123 | return 124 | rewardPerTokenStored.add( 125 | lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e18).div(_totalMiningPower) 126 | ); 127 | } 128 | 129 | function earned(address account) public override view returns (uint256) { 130 | return _balances[account].mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e18).add(rewards[account]); 131 | } 132 | 133 | function getRewardForDuration() external override view returns (uint256) { 134 | return rewardRate.mul(rewardsDuration); 135 | } 136 | 137 | function stake(uint256 boxId) external override updateReward(msg.sender) { 138 | uint256 miningPower = shitbox.getMiningPower(boxId); 139 | require(miningPower > 0, "0 mining power"); 140 | 141 | shitbox.transferFrom(msg.sender, address(this), boxId); 142 | require(shitbox.ownerOf(boxId) == address(this),"transferFrom failed"); 143 | 144 | _totalMiningPower = _totalMiningPower.add(miningPower); 145 | _balances[msg.sender] = _balances[msg.sender].add(miningPower); 146 | _ownerOf[boxId] = msg.sender; 147 | _holderTokens[msg.sender].add(boxId); 148 | } 149 | 150 | function withdraw(uint256 boxId) public override updateReward(msg.sender) { 151 | require(shitbox.ownerOf(boxId) == address(this)); 152 | require(_ownerOf[boxId] == msg.sender); 153 | 154 | uint256 miningPower = shitbox.getMiningPower(boxId); 155 | _totalMiningPower = _totalMiningPower.sub(miningPower); 156 | _balances[msg.sender] = _balances[msg.sender].sub(miningPower); 157 | _ownerOf[boxId] = address(0x0); 158 | _holderTokens[msg.sender].remove(boxId); 159 | shitbox.transferFrom(address(this), msg.sender, boxId); 160 | } 161 | 162 | function getReward() public override updateReward(msg.sender) { 163 | uint256 reward = rewards[msg.sender]; 164 | if (reward > 0) { 165 | rewards[msg.sender] = 0; 166 | rewardsToken.safeTransfer(msg.sender, reward); 167 | } 168 | } 169 | 170 | function notifyRewardAmount(uint256 reward) external updateReward(address(0)) { 171 | if (block.timestamp >= periodFinish) { 172 | rewardRate = reward.div(rewardsDuration); 173 | } else { 174 | uint256 remaining = periodFinish.sub(block.timestamp); 175 | uint256 leftover = remaining.mul(rewardRate); 176 | rewardRate = reward.add(leftover).div(rewardsDuration); 177 | } 178 | 179 | // Ensure the provided reward amount is not more than the balance in the contract. 180 | // This keeps the reward rate in the right range, preventing overflows due to 181 | // very high values of rewardRate in the earned and rewardsPerToken functions; 182 | // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow. 183 | uint balance = rewardsToken.balanceOf(address(this)); 184 | require(rewardRate <= balance.div(rewardsDuration), "Provided reward too high"); 185 | 186 | lastUpdateTime = block.timestamp; 187 | periodFinish = block.timestamp.add(rewardsDuration); 188 | } 189 | 190 | // End rewards emission earlier 191 | function updatePeriodFinish(uint timestamp) external onlyOwner updateReward(address(0)) { 192 | periodFinish = timestamp; 193 | } 194 | 195 | // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders 196 | function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner { 197 | require(tokenAddress != address(rewardsToken), "Cannot withdraw the rewards token"); 198 | IERC20(tokenAddress).safeTransfer(owner, tokenAmount); 199 | } 200 | 201 | function setRewardsDuration(uint256 _rewardsDuration) external onlyOwner { 202 | require( 203 | block.timestamp > periodFinish, 204 | "Previous rewards period must be complete before changing the duration for the new period" 205 | ); 206 | rewardsDuration = _rewardsDuration; 207 | } 208 | 209 | modifier updateReward(address account) { 210 | rewardPerTokenStored = rewardPerToken(); 211 | lastUpdateTime = lastTimeRewardApplicable(); 212 | if (account != address(0)) { 213 | rewards[account] = earned(account); 214 | userRewardPerTokenPaid[account] = rewardPerTokenStored; 215 | } 216 | _; 217 | } 218 | } 219 | -------------------------------------------------------------------------------- /abi/shit.abi: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [], 4 | "stateMutability": "nonpayable", 5 | "type": "constructor" 6 | }, 7 | { 8 | "anonymous": false, 9 | "inputs": [ 10 | { 11 | "indexed": true, 12 | "internalType": "address", 13 | "name": "owner", 14 | "type": "address" 15 | }, 16 | { 17 | "indexed": true, 18 | "internalType": "address", 19 | "name": "spender", 20 | "type": "address" 21 | }, 22 | { 23 | "indexed": false, 24 | "internalType": "uint256", 25 | "name": "value", 26 | "type": "uint256" 27 | } 28 | ], 29 | "name": "Approval", 30 | "type": "event" 31 | }, 32 | { 33 | "anonymous": false, 34 | "inputs": [ 35 | { 36 | "indexed": true, 37 | "internalType": "address", 38 | "name": "from", 39 | "type": "address" 40 | }, 41 | { 42 | "indexed": true, 43 | "internalType": "address", 44 | "name": "to", 45 | "type": "address" 46 | }, 47 | { 48 | "indexed": false, 49 | "internalType": "uint256", 50 | "name": "value", 51 | "type": "uint256" 52 | } 53 | ], 54 | "name": "Transfer", 55 | "type": "event" 56 | }, 57 | { 58 | "inputs": [ 59 | { 60 | "internalType": "address", 61 | "name": "tokenAddress", 62 | "type": "address" 63 | }, 64 | { 65 | "internalType": "address", 66 | "name": "bridge", 67 | "type": "address" 68 | } 69 | ], 70 | "name": "addShitToken", 71 | "outputs": [], 72 | "stateMutability": "nonpayable", 73 | "type": "function" 74 | }, 75 | { 76 | "inputs": [ 77 | { 78 | "internalType": "address", 79 | "name": "owner", 80 | "type": "address" 81 | }, 82 | { 83 | "internalType": "address", 84 | "name": "spender", 85 | "type": "address" 86 | } 87 | ], 88 | "name": "allowance", 89 | "outputs": [ 90 | { 91 | "internalType": "uint256", 92 | "name": "", 93 | "type": "uint256" 94 | } 95 | ], 96 | "stateMutability": "view", 97 | "type": "function" 98 | }, 99 | { 100 | "inputs": [ 101 | { 102 | "internalType": "address", 103 | "name": "spender", 104 | "type": "address" 105 | }, 106 | { 107 | "internalType": "uint256", 108 | "name": "amount", 109 | "type": "uint256" 110 | } 111 | ], 112 | "name": "approve", 113 | "outputs": [ 114 | { 115 | "internalType": "bool", 116 | "name": "", 117 | "type": "bool" 118 | } 119 | ], 120 | "stateMutability": "nonpayable", 121 | "type": "function" 122 | }, 123 | { 124 | "inputs": [ 125 | { 126 | "internalType": "address", 127 | "name": "account", 128 | "type": "address" 129 | } 130 | ], 131 | "name": "balanceOf", 132 | "outputs": [ 133 | { 134 | "internalType": "uint256", 135 | "name": "", 136 | "type": "uint256" 137 | } 138 | ], 139 | "stateMutability": "view", 140 | "type": "function" 141 | }, 142 | { 143 | "inputs": [ 144 | { 145 | "internalType": "address", 146 | "name": "", 147 | "type": "address" 148 | } 149 | ], 150 | "name": "bridges", 151 | "outputs": [ 152 | { 153 | "internalType": "address", 154 | "name": "", 155 | "type": "address" 156 | } 157 | ], 158 | "stateMutability": "view", 159 | "type": "function" 160 | }, 161 | { 162 | "inputs": [], 163 | "name": "decimals", 164 | "outputs": [ 165 | { 166 | "internalType": "uint8", 167 | "name": "", 168 | "type": "uint8" 169 | } 170 | ], 171 | "stateMutability": "view", 172 | "type": "function" 173 | }, 174 | { 175 | "inputs": [ 176 | { 177 | "internalType": "address", 178 | "name": "spender", 179 | "type": "address" 180 | }, 181 | { 182 | "internalType": "uint256", 183 | "name": "subtractedValue", 184 | "type": "uint256" 185 | } 186 | ], 187 | "name": "decreaseAllowance", 188 | "outputs": [ 189 | { 190 | "internalType": "bool", 191 | "name": "", 192 | "type": "bool" 193 | } 194 | ], 195 | "stateMutability": "nonpayable", 196 | "type": "function" 197 | }, 198 | { 199 | "inputs": [ 200 | { 201 | "internalType": "address", 202 | "name": "tokenAddress", 203 | "type": "address" 204 | } 205 | ], 206 | "name": "getBridgeToken", 207 | "outputs": [ 208 | { 209 | "internalType": "address", 210 | "name": "", 211 | "type": "address" 212 | } 213 | ], 214 | "stateMutability": "view", 215 | "type": "function" 216 | }, 217 | { 218 | "inputs": [], 219 | "name": "getRange", 220 | "outputs": [ 221 | { 222 | "internalType": "uint256[]", 223 | "name": "", 224 | "type": "uint256[]" 225 | } 226 | ], 227 | "stateMutability": "view", 228 | "type": "function" 229 | }, 230 | { 231 | "inputs": [], 232 | "name": "getShitTokenList", 233 | "outputs": [ 234 | { 235 | "internalType": "address[]", 236 | "name": "", 237 | "type": "address[]" 238 | } 239 | ], 240 | "stateMutability": "view", 241 | "type": "function" 242 | }, 243 | { 244 | "inputs": [], 245 | "name": "governance", 246 | "outputs": [ 247 | { 248 | "internalType": "address", 249 | "name": "", 250 | "type": "address" 251 | } 252 | ], 253 | "stateMutability": "view", 254 | "type": "function" 255 | }, 256 | { 257 | "inputs": [ 258 | { 259 | "internalType": "address", 260 | "name": "spender", 261 | "type": "address" 262 | }, 263 | { 264 | "internalType": "uint256", 265 | "name": "addedValue", 266 | "type": "uint256" 267 | } 268 | ], 269 | "name": "increaseAllowance", 270 | "outputs": [ 271 | { 272 | "internalType": "bool", 273 | "name": "", 274 | "type": "bool" 275 | } 276 | ], 277 | "stateMutability": "nonpayable", 278 | "type": "function" 279 | }, 280 | { 281 | "inputs": [ 282 | { 283 | "internalType": "address", 284 | "name": "tokenAddress", 285 | "type": "address" 286 | } 287 | ], 288 | "name": "isShitToken", 289 | "outputs": [ 290 | { 291 | "internalType": "bool", 292 | "name": "", 293 | "type": "bool" 294 | } 295 | ], 296 | "stateMutability": "view", 297 | "type": "function" 298 | }, 299 | { 300 | "inputs": [], 301 | "name": "name", 302 | "outputs": [ 303 | { 304 | "internalType": "string", 305 | "name": "", 306 | "type": "string" 307 | } 308 | ], 309 | "stateMutability": "view", 310 | "type": "function" 311 | }, 312 | { 313 | "inputs": [ 314 | { 315 | "internalType": "uint256", 316 | "name": "", 317 | "type": "uint256" 318 | } 319 | ], 320 | "name": "rangeValue", 321 | "outputs": [ 322 | { 323 | "internalType": "uint256", 324 | "name": "", 325 | "type": "uint256" 326 | } 327 | ], 328 | "stateMutability": "view", 329 | "type": "function" 330 | }, 331 | { 332 | "inputs": [ 333 | { 334 | "internalType": "address", 335 | "name": "tokenAddress", 336 | "type": "address" 337 | } 338 | ], 339 | "name": "removeShitToken", 340 | "outputs": [], 341 | "stateMutability": "nonpayable", 342 | "type": "function" 343 | }, 344 | { 345 | "inputs": [ 346 | { 347 | "internalType": "address", 348 | "name": "_governance", 349 | "type": "address" 350 | } 351 | ], 352 | "name": "setGovernance", 353 | "outputs": [], 354 | "stateMutability": "nonpayable", 355 | "type": "function" 356 | }, 357 | { 358 | "inputs": [ 359 | { 360 | "internalType": "uint256", 361 | "name": "", 362 | "type": "uint256" 363 | } 364 | ], 365 | "name": "shitTokenList", 366 | "outputs": [ 367 | { 368 | "internalType": "address", 369 | "name": "", 370 | "type": "address" 371 | } 372 | ], 373 | "stateMutability": "view", 374 | "type": "function" 375 | }, 376 | { 377 | "inputs": [ 378 | { 379 | "internalType": "address", 380 | "name": "", 381 | "type": "address" 382 | } 383 | ], 384 | "name": "shitTokens", 385 | "outputs": [ 386 | { 387 | "internalType": "bool", 388 | "name": "", 389 | "type": "bool" 390 | } 391 | ], 392 | "stateMutability": "view", 393 | "type": "function" 394 | }, 395 | { 396 | "inputs": [], 397 | "name": "symbol", 398 | "outputs": [ 399 | { 400 | "internalType": "string", 401 | "name": "", 402 | "type": "string" 403 | } 404 | ], 405 | "stateMutability": "view", 406 | "type": "function" 407 | }, 408 | { 409 | "inputs": [], 410 | "name": "totalSupply", 411 | "outputs": [ 412 | { 413 | "internalType": "uint256", 414 | "name": "", 415 | "type": "uint256" 416 | } 417 | ], 418 | "stateMutability": "view", 419 | "type": "function" 420 | }, 421 | { 422 | "inputs": [ 423 | { 424 | "internalType": "address", 425 | "name": "recipient", 426 | "type": "address" 427 | }, 428 | { 429 | "internalType": "uint256", 430 | "name": "amount", 431 | "type": "uint256" 432 | } 433 | ], 434 | "name": "transfer", 435 | "outputs": [ 436 | { 437 | "internalType": "bool", 438 | "name": "", 439 | "type": "bool" 440 | } 441 | ], 442 | "stateMutability": "nonpayable", 443 | "type": "function" 444 | }, 445 | { 446 | "inputs": [ 447 | { 448 | "internalType": "address", 449 | "name": "sender", 450 | "type": "address" 451 | }, 452 | { 453 | "internalType": "address", 454 | "name": "recipient", 455 | "type": "address" 456 | }, 457 | { 458 | "internalType": "uint256", 459 | "name": "amount", 460 | "type": "uint256" 461 | } 462 | ], 463 | "name": "transferFrom", 464 | "outputs": [ 465 | { 466 | "internalType": "bool", 467 | "name": "", 468 | "type": "bool" 469 | } 470 | ], 471 | "stateMutability": "nonpayable", 472 | "type": "function" 473 | } 474 | ] -------------------------------------------------------------------------------- /contracts/shit.sol: -------------------------------------------------------------------------------- 1 | /** 2 | *Submitted for verification at Etherscan.io on 2020-07-26 3 | */ 4 | 5 | pragma solidity ^0.6.0; 6 | 7 | interface IERC20 { 8 | function totalSupply() external view returns (uint); 9 | function balanceOf(address account) external view returns (uint); 10 | function transfer(address recipient, uint amount) external returns (bool); 11 | function allowance(address owner, address spender) external view returns (uint); 12 | function approve(address spender, uint amount) external returns (bool); 13 | function transferFrom(address sender, address recipient, uint amount) external returns (bool); 14 | event Transfer(address indexed from, address indexed to, uint value); 15 | event Approval(address indexed owner, address indexed spender, uint value); 16 | } 17 | 18 | contract Context { 19 | constructor () internal { } 20 | // solhint-disable-previous-line no-empty-blocks 21 | 22 | function _msgSender() internal view returns (address payable) { 23 | return msg.sender; 24 | } 25 | } 26 | 27 | contract ERC20 is Context, IERC20 { 28 | using SafeMath for uint; 29 | 30 | mapping (address => uint) private _balances; 31 | 32 | mapping (address => mapping (address => uint)) private _allowances; 33 | 34 | uint private _totalSupply; 35 | 36 | function totalSupply() public view override returns (uint) { 37 | return _totalSupply; 38 | } 39 | function balanceOf(address account) public view override returns (uint) { 40 | return _balances[account]; 41 | } 42 | function transfer(address recipient, uint amount) public override returns (bool) { 43 | _transfer(_msgSender(), recipient, amount); 44 | return true; 45 | } 46 | function allowance(address owner, address spender) public view override returns (uint) { 47 | return _allowances[owner][spender]; 48 | } 49 | function approve(address spender, uint amount) public override returns (bool) { 50 | _approve(_msgSender(), spender, amount); 51 | return true; 52 | } 53 | function transferFrom(address sender, address recipient, uint amount) public override returns (bool) { 54 | _transfer(sender, recipient, amount); 55 | _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); 56 | return true; 57 | } 58 | function increaseAllowance(address spender, uint addedValue) public returns (bool) { 59 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); 60 | return true; 61 | } 62 | function decreaseAllowance(address spender, uint subtractedValue) public returns (bool) { 63 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); 64 | return true; 65 | } 66 | function _transfer(address sender, address recipient, uint amount) internal { 67 | require(sender != address(0), "ERC20: transfer from the zero address"); 68 | require(recipient != address(0), "ERC20: transfer to the zero address"); 69 | 70 | _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); 71 | _balances[recipient] = _balances[recipient].add(amount); 72 | emit Transfer(sender, recipient, amount); 73 | } 74 | function _mint(address account, uint amount) internal { 75 | require(account != address(0), "ERC20: mint to the zero address"); 76 | 77 | _totalSupply = _totalSupply.add(amount); 78 | _balances[account] = _balances[account].add(amount); 79 | emit Transfer(address(0), account, amount); 80 | } 81 | function _burn(address account, uint amount) internal { 82 | require(account != address(0), "ERC20: burn from the zero address"); 83 | 84 | _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); 85 | _totalSupply = _totalSupply.sub(amount); 86 | emit Transfer(account, address(0), amount); 87 | } 88 | function _approve(address owner, address spender, uint amount) internal { 89 | require(owner != address(0), "ERC20: approve from the zero address"); 90 | require(spender != address(0), "ERC20: approve to the zero address"); 91 | 92 | _allowances[owner][spender] = amount; 93 | emit Approval(owner, spender, amount); 94 | } 95 | } 96 | 97 | contract ERC20Detailed { 98 | string private _name; 99 | string private _symbol; 100 | uint8 private _decimals; 101 | 102 | constructor (string memory name, string memory symbol, uint8 decimals) public { 103 | _name = name; 104 | _symbol = symbol; 105 | _decimals = decimals; 106 | } 107 | 108 | function name() public view returns (string memory) { 109 | return _name; 110 | } 111 | function symbol() public view returns (string memory) { 112 | return _symbol; 113 | } 114 | function decimals() public view returns (uint8) { 115 | return _decimals; 116 | } 117 | } 118 | 119 | library SafeMath { 120 | function add(uint a, uint b) internal pure returns (uint) { 121 | uint c = a + b; 122 | require(c >= a, "SafeMath: addition overflow"); 123 | 124 | return c; 125 | } 126 | function sub(uint a, uint b) internal pure returns (uint) { 127 | return sub(a, b, "SafeMath: subtraction overflow"); 128 | } 129 | function sub(uint a, uint b, string memory errorMessage) internal pure returns (uint) { 130 | require(b <= a, errorMessage); 131 | uint c = a - b; 132 | 133 | return c; 134 | } 135 | function mul(uint a, uint b) internal pure returns (uint) { 136 | if (a == 0) { 137 | return 0; 138 | } 139 | 140 | uint c = a * b; 141 | require(c / a == b, "SafeMath: multiplication overflow"); 142 | 143 | return c; 144 | } 145 | function div(uint a, uint b) internal pure returns (uint) { 146 | return div(a, b, "SafeMath: division by zero"); 147 | } 148 | function div(uint a, uint b, string memory errorMessage) internal pure returns (uint) { 149 | // Solidity only automatically asserts when dividing by 0 150 | require(b > 0, errorMessage); 151 | uint c = a / b; 152 | 153 | return c; 154 | } 155 | } 156 | 157 | library Address { 158 | function isContract(address account) internal view returns (bool) { 159 | bytes32 codehash; 160 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 161 | // solhint-disable-next-line no-inline-assembly 162 | assembly { codehash := extcodehash(account) } 163 | return (codehash != 0x0 && codehash != accountHash); 164 | } 165 | } 166 | 167 | library SafeERC20 { 168 | using SafeMath for uint; 169 | using Address for address; 170 | 171 | function safeTransfer(IERC20 token, address to, uint value) internal { 172 | callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 173 | } 174 | 175 | function safeTransferFrom(IERC20 token, address from, address to, uint value) internal { 176 | callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 177 | } 178 | 179 | function safeApprove(IERC20 token, address spender, uint value) internal { 180 | require((value == 0) || (token.allowance(address(this), spender) == 0), 181 | "SafeERC20: approve from non-zero to non-zero allowance" 182 | ); 183 | callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 184 | } 185 | function callOptionalReturn(IERC20 token, bytes memory data) private { 186 | require(address(token).isContract(), "SafeERC20: call to non-contract"); 187 | 188 | // solhint-disable-next-line avoid-low-level-calls 189 | (bool success, bytes memory returndata) = address(token).call(data); 190 | require(success, "SafeERC20: low-level call failed"); 191 | 192 | if (returndata.length > 0) { // Return data is optional 193 | // solhint-disable-next-line max-line-length 194 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 195 | } 196 | } 197 | } 198 | 199 | contract Shit is ERC20, ERC20Detailed { 200 | using SafeERC20 for IERC20; 201 | using Address for address; 202 | using SafeMath for uint; 203 | 204 | address public governance; 205 | mapping (address => bool) public shitTokens; 206 | mapping (address => address) public bridges; 207 | 208 | address[] public shitTokenList; 209 | // The value determines the kind of nft 210 | // The array control the interval of rangevalue which could be supported to change by shitdao 211 | uint[] public rangeValue = [1, 10, 100, 1000, 10000, 100000]; 212 | 213 | constructor () public ERC20Detailed("ShitHole", "SHIT", 18) { 214 | governance = tx.origin; 215 | 216 | _mint(msg.sender, 1000000000000000000); 217 | } 218 | 219 | function addShitToken(address tokenAddress, address bridge) public { 220 | require(msg.sender == governance, "!governance"); 221 | shitTokens[tokenAddress] = true; 222 | bridges[tokenAddress] = bridge; 223 | shitTokenList.push(tokenAddress); 224 | } 225 | 226 | function getShitTokenList() public view returns(address[] memory) { 227 | return shitTokenList; 228 | } 229 | 230 | function getBridgeToken(address tokenAddress) public view returns(address) { 231 | return bridges[tokenAddress]; 232 | } 233 | 234 | function removeShitToken(address tokenAddress) public { 235 | require(msg.sender == governance, "!governance"); 236 | shitTokens[tokenAddress] = false; 237 | bridges[tokenAddress] = address(0); 238 | } 239 | 240 | function isShitToken(address tokenAddress) public view returns (bool) { 241 | return shitTokens[tokenAddress]; 242 | } 243 | 244 | function setGovernance(address _governance) public { 245 | require(msg.sender == governance, "!governance"); 246 | governance = _governance; 247 | } 248 | 249 | function getRange() public view returns (uint[] memory){ 250 | return rangeValue; 251 | } 252 | } 253 | -------------------------------------------------------------------------------- /contracts/utils/ERC721.sol: -------------------------------------------------------------------------------- 1 | pragma solidity ^0.4.24; 2 | 3 | import "./IERC721.sol"; 4 | import "./IERC721Receiver.sol"; 5 | import "./SafeMath.sol"; 6 | import "./Address.sol"; 7 | import "./IERC165.sol"; 8 | 9 | /** 10 | * @title ERC721 Non-Fungible Token Standard basic implementation 11 | * @dev see https://github.com/ethereum/EIPs/blob/master/EIPS/eip-721.md 12 | */ 13 | contract ERC721 is ERC165, IERC721 { 14 | 15 | using SafeMath for uint256; 16 | using Address for address; 17 | 18 | // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` 19 | // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector` 20 | bytes4 private constant _ERC721_RECEIVED = 0x150b7a02; 21 | 22 | // Mapping from token ID to owner 23 | mapping (uint256 => address) private _tokenOwner; 24 | 25 | // Mapping from token ID to approved address 26 | mapping (uint256 => address) private _tokenApprovals; 27 | 28 | // Mapping from owner to number of owned token 29 | mapping (address => uint256) private _ownedTokensCount; 30 | 31 | // Mapping from owner to operator approvals 32 | mapping (address => mapping (address => bool)) private _operatorApprovals; 33 | 34 | bytes4 private constant _InterfaceId_ERC721 = 0x80ac58cd; 35 | /* 36 | * 0x80ac58cd === 37 | * bytes4(keccak256('balanceOf(address)')) ^ 38 | * bytes4(keccak256('ownerOf(uint256)')) ^ 39 | * bytes4(keccak256('approve(address,uint256)')) ^ 40 | * bytes4(keccak256('getApproved(uint256)')) ^ 41 | * bytes4(keccak256('setApprovalForAll(address,bool)')) ^ 42 | * bytes4(keccak256('isApprovedForAll(address,address)')) ^ 43 | * bytes4(keccak256('transferFrom(address,address,uint256)')) ^ 44 | * bytes4(keccak256('safeTransferFrom(address,address,uint256)')) ^ 45 | * bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) 46 | */ 47 | 48 | constructor() 49 | public 50 | { 51 | // register the supported interfaces to conform to ERC721 via ERC165 52 | _registerInterface(_InterfaceId_ERC721); 53 | } 54 | 55 | /** 56 | * @dev Gets the balance of the specified address 57 | * @param owner address to query the balance of 58 | * @return uint256 representing the amount owned by the passed address 59 | */ 60 | function balanceOf(address owner) public view returns (uint256) { 61 | require(owner != address(0)); 62 | return _ownedTokensCount[owner]; 63 | } 64 | 65 | /** 66 | * @dev Gets the owner of the specified token ID 67 | * @param tokenId uint256 ID of the token to query the owner of 68 | * @return owner address currently marked as the owner of the given token ID 69 | */ 70 | function ownerOf(uint256 tokenId) public view returns (address) { 71 | address owner = _tokenOwner[tokenId]; 72 | require(owner != address(0)); 73 | return owner; 74 | } 75 | 76 | /** 77 | * @dev Approves another address to transfer the given token ID 78 | * The zero address indicates there is no approved address. 79 | * There can only be one approved address per token at a given time. 80 | * Can only be called by the token owner or an approved operator. 81 | * @param to address to be approved for the given token ID 82 | * @param tokenId uint256 ID of the token to be approved 83 | */ 84 | function approve(address to, uint256 tokenId) public { 85 | address owner = ownerOf(tokenId); 86 | require(to != owner); 87 | require(msg.sender == owner || isApprovedForAll(owner, msg.sender)); 88 | 89 | _tokenApprovals[tokenId] = to; 90 | emit Approval(owner, to, tokenId); 91 | } 92 | 93 | /** 94 | * @dev Gets the approved address for a token ID, or zero if no address set 95 | * Reverts if the token ID does not exist. 96 | * @param tokenId uint256 ID of the token to query the approval of 97 | * @return address currently approved for the given token ID 98 | */ 99 | function getApproved(uint256 tokenId) public view returns (address) { 100 | require(_exists(tokenId)); 101 | return _tokenApprovals[tokenId]; 102 | } 103 | 104 | /** 105 | * @dev Sets or unsets the approval of a given operator 106 | * An operator is allowed to transfer all tokens of the sender on their behalf 107 | * @param to operator address to set the approval 108 | * @param approved representing the status of the approval to be set 109 | */ 110 | function setApprovalForAll(address to, bool approved) public { 111 | require(to != msg.sender); 112 | _operatorApprovals[msg.sender][to] = approved; 113 | emit ApprovalForAll(msg.sender, to, approved); 114 | } 115 | 116 | /** 117 | * @dev Tells whether an operator is approved by a given owner 118 | * @param owner owner address which you want to query the approval of 119 | * @param operator operator address which you want to query the approval of 120 | * @return bool whether the given operator is approved by the given owner 121 | */ 122 | function isApprovedForAll( 123 | address owner, 124 | address operator 125 | ) 126 | public 127 | view 128 | returns (bool) 129 | { 130 | return _operatorApprovals[owner][operator]; 131 | } 132 | 133 | /** 134 | * @dev Transfers the ownership of a given token ID to another address 135 | * Usage of this method is discouraged, use `safeTransferFrom` whenever possible 136 | * Requires the msg sender to be the owner, approved, or operator 137 | * @param from current owner of the token 138 | * @param to address to receive the ownership of the given token ID 139 | * @param tokenId uint256 ID of the token to be transferred 140 | */ 141 | function transferFrom( 142 | address from, 143 | address to, 144 | uint256 tokenId 145 | ) 146 | public 147 | { 148 | require(_isApprovedOrOwner(msg.sender, tokenId)); 149 | require(to != address(0)); 150 | 151 | _clearApproval(from, tokenId); 152 | _removeTokenFrom(from, tokenId); 153 | _addTokenTo(to, tokenId); 154 | 155 | emit Transfer(from, to, tokenId); 156 | } 157 | 158 | /** 159 | * @dev Safely transfers the ownership of a given token ID to another address 160 | * If the target address is a contract, it must implement `onERC721Received`, 161 | * which is called upon a safe transfer, and return the magic value 162 | * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, 163 | * the transfer is reverted. 164 | * 165 | * Requires the msg sender to be the owner, approved, or operator 166 | * @param from current owner of the token 167 | * @param to address to receive the ownership of the given token ID 168 | * @param tokenId uint256 ID of the token to be transferred 169 | */ 170 | function safeTransferFrom( 171 | address from, 172 | address to, 173 | uint256 tokenId 174 | ) 175 | public 176 | { 177 | // solium-disable-next-line arg-overflow 178 | safeTransferFrom(from, to, tokenId, ""); 179 | } 180 | 181 | /** 182 | * @dev Safely transfers the ownership of a given token ID to another address 183 | * If the target address is a contract, it must implement `onERC721Received`, 184 | * which is called upon a safe transfer, and return the magic value 185 | * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`; otherwise, 186 | * the transfer is reverted. 187 | * Requires the msg sender to be the owner, approved, or operator 188 | * @param from current owner of the token 189 | * @param to address to receive the ownership of the given token ID 190 | * @param tokenId uint256 ID of the token to be transferred 191 | * @param _data bytes data to send along with a safe transfer check 192 | */ 193 | function safeTransferFrom( 194 | address from, 195 | address to, 196 | uint256 tokenId, 197 | bytes _data 198 | ) 199 | public 200 | { 201 | transferFrom(from, to, tokenId); 202 | // solium-disable-next-line arg-overflow 203 | require(_checkOnERC721Received(from, to, tokenId, _data)); 204 | } 205 | 206 | /** 207 | * @dev Returns whether the specified token exists 208 | * @param tokenId uint256 ID of the token to query the existence of 209 | * @return whether the token exists 210 | */ 211 | function _exists(uint256 tokenId) internal view returns (bool) { 212 | address owner = _tokenOwner[tokenId]; 213 | return owner != address(0); 214 | } 215 | 216 | /** 217 | * @dev Returns whether the given spender can transfer a given token ID 218 | * @param spender address of the spender to query 219 | * @param tokenId uint256 ID of the token to be transferred 220 | * @return bool whether the msg.sender is approved for the given token ID, 221 | * is an operator of the owner, or is the owner of the token 222 | */ 223 | function _isApprovedOrOwner( 224 | address spender, 225 | uint256 tokenId 226 | ) 227 | internal 228 | view 229 | returns (bool) 230 | { 231 | address owner = ownerOf(tokenId); 232 | // Disable solium check because of 233 | // https://github.com/duaraghav8/Solium/issues/175 234 | // solium-disable-next-line operator-whitespace 235 | return ( 236 | spender == owner || 237 | getApproved(tokenId) == spender || 238 | isApprovedForAll(owner, spender) 239 | ); 240 | } 241 | 242 | /** 243 | * @dev Internal function to mint a new token 244 | * Reverts if the given token ID already exists 245 | * @param to The address that will own the minted token 246 | * @param tokenId uint256 ID of the token to be minted by the msg.sender 247 | */ 248 | function _mint(address to, uint256 tokenId) internal { 249 | require(to != address(0)); 250 | _addTokenTo(to, tokenId); 251 | emit Transfer(address(0), to, tokenId); 252 | } 253 | 254 | /** 255 | * @dev Internal function to burn a specific token 256 | * Reverts if the token does not exist 257 | * @param tokenId uint256 ID of the token being burned by the msg.sender 258 | */ 259 | function _burn(address owner, uint256 tokenId) internal { 260 | _clearApproval(owner, tokenId); 261 | _removeTokenFrom(owner, tokenId); 262 | emit Transfer(owner, address(0), tokenId); 263 | } 264 | 265 | /** 266 | * @dev Internal function to add a token ID to the list of a given address 267 | * Note that this function is left internal to make ERC721Enumerable possible, but is not 268 | * intended to be called by custom derived contracts: in particular, it emits no Transfer event. 269 | * @param to address representing the new owner of the given token ID 270 | * @param tokenId uint256 ID of the token to be added to the tokens list of the given address 271 | */ 272 | function _addTokenTo(address to, uint256 tokenId) internal { 273 | require(_tokenOwner[tokenId] == address(0)); 274 | _tokenOwner[tokenId] = to; 275 | _ownedTokensCount[to] = _ownedTokensCount[to].add(1); 276 | } 277 | 278 | /** 279 | * @dev Internal function to remove a token ID from the list of a given address 280 | * Note that this function is left internal to make ERC721Enumerable possible, but is not 281 | * intended to be called by custom derived contracts: in particular, it emits no Transfer event, 282 | * and doesn't clear approvals. 283 | * @param from address representing the previous owner of the given token ID 284 | * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address 285 | */ 286 | function _removeTokenFrom(address from, uint256 tokenId) internal { 287 | require(ownerOf(tokenId) == from); 288 | _ownedTokensCount[from] = _ownedTokensCount[from].sub(1); 289 | _tokenOwner[tokenId] = address(0); 290 | } 291 | 292 | /** 293 | * @dev Internal function to invoke `onERC721Received` on a target address 294 | * The call is not executed if the target address is not a contract 295 | * @param from address representing the previous owner of the given token ID 296 | * @param to target address that will receive the tokens 297 | * @param tokenId uint256 ID of the token to be transferred 298 | * @param _data bytes optional data to send along with the call 299 | * @return whether the call correctly returned the expected magic value 300 | */ 301 | function _checkOnERC721Received( 302 | address from, 303 | address to, 304 | uint256 tokenId, 305 | bytes _data 306 | ) 307 | internal 308 | returns (bool) 309 | { 310 | if (!to.isContract()) { 311 | return true; 312 | } 313 | bytes4 retval = IERC721Receiver(to).onERC721Received( 314 | msg.sender, from, tokenId, _data); 315 | return (retval == _ERC721_RECEIVED); 316 | } 317 | 318 | /** 319 | * @dev Private function to clear current approval of a given token ID 320 | * Reverts if the given address is not indeed the owner of the token 321 | * @param owner owner of the token 322 | * @param tokenId uint256 ID of the token to be transferred 323 | */ 324 | function _clearApproval(address owner, uint256 tokenId) private { 325 | require(ownerOf(tokenId) == owner); 326 | if (_tokenApprovals[tokenId] != address(0)) { 327 | _tokenApprovals[tokenId] = address(0); 328 | } 329 | } 330 | } 331 | -------------------------------------------------------------------------------- /contracts/staking.sol: -------------------------------------------------------------------------------- 1 | pragma solidity >=0.6.0; 2 | 3 | import './shitbox.sol'; 4 | 5 | interface IERC20 { 6 | function totalSupply() external view returns (uint); 7 | function balanceOf(address account) external view returns (uint); 8 | function transfer(address recipient, uint amount) external returns (bool); 9 | function allowance(address owner, address spender) external view returns (uint); 10 | function approve(address spender, uint amount) external returns (bool); 11 | function transferFrom(address sender, address recipient, uint amount) external returns (bool); 12 | event Transfer(address indexed from, address indexed to, uint value); 13 | event Approval(address indexed owner, address indexed spender, uint value); 14 | } 15 | 16 | contract Context { 17 | constructor () internal { } 18 | // solhint-disable-previous-line no-empty-blocks 19 | function _msgSender() internal view returns (address payable) { 20 | return msg.sender; 21 | } 22 | } 23 | 24 | contract ERC20 is Context, IERC20 { 25 | using SafeMath for uint; 26 | 27 | mapping (address => uint) private _balances; 28 | 29 | mapping (address => mapping (address => uint)) private _allowances; 30 | 31 | uint private _totalSupply; 32 | function totalSupply() public view returns (uint) { 33 | return _totalSupply; 34 | } 35 | function balanceOf(address account) public view returns (uint) { 36 | return _balances[account]; 37 | } 38 | function transfer(address recipient, uint amount) public returns (bool) { 39 | _transfer(_msgSender(), recipient, amount); 40 | return true; 41 | } 42 | function allowance(address owner, address spender) public view returns (uint) { 43 | return _allowances[owner][spender]; 44 | } 45 | function approve(address spender, uint amount) public returns (bool) { 46 | _approve(_msgSender(), spender, amount); 47 | return true; 48 | } 49 | function transferFrom(address sender, address recipient, uint amount) public returns (bool) { 50 | _transfer(sender, recipient, amount); 51 | _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); 52 | return true; 53 | } 54 | function increaseAllowance(address spender, uint addedValue) public returns (bool) { 55 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); 56 | return true; 57 | } 58 | function decreaseAllowance(address spender, uint subtractedValue) public returns (bool) { 59 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); 60 | return true; 61 | } 62 | function _transfer(address sender, address recipient, uint amount) internal { 63 | require(sender != address(0), "ERC20: transfer from the zero address"); 64 | require(recipient != address(0), "ERC20: transfer to the zero address"); 65 | 66 | _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); 67 | _balances[recipient] = _balances[recipient].add(amount); 68 | emit Transfer(sender, recipient, amount); 69 | } 70 | function _mint(address account, uint amount) internal { 71 | require(account != address(0), "ERC20: mint to the zero address"); 72 | 73 | _totalSupply = _totalSupply.add(amount); 74 | _balances[account] = _balances[account].add(amount); 75 | emit Transfer(address(0), account, amount); 76 | } 77 | function _burn(address account, uint amount) internal { 78 | require(account != address(0), "ERC20: burn from the zero address"); 79 | 80 | _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); 81 | _totalSupply = _totalSupply.sub(amount); 82 | emit Transfer(account, address(0), amount); 83 | } 84 | function _approve(address owner, address spender, uint amount) internal { 85 | require(owner != address(0), "ERC20: approve from the zero address"); 86 | require(spender != address(0), "ERC20: approve to the zero address"); 87 | 88 | _allowances[owner][spender] = amount; 89 | emit Approval(owner, spender, amount); 90 | } 91 | } 92 | 93 | contract ERC20Detailed is IERC20 { 94 | string private _name; 95 | string private _symbol; 96 | uint8 private _decimals; 97 | 98 | constructor (string memory name, string memory symbol, uint8 decimals) public { 99 | _name = name; 100 | _symbol = symbol; 101 | _decimals = decimals; 102 | } 103 | function name() public view returns (string memory) { 104 | return _name; 105 | } 106 | function symbol() public view returns (string memory) { 107 | return _symbol; 108 | } 109 | function decimals() public view returns (uint8) { 110 | return _decimals; 111 | } 112 | } 113 | 114 | library SafeMath { 115 | function add(uint a, uint b) internal pure returns (uint) { 116 | uint c = a + b; 117 | require(c >= a, "SafeMath: addition overflow"); 118 | 119 | return c; 120 | } 121 | function sub(uint a, uint b) internal pure returns (uint) { 122 | return sub(a, b, "SafeMath: subtraction overflow"); 123 | } 124 | function sub(uint a, uint b, string memory errorMessage) internal pure returns (uint) { 125 | require(b <= a, errorMessage); 126 | uint c = a - b; 127 | 128 | return c; 129 | } 130 | function mul(uint a, uint b) internal pure returns (uint) { 131 | if (a == 0) { 132 | return 0; 133 | } 134 | 135 | uint c = a * b; 136 | require(c / a == b, "SafeMath: multiplication overflow"); 137 | 138 | return c; 139 | } 140 | function div(uint a, uint b) internal pure returns (uint) { 141 | return div(a, b, "SafeMath: division by zero"); 142 | } 143 | function div(uint a, uint b, string memory errorMessage) internal pure returns (uint) { 144 | // Solidity only automatically asserts when dividing by 0 145 | require(b > 0, errorMessage); 146 | uint c = a / b; 147 | 148 | return c; 149 | } 150 | } 151 | 152 | library Address { 153 | function isContract(address account) internal view returns (bool) { 154 | bytes32 codehash; 155 | bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470; 156 | // solhint-disable-next-line no-inline-assembly 157 | assembly { codehash := extcodehash(account) } 158 | return (codehash != 0x0 && codehash != accountHash); 159 | } 160 | } 161 | 162 | library SafeERC20 { 163 | using SafeMath for uint; 164 | using Address for address; 165 | 166 | function safeTransfer(IERC20 token, address to, uint value) internal { 167 | callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); 168 | } 169 | 170 | function safeTransferFrom(IERC20 token, address from, address to, uint value) internal { 171 | callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); 172 | } 173 | 174 | function safeApprove(IERC20 token, address spender, uint value) internal { 175 | require((value == 0) || (token.allowance(address(this), spender) == 0), 176 | "SafeERC20: approve from non-zero to non-zero allowance" 177 | ); 178 | callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); 179 | } 180 | function callOptionalReturn(IERC20 token, bytes memory data) private { 181 | require(address(token).isContract(), "SafeERC20: call to non-contract"); 182 | 183 | // solhint-disable-next-line avoid-low-level-calls 184 | (bool success, bytes memory returndata) = address(token).call(data); 185 | require(success, "SafeERC20: low-level call failed"); 186 | 187 | if (returndata.length > 0) { // Return data is optional 188 | // solhint-disable-next-line max-line-length 189 | require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); 190 | } 191 | } 192 | } 193 | 194 | interface IStakingRewards { 195 | // Views 196 | function lastTimeRewardApplicable() external view returns (uint256); 197 | 198 | function rewardPerToken() external view returns (uint256); 199 | 200 | function earned(address account) external view returns (uint256); 201 | 202 | function getRewardForDuration() external view returns (uint256); 203 | 204 | function totalSupply() external view returns (uint256); 205 | 206 | function balanceOf(address account) external view returns (uint256); 207 | 208 | // Mutative 209 | 210 | function stake(uint256 amount) external; 211 | 212 | function withdraw(uint256 amount) external; 213 | 214 | function getReward() external; 215 | 216 | function exit() external; 217 | } 218 | 219 | // https://docs.synthetix.io/contracts/source/contracts/stakingrewards 220 | contract StakingRewards is IStakingRewards { 221 | using SafeMath for uint256; 222 | using SafeERC20 for IERC20; 223 | 224 | /* ========== STATE VARIABLES ========== */ 225 | 226 | address public shitboxAddress; 227 | ShitBox shitbox = ShitBox(shitboxAddress); 228 | 229 | IERC20 public rewardsToken; 230 | uint256 public periodFinish = 0; 231 | uint256 public rewardRate = 0; 232 | uint256 public rewardsDuration = 7 days; 233 | uint256 public lastUpdateTime; 234 | uint256 public rewardPerTokenStored; 235 | 236 | mapping(address => uint256) public userRewardPerTokenPaid; 237 | mapping(address => uint256) public rewards; 238 | 239 | uint256 private _totalMiningPower; 240 | mapping(address => uint256) private _balances; 241 | mapping(uint256 => address) public _ownerOf; 242 | 243 | /* ========== CONSTRUCTOR ========== */ 244 | 245 | constructor( 246 | address _owner, 247 | address _rewardsToken 248 | ) public Owned(_owner) { 249 | rewardsToken = IERC20(_rewardsToken); 250 | } 251 | 252 | /* ========== VIEWS ========== */ 253 | 254 | function totalMiningPower() external view returns (uint256) { 255 | return _totalMiningPower; 256 | } 257 | 258 | function balanceOf(address account) external view returns (uint256) { 259 | return _balances[account]; 260 | } 261 | 262 | function lastTimeRewardApplicable() public view returns (uint256) { 263 | return Math.min(block.timestamp, periodFinish); 264 | } 265 | 266 | function rewardPerToken() public view returns (uint256) { 267 | if (_totalSupply == 0) { 268 | return rewardPerTokenStored; 269 | } 270 | return 271 | rewardPerTokenStored.add( 272 | lastTimeRewardApplicable().sub(lastUpdateTime).mul(rewardRate).mul(1e18).div(_totalMiningPower) 273 | ); 274 | } 275 | 276 | function earned(address account) public view returns (uint256) { 277 | return _balances[account].mul(rewardPerToken().sub(userRewardPerTokenPaid[account])).div(1e18).add(rewards[account]); 278 | } 279 | 280 | function getRewardForDuration() external view returns (uint256) { 281 | return rewardRate.mul(rewardsDuration); 282 | } 283 | 284 | function stake(uint256 boxId) external updateReward(msg.sender) { 285 | uint256 miningPower = shitbox.getMiningPower(boxId); 286 | require(miningPower > 0, "0 mining power"); 287 | 288 | _totalMiningPower = _totalMiningPower.add(miningPower); 289 | _balances[msg.sender] = _balances[msg.sender].add(miningPower); 290 | _ownerOf[boxId] = msg.sender; 291 | shitbox.transferFrom(msg.sender, address(this), boxId); 292 | } 293 | 294 | function withdraw(uint256 boxId) public updateReward(msg.sender) { 295 | require(shitbox.ownerOf(boxId) == address(this)); 296 | require(_ownerOf(boxId) == msg.sender); 297 | 298 | uint256 miningPower = shitbox.getMiningPower(boxId); 299 | _totalMiningPower = _totalMiningPower.sub(miningPower); 300 | _balances[msg.sender] = _balances[msg.sender].sub(miningPower); 301 | shitbox.transferFrom(address(this), msg.sender, boxId); 302 | } 303 | 304 | function getReward() public updateReward(msg.sender) { 305 | uint256 reward = rewards[msg.sender]; 306 | if (reward > 0) { 307 | rewards[msg.sender] = 0; 308 | rewardsToken.safeTransfer(msg.sender, reward); 309 | } 310 | } 311 | 312 | function notifyRewardAmount(uint256 reward) external updateReward(address(0)) { 313 | if (block.timestamp >= periodFinish) { 314 | rewardRate = reward.div(rewardsDuration); 315 | } else { 316 | uint256 remaining = periodFinish.sub(block.timestamp); 317 | uint256 leftover = remaining.mul(rewardRate); 318 | rewardRate = reward.add(leftover).div(rewardsDuration); 319 | } 320 | 321 | // Ensure the provided reward amount is not more than the balance in the contract. 322 | // This keeps the reward rate in the right range, preventing overflows due to 323 | // very high values of rewardRate in the earned and rewardsPerToken functions; 324 | // Reward + leftover must be less than 2^256 / 10^18 to avoid overflow. 325 | uint balance = rewardsToken.balanceOf(address(this)); 326 | require(rewardRate <= balance.div(rewardsDuration), "Provided reward too high"); 327 | 328 | lastUpdateTime = block.timestamp; 329 | periodFinish = block.timestamp.add(rewardsDuration); 330 | } 331 | 332 | // End rewards emission earlier 333 | function updatePeriodFinish(uint timestamp) external onlyOwner updateReward(address(0)) { 334 | periodFinish = timestamp; 335 | } 336 | 337 | // Added to support recovering LP Rewards from other systems such as BAL to be distributed to holders 338 | function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyOwner { 339 | require(tokenAddress != address(stakingToken), "Cannot withdraw the staking token"); 340 | IERC20(tokenAddress).safeTransfer(owner, tokenAmount); 341 | } 342 | 343 | function setRewardsDuration(uint256 _rewardsDuration) external onlyOwner { 344 | require( 345 | block.timestamp > periodFinish, 346 | "Previous rewards period must be complete before changing the duration for the new period" 347 | ); 348 | rewardsDuration = _rewardsDuration; 349 | } 350 | 351 | modifier updateReward(address account) { 352 | rewardPerTokenStored = rewardPerToken(); 353 | lastUpdateTime = lastTimeRewardApplicable(); 354 | if (account != address(0)) { 355 | rewards[account] = earned(account); 356 | userRewardPerTokenPaid[account] = rewardPerTokenStored; 357 | } 358 | _; 359 | } 360 | } 361 | -------------------------------------------------------------------------------- /abi/shitbox.abi: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "inputs": [ 4 | { 5 | "internalType": "string", 6 | "name": "_name", 7 | "type": "string" 8 | }, 9 | { 10 | "internalType": "string", 11 | "name": "_symbol", 12 | "type": "string" 13 | } 14 | ], 15 | "stateMutability": "nonpayable", 16 | "type": "constructor" 17 | }, 18 | { 19 | "anonymous": false, 20 | "inputs": [ 21 | { 22 | "indexed": true, 23 | "internalType": "address", 24 | "name": "owner", 25 | "type": "address" 26 | }, 27 | { 28 | "indexed": true, 29 | "internalType": "address", 30 | "name": "approved", 31 | "type": "address" 32 | }, 33 | { 34 | "indexed": true, 35 | "internalType": "uint256", 36 | "name": "tokenId", 37 | "type": "uint256" 38 | } 39 | ], 40 | "name": "Approval", 41 | "type": "event" 42 | }, 43 | { 44 | "anonymous": false, 45 | "inputs": [ 46 | { 47 | "indexed": true, 48 | "internalType": "address", 49 | "name": "owner", 50 | "type": "address" 51 | }, 52 | { 53 | "indexed": true, 54 | "internalType": "address", 55 | "name": "operator", 56 | "type": "address" 57 | }, 58 | { 59 | "indexed": false, 60 | "internalType": "bool", 61 | "name": "approved", 62 | "type": "bool" 63 | } 64 | ], 65 | "name": "ApprovalForAll", 66 | "type": "event" 67 | }, 68 | { 69 | "anonymous": false, 70 | "inputs": [ 71 | { 72 | "indexed": true, 73 | "internalType": "address", 74 | "name": "from", 75 | "type": "address" 76 | }, 77 | { 78 | "indexed": true, 79 | "internalType": "address", 80 | "name": "to", 81 | "type": "address" 82 | }, 83 | { 84 | "indexed": true, 85 | "internalType": "uint256", 86 | "name": "tokenId", 87 | "type": "uint256" 88 | } 89 | ], 90 | "name": "Transfer", 91 | "type": "event" 92 | }, 93 | { 94 | "inputs": [ 95 | { 96 | "internalType": "address", 97 | "name": "to", 98 | "type": "address" 99 | }, 100 | { 101 | "internalType": "uint256", 102 | "name": "tokenId", 103 | "type": "uint256" 104 | } 105 | ], 106 | "name": "approve", 107 | "outputs": [], 108 | "stateMutability": "nonpayable", 109 | "type": "function" 110 | }, 111 | { 112 | "inputs": [ 113 | { 114 | "internalType": "address", 115 | "name": "owner", 116 | "type": "address" 117 | } 118 | ], 119 | "name": "balanceOf", 120 | "outputs": [ 121 | { 122 | "internalType": "uint256", 123 | "name": "", 124 | "type": "uint256" 125 | } 126 | ], 127 | "stateMutability": "view", 128 | "type": "function" 129 | }, 130 | { 131 | "inputs": [], 132 | "name": "baseURI", 133 | "outputs": [ 134 | { 135 | "internalType": "string", 136 | "name": "", 137 | "type": "string" 138 | } 139 | ], 140 | "stateMutability": "view", 141 | "type": "function" 142 | }, 143 | { 144 | "inputs": [ 145 | { 146 | "internalType": "uint256", 147 | "name": "", 148 | "type": "uint256" 149 | } 150 | ], 151 | "name": "boxes", 152 | "outputs": [ 153 | { 154 | "internalType": "uint256", 155 | "name": "id", 156 | "type": "uint256" 157 | }, 158 | { 159 | "internalType": "address", 160 | "name": "shiter", 161 | "type": "address" 162 | }, 163 | { 164 | "internalType": "address", 165 | "name": "tokenAddress", 166 | "type": "address" 167 | }, 168 | { 169 | "internalType": "uint256", 170 | "name": "amount", 171 | "type": "uint256" 172 | }, 173 | { 174 | "internalType": "uint256", 175 | "name": "initUSDValue", 176 | "type": "uint256" 177 | }, 178 | { 179 | "internalType": "uint256", 180 | "name": "quality", 181 | "type": "uint256" 182 | }, 183 | { 184 | "internalType": "uint256", 185 | "name": "bonusPower", 186 | "type": "uint256" 187 | }, 188 | { 189 | "internalType": "uint256", 190 | "name": "miningPower", 191 | "type": "uint256" 192 | }, 193 | { 194 | "internalType": "uint256", 195 | "name": "timestamp", 196 | "type": "uint256" 197 | } 198 | ], 199 | "stateMutability": "view", 200 | "type": "function" 201 | }, 202 | { 203 | "inputs": [], 204 | "name": "burnedCounter", 205 | "outputs": [ 206 | { 207 | "internalType": "uint256", 208 | "name": "", 209 | "type": "uint256" 210 | } 211 | ], 212 | "stateMutability": "view", 213 | "type": "function" 214 | }, 215 | { 216 | "inputs": [ 217 | { 218 | "internalType": "uint256", 219 | "name": "tokenId", 220 | "type": "uint256" 221 | } 222 | ], 223 | "name": "getApproved", 224 | "outputs": [ 225 | { 226 | "internalType": "address", 227 | "name": "", 228 | "type": "address" 229 | } 230 | ], 231 | "stateMutability": "view", 232 | "type": "function" 233 | }, 234 | { 235 | "inputs": [ 236 | { 237 | "internalType": "uint256", 238 | "name": "boxId", 239 | "type": "uint256" 240 | } 241 | ], 242 | "name": "getBoxBonusPower", 243 | "outputs": [ 244 | { 245 | "internalType": "uint256", 246 | "name": "", 247 | "type": "uint256" 248 | } 249 | ], 250 | "stateMutability": "view", 251 | "type": "function" 252 | }, 253 | { 254 | "inputs": [ 255 | { 256 | "internalType": "uint256", 257 | "name": "boxId", 258 | "type": "uint256" 259 | } 260 | ], 261 | "name": "getBoxInfo", 262 | "outputs": [ 263 | { 264 | "components": [ 265 | { 266 | "internalType": "uint256", 267 | "name": "id", 268 | "type": "uint256" 269 | }, 270 | { 271 | "internalType": "address", 272 | "name": "shiter", 273 | "type": "address" 274 | }, 275 | { 276 | "internalType": "address", 277 | "name": "tokenAddress", 278 | "type": "address" 279 | }, 280 | { 281 | "internalType": "uint256", 282 | "name": "amount", 283 | "type": "uint256" 284 | }, 285 | { 286 | "internalType": "uint256", 287 | "name": "initUSDValue", 288 | "type": "uint256" 289 | }, 290 | { 291 | "internalType": "uint256", 292 | "name": "quality", 293 | "type": "uint256" 294 | }, 295 | { 296 | "internalType": "uint256", 297 | "name": "bonusPower", 298 | "type": "uint256" 299 | }, 300 | { 301 | "internalType": "uint256", 302 | "name": "miningPower", 303 | "type": "uint256" 304 | }, 305 | { 306 | "internalType": "uint256", 307 | "name": "timestamp", 308 | "type": "uint256" 309 | } 310 | ], 311 | "internalType": "struct ShitBox.Box", 312 | "name": "", 313 | "type": "tuple" 314 | } 315 | ], 316 | "stateMutability": "view", 317 | "type": "function" 318 | }, 319 | { 320 | "inputs": [ 321 | { 322 | "internalType": "uint256", 323 | "name": "boxId", 324 | "type": "uint256" 325 | } 326 | ], 327 | "name": "getBoxQuality", 328 | "outputs": [ 329 | { 330 | "internalType": "uint256", 331 | "name": "", 332 | "type": "uint256" 333 | } 334 | ], 335 | "stateMutability": "view", 336 | "type": "function" 337 | }, 338 | { 339 | "inputs": [ 340 | { 341 | "internalType": "uint256", 342 | "name": "boxId", 343 | "type": "uint256" 344 | } 345 | ], 346 | "name": "getBoxTimestamp", 347 | "outputs": [ 348 | { 349 | "internalType": "uint256", 350 | "name": "", 351 | "type": "uint256" 352 | } 353 | ], 354 | "stateMutability": "view", 355 | "type": "function" 356 | }, 357 | { 358 | "inputs": [ 359 | { 360 | "internalType": "uint256", 361 | "name": "boxId", 362 | "type": "uint256" 363 | } 364 | ], 365 | "name": "getBoxToken", 366 | "outputs": [ 367 | { 368 | "internalType": "address", 369 | "name": "", 370 | "type": "address" 371 | } 372 | ], 373 | "stateMutability": "view", 374 | "type": "function" 375 | }, 376 | { 377 | "inputs": [ 378 | { 379 | "internalType": "uint256", 380 | "name": "boxId", 381 | "type": "uint256" 382 | } 383 | ], 384 | "name": "getBoxTokenAmount", 385 | "outputs": [ 386 | { 387 | "internalType": "uint256", 388 | "name": "", 389 | "type": "uint256" 390 | } 391 | ], 392 | "stateMutability": "view", 393 | "type": "function" 394 | }, 395 | { 396 | "inputs": [ 397 | { 398 | "internalType": "uint256", 399 | "name": "boxId", 400 | "type": "uint256" 401 | } 402 | ], 403 | "name": "getBoxTokenUSDValue", 404 | "outputs": [ 405 | { 406 | "internalType": "uint256", 407 | "name": "", 408 | "type": "uint256" 409 | } 410 | ], 411 | "stateMutability": "view", 412 | "type": "function" 413 | }, 414 | { 415 | "inputs": [ 416 | { 417 | "internalType": "uint256", 418 | "name": "boxId", 419 | "type": "uint256" 420 | } 421 | ], 422 | "name": "getMiningPower", 423 | "outputs": [ 424 | { 425 | "internalType": "uint256", 426 | "name": "", 427 | "type": "uint256" 428 | } 429 | ], 430 | "stateMutability": "view", 431 | "type": "function" 432 | }, 433 | { 434 | "inputs": [ 435 | { 436 | "internalType": "address", 437 | "name": "owner", 438 | "type": "address" 439 | }, 440 | { 441 | "internalType": "address", 442 | "name": "operator", 443 | "type": "address" 444 | } 445 | ], 446 | "name": "isApprovedForAll", 447 | "outputs": [ 448 | { 449 | "internalType": "bool", 450 | "name": "", 451 | "type": "bool" 452 | } 453 | ], 454 | "stateMutability": "view", 455 | "type": "function" 456 | }, 457 | { 458 | "inputs": [ 459 | { 460 | "internalType": "address", 461 | "name": "tokenAddress", 462 | "type": "address" 463 | }, 464 | { 465 | "internalType": "uint256", 466 | "name": "amount", 467 | "type": "uint256" 468 | } 469 | ], 470 | "name": "mintShitBox", 471 | "outputs": [], 472 | "stateMutability": "nonpayable", 473 | "type": "function" 474 | }, 475 | { 476 | "inputs": [], 477 | "name": "name", 478 | "outputs": [ 479 | { 480 | "internalType": "string", 481 | "name": "", 482 | "type": "string" 483 | } 484 | ], 485 | "stateMutability": "view", 486 | "type": "function" 487 | }, 488 | { 489 | "inputs": [ 490 | { 491 | "internalType": "uint256", 492 | "name": "tokenId", 493 | "type": "uint256" 494 | } 495 | ], 496 | "name": "ownerOf", 497 | "outputs": [ 498 | { 499 | "internalType": "address", 500 | "name": "", 501 | "type": "address" 502 | } 503 | ], 504 | "stateMutability": "view", 505 | "type": "function" 506 | }, 507 | { 508 | "inputs": [], 509 | "name": "pancakeRouterAddr", 510 | "outputs": [ 511 | { 512 | "internalType": "address", 513 | "name": "", 514 | "type": "address" 515 | } 516 | ], 517 | "stateMutability": "view", 518 | "type": "function" 519 | }, 520 | { 521 | "inputs": [ 522 | { 523 | "internalType": "address", 524 | "name": "from", 525 | "type": "address" 526 | }, 527 | { 528 | "internalType": "address", 529 | "name": "to", 530 | "type": "address" 531 | }, 532 | { 533 | "internalType": "uint256", 534 | "name": "tokenId", 535 | "type": "uint256" 536 | } 537 | ], 538 | "name": "safeTransferFrom", 539 | "outputs": [], 540 | "stateMutability": "nonpayable", 541 | "type": "function" 542 | }, 543 | { 544 | "inputs": [ 545 | { 546 | "internalType": "address", 547 | "name": "from", 548 | "type": "address" 549 | }, 550 | { 551 | "internalType": "address", 552 | "name": "to", 553 | "type": "address" 554 | }, 555 | { 556 | "internalType": "uint256", 557 | "name": "tokenId", 558 | "type": "uint256" 559 | }, 560 | { 561 | "internalType": "bytes", 562 | "name": "_data", 563 | "type": "bytes" 564 | } 565 | ], 566 | "name": "safeTransferFrom", 567 | "outputs": [], 568 | "stateMutability": "nonpayable", 569 | "type": "function" 570 | }, 571 | { 572 | "inputs": [ 573 | { 574 | "internalType": "address", 575 | "name": "operator", 576 | "type": "address" 577 | }, 578 | { 579 | "internalType": "bool", 580 | "name": "approved", 581 | "type": "bool" 582 | } 583 | ], 584 | "name": "setApprovalForAll", 585 | "outputs": [], 586 | "stateMutability": "nonpayable", 587 | "type": "function" 588 | }, 589 | { 590 | "inputs": [], 591 | "name": "shitAddress", 592 | "outputs": [ 593 | { 594 | "internalType": "address", 595 | "name": "", 596 | "type": "address" 597 | } 598 | ], 599 | "stateMutability": "view", 600 | "type": "function" 601 | }, 602 | { 603 | "inputs": [ 604 | { 605 | "internalType": "address", 606 | "name": "tokenAddress", 607 | "type": "address" 608 | } 609 | ], 610 | "name": "skim", 611 | "outputs": [], 612 | "stateMutability": "nonpayable", 613 | "type": "function" 614 | }, 615 | { 616 | "inputs": [ 617 | { 618 | "internalType": "bytes4", 619 | "name": "interfaceId", 620 | "type": "bytes4" 621 | } 622 | ], 623 | "name": "supportsInterface", 624 | "outputs": [ 625 | { 626 | "internalType": "bool", 627 | "name": "", 628 | "type": "bool" 629 | } 630 | ], 631 | "stateMutability": "view", 632 | "type": "function" 633 | }, 634 | { 635 | "inputs": [], 636 | "name": "symbol", 637 | "outputs": [ 638 | { 639 | "internalType": "string", 640 | "name": "", 641 | "type": "string" 642 | } 643 | ], 644 | "stateMutability": "view", 645 | "type": "function" 646 | }, 647 | { 648 | "inputs": [ 649 | { 650 | "internalType": "uint256", 651 | "name": "index", 652 | "type": "uint256" 653 | } 654 | ], 655 | "name": "tokenByIndex", 656 | "outputs": [ 657 | { 658 | "internalType": "uint256", 659 | "name": "", 660 | "type": "uint256" 661 | } 662 | ], 663 | "stateMutability": "view", 664 | "type": "function" 665 | }, 666 | { 667 | "inputs": [ 668 | { 669 | "internalType": "address", 670 | "name": "owner", 671 | "type": "address" 672 | }, 673 | { 674 | "internalType": "uint256", 675 | "name": "index", 676 | "type": "uint256" 677 | } 678 | ], 679 | "name": "tokenOfOwnerByIndex", 680 | "outputs": [ 681 | { 682 | "internalType": "uint256", 683 | "name": "", 684 | "type": "uint256" 685 | } 686 | ], 687 | "stateMutability": "view", 688 | "type": "function" 689 | }, 690 | { 691 | "inputs": [ 692 | { 693 | "internalType": "uint256", 694 | "name": "tokenId", 695 | "type": "uint256" 696 | } 697 | ], 698 | "name": "tokenURI", 699 | "outputs": [ 700 | { 701 | "internalType": "string", 702 | "name": "", 703 | "type": "string" 704 | } 705 | ], 706 | "stateMutability": "view", 707 | "type": "function" 708 | }, 709 | { 710 | "inputs": [ 711 | { 712 | "internalType": "address", 713 | "name": "_owner", 714 | "type": "address" 715 | } 716 | ], 717 | "name": "tokensOfOwner", 718 | "outputs": [ 719 | { 720 | "internalType": "uint256[]", 721 | "name": "ownerTokens", 722 | "type": "uint256[]" 723 | } 724 | ], 725 | "stateMutability": "view", 726 | "type": "function" 727 | }, 728 | { 729 | "inputs": [], 730 | "name": "totalSupply", 731 | "outputs": [ 732 | { 733 | "internalType": "uint256", 734 | "name": "", 735 | "type": "uint256" 736 | } 737 | ], 738 | "stateMutability": "view", 739 | "type": "function" 740 | }, 741 | { 742 | "inputs": [ 743 | { 744 | "internalType": "address", 745 | "name": "from", 746 | "type": "address" 747 | }, 748 | { 749 | "internalType": "address", 750 | "name": "to", 751 | "type": "address" 752 | }, 753 | { 754 | "internalType": "uint256", 755 | "name": "tokenId", 756 | "type": "uint256" 757 | } 758 | ], 759 | "name": "transferFrom", 760 | "outputs": [], 761 | "stateMutability": "nonpayable", 762 | "type": "function" 763 | }, 764 | { 765 | "inputs": [], 766 | "name": "upgradePrice", 767 | "outputs": [ 768 | { 769 | "internalType": "uint256", 770 | "name": "", 771 | "type": "uint256" 772 | } 773 | ], 774 | "stateMutability": "view", 775 | "type": "function" 776 | }, 777 | { 778 | "inputs": [ 779 | { 780 | "internalType": "uint256", 781 | "name": "boxId", 782 | "type": "uint256" 783 | } 784 | ], 785 | "name": "upgradeShitBox", 786 | "outputs": [], 787 | "stateMutability": "nonpayable", 788 | "type": "function" 789 | }, 790 | { 791 | "inputs": [], 792 | "name": "usdtAddress", 793 | "outputs": [ 794 | { 795 | "internalType": "address", 796 | "name": "", 797 | "type": "address" 798 | } 799 | ], 800 | "stateMutability": "view", 801 | "type": "function" 802 | }, 803 | { 804 | "inputs": [], 805 | "name": "vrfAddr", 806 | "outputs": [ 807 | { 808 | "internalType": "address", 809 | "name": "", 810 | "type": "address" 811 | } 812 | ], 813 | "stateMutability": "view", 814 | "type": "function" 815 | } 816 | ] -------------------------------------------------------------------------------- /verifyContract/shit.sol: -------------------------------------------------------------------------------- 1 | // SPDX-License-Identifier: MIT 2 | 3 | pragma solidity ^0.6.2; 4 | 5 | abstract contract Context { 6 | function _msgSender() internal view virtual returns (address payable) { 7 | return msg.sender; 8 | } 9 | 10 | function _msgData() internal view virtual returns (bytes memory) { 11 | this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 12 | return msg.data; 13 | } 14 | } 15 | 16 | interface IERC20 { 17 | /** 18 | * @dev Returns the amount of tokens in existence. 19 | */ 20 | function totalSupply() external view returns (uint256); 21 | 22 | /** 23 | * @dev Returns the amount of tokens owned by `account`. 24 | */ 25 | function balanceOf(address account) external view returns (uint256); 26 | 27 | /** 28 | * @dev Moves `amount` tokens from the caller's account to `recipient`. 29 | * 30 | * Returns a boolean value indicating whether the operation succeeded. 31 | * 32 | * Emits a {Transfer} event. 33 | */ 34 | function transfer(address recipient, uint256 amount) external returns (bool); 35 | 36 | /** 37 | * @dev Returns the remaining number of tokens that `spender` will be 38 | * allowed to spend on behalf of `owner` through {transferFrom}. This is 39 | * zero by default. 40 | * 41 | * This value changes when {approve} or {transferFrom} are called. 42 | */ 43 | function allowance(address owner, address spender) external view returns (uint256); 44 | 45 | /** 46 | * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. 47 | * 48 | * Returns a boolean value indicating whether the operation succeeded. 49 | * 50 | * IMPORTANT: Beware that changing an allowance with this method brings the risk 51 | * that someone may use both the old and the new allowance by unfortunate 52 | * transaction ordering. One possible solution to mitigate this race 53 | * condition is to first reduce the spender's allowance to 0 and set the 54 | * desired value afterwards: 55 | * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 56 | * 57 | * Emits an {Approval} event. 58 | */ 59 | function approve(address spender, uint256 amount) external returns (bool); 60 | 61 | /** 62 | * @dev Moves `amount` tokens from `sender` to `recipient` using the 63 | * allowance mechanism. `amount` is then deducted from the caller's 64 | * allowance. 65 | * 66 | * Returns a boolean value indicating whether the operation succeeded. 67 | * 68 | * Emits a {Transfer} event. 69 | */ 70 | function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); 71 | 72 | /** 73 | * @dev Emitted when `value` tokens are moved from one account (`from`) to 74 | * another (`to`). 75 | * 76 | * Note that `value` may be zero. 77 | */ 78 | event Transfer(address indexed from, address indexed to, uint256 value); 79 | 80 | /** 81 | * @dev Emitted when the allowance of a `spender` for an `owner` is set by 82 | * a call to {approve}. `value` is the new allowance. 83 | */ 84 | event Approval(address indexed owner, address indexed spender, uint256 value); 85 | } 86 | library SafeMath { 87 | /** 88 | * @dev Returns the addition of two unsigned integers, reverting on 89 | * overflow. 90 | * 91 | * Counterpart to Solidity's `+` operator. 92 | * 93 | * Requirements: 94 | * 95 | * - Addition cannot overflow. 96 | */ 97 | function add(uint256 a, uint256 b) internal pure returns (uint256) { 98 | uint256 c = a + b; 99 | require(c >= a, "SafeMath: addition overflow"); 100 | 101 | return c; 102 | } 103 | 104 | /** 105 | * @dev Returns the subtraction of two unsigned integers, reverting on 106 | * overflow (when the result is negative). 107 | * 108 | * Counterpart to Solidity's `-` operator. 109 | * 110 | * Requirements: 111 | * 112 | * - Subtraction cannot overflow. 113 | */ 114 | function sub(uint256 a, uint256 b) internal pure returns (uint256) { 115 | return sub(a, b, "SafeMath: subtraction overflow"); 116 | } 117 | 118 | /** 119 | * @dev Returns the subtraction of two unsigned integers, reverting with custom message on 120 | * overflow (when the result is negative). 121 | * 122 | * Counterpart to Solidity's `-` operator. 123 | * 124 | * Requirements: 125 | * 126 | * - Subtraction cannot overflow. 127 | */ 128 | function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 129 | require(b <= a, errorMessage); 130 | uint256 c = a - b; 131 | 132 | return c; 133 | } 134 | 135 | /** 136 | * @dev Returns the multiplication of two unsigned integers, reverting on 137 | * overflow. 138 | * 139 | * Counterpart to Solidity's `*` operator. 140 | * 141 | * Requirements: 142 | * 143 | * - Multiplication cannot overflow. 144 | */ 145 | function mul(uint256 a, uint256 b) internal pure returns (uint256) { 146 | // Gas optimization: this is cheaper than requiring 'a' not being zero, but the 147 | // benefit is lost if 'b' is also tested. 148 | // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 149 | if (a == 0) { 150 | return 0; 151 | } 152 | 153 | uint256 c = a * b; 154 | require(c / a == b, "SafeMath: multiplication overflow"); 155 | 156 | return c; 157 | } 158 | 159 | /** 160 | * @dev Returns the integer division of two unsigned integers. Reverts on 161 | * division by zero. The result is rounded towards zero. 162 | * 163 | * Counterpart to Solidity's `/` operator. Note: this function uses a 164 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 165 | * uses an invalid opcode to revert (consuming all remaining gas). 166 | * 167 | * Requirements: 168 | * 169 | * - The divisor cannot be zero. 170 | */ 171 | function div(uint256 a, uint256 b) internal pure returns (uint256) { 172 | return div(a, b, "SafeMath: division by zero"); 173 | } 174 | 175 | /** 176 | * @dev Returns the integer division of two unsigned integers. Reverts with custom message on 177 | * division by zero. The result is rounded towards zero. 178 | * 179 | * Counterpart to Solidity's `/` operator. Note: this function uses a 180 | * `revert` opcode (which leaves remaining gas untouched) while Solidity 181 | * uses an invalid opcode to revert (consuming all remaining gas). 182 | * 183 | * Requirements: 184 | * 185 | * - The divisor cannot be zero. 186 | */ 187 | function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 188 | require(b > 0, errorMessage); 189 | uint256 c = a / b; 190 | // assert(a == b * c + a % b); // There is no case in which this doesn't hold 191 | 192 | return c; 193 | } 194 | 195 | /** 196 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 197 | * Reverts when dividing by zero. 198 | * 199 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 200 | * opcode (which leaves remaining gas untouched) while Solidity uses an 201 | * invalid opcode to revert (consuming all remaining gas). 202 | * 203 | * Requirements: 204 | * 205 | * - The divisor cannot be zero. 206 | */ 207 | function mod(uint256 a, uint256 b) internal pure returns (uint256) { 208 | return mod(a, b, "SafeMath: modulo by zero"); 209 | } 210 | 211 | /** 212 | * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), 213 | * Reverts with custom message when dividing by zero. 214 | * 215 | * Counterpart to Solidity's `%` operator. This function uses a `revert` 216 | * opcode (which leaves remaining gas untouched) while Solidity uses an 217 | * invalid opcode to revert (consuming all remaining gas). 218 | * 219 | * Requirements: 220 | * 221 | * - The divisor cannot be zero. 222 | */ 223 | function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { 224 | require(b != 0, errorMessage); 225 | return a % b; 226 | } 227 | } 228 | 229 | contract ERC20 is Context, IERC20 { 230 | using SafeMath for uint256; 231 | 232 | mapping (address => uint256) private _balances; 233 | 234 | mapping (address => mapping (address => uint256)) private _allowances; 235 | 236 | uint256 private _totalSupply; 237 | 238 | string private _name; 239 | string private _symbol; 240 | uint8 private _decimals; 241 | 242 | /** 243 | * @dev Sets the values for {name} and {symbol}, initializes {decimals} with 244 | * a default value of 18. 245 | * 246 | * To select a different value for {decimals}, use {_setupDecimals}. 247 | * 248 | * All three of these values are immutable: they can only be set once during 249 | * construction. 250 | */ 251 | constructor (string memory name_, string memory symbol_) public { 252 | _name = name_; 253 | _symbol = symbol_; 254 | _decimals = 18; 255 | } 256 | 257 | /** 258 | * @dev Returns the name of the token. 259 | */ 260 | function name() public view returns (string memory) { 261 | return _name; 262 | } 263 | 264 | /** 265 | * @dev Returns the symbol of the token, usually a shorter version of the 266 | * name. 267 | */ 268 | function symbol() public view returns (string memory) { 269 | return _symbol; 270 | } 271 | 272 | /** 273 | * @dev Returns the number of decimals used to get its user representation. 274 | * For example, if `decimals` equals `2`, a balance of `505` tokens should 275 | * be displayed to a user as `5,05` (`505 / 10 ** 2`). 276 | * 277 | * Tokens usually opt for a value of 18, imitating the relationship between 278 | * Ether and Wei. This is the value {ERC20} uses, unless {_setupDecimals} is 279 | * called. 280 | * 281 | * NOTE: This information is only used for _display_ purposes: it in 282 | * no way affects any of the arithmetic of the contract, including 283 | * {IERC20-balanceOf} and {IERC20-transfer}. 284 | */ 285 | function decimals() public view returns (uint8) { 286 | return _decimals; 287 | } 288 | 289 | /** 290 | * @dev See {IERC20-totalSupply}. 291 | */ 292 | function totalSupply() public view override returns (uint256) { 293 | return _totalSupply; 294 | } 295 | 296 | /** 297 | * @dev See {IERC20-balanceOf}. 298 | */ 299 | function balanceOf(address account) public view override returns (uint256) { 300 | return _balances[account]; 301 | } 302 | 303 | /** 304 | * @dev See {IERC20-transfer}. 305 | * 306 | * Requirements: 307 | * 308 | * - `recipient` cannot be the zero address. 309 | * - the caller must have a balance of at least `amount`. 310 | */ 311 | function transfer(address recipient, uint256 amount) public virtual override returns (bool) { 312 | _transfer(_msgSender(), recipient, amount); 313 | return true; 314 | } 315 | 316 | /** 317 | * @dev See {IERC20-allowance}. 318 | */ 319 | function allowance(address owner, address spender) public view virtual override returns (uint256) { 320 | return _allowances[owner][spender]; 321 | } 322 | 323 | /** 324 | * @dev See {IERC20-approve}. 325 | * 326 | * Requirements: 327 | * 328 | * - `spender` cannot be the zero address. 329 | */ 330 | function approve(address spender, uint256 amount) public virtual override returns (bool) { 331 | _approve(_msgSender(), spender, amount); 332 | return true; 333 | } 334 | 335 | /** 336 | * @dev See {IERC20-transferFrom}. 337 | * 338 | * Emits an {Approval} event indicating the updated allowance. This is not 339 | * required by the EIP. See the note at the beginning of {ERC20}. 340 | * 341 | * Requirements: 342 | * 343 | * - `sender` and `recipient` cannot be the zero address. 344 | * - `sender` must have a balance of at least `amount`. 345 | * - the caller must have allowance for ``sender``'s tokens of at least 346 | * `amount`. 347 | */ 348 | function transferFrom(address sender, address recipient, uint256 amount) public virtual override returns (bool) { 349 | _transfer(sender, recipient, amount); 350 | _approve(sender, _msgSender(), _allowances[sender][_msgSender()].sub(amount, "ERC20: transfer amount exceeds allowance")); 351 | return true; 352 | } 353 | 354 | /** 355 | * @dev Atomically increases the allowance granted to `spender` by the caller. 356 | * 357 | * This is an alternative to {approve} that can be used as a mitigation for 358 | * problems described in {IERC20-approve}. 359 | * 360 | * Emits an {Approval} event indicating the updated allowance. 361 | * 362 | * Requirements: 363 | * 364 | * - `spender` cannot be the zero address. 365 | */ 366 | function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { 367 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].add(addedValue)); 368 | return true; 369 | } 370 | 371 | /** 372 | * @dev Atomically decreases the allowance granted to `spender` by the caller. 373 | * 374 | * This is an alternative to {approve} that can be used as a mitigation for 375 | * problems described in {IERC20-approve}. 376 | * 377 | * Emits an {Approval} event indicating the updated allowance. 378 | * 379 | * Requirements: 380 | * 381 | * - `spender` cannot be the zero address. 382 | * - `spender` must have allowance for the caller of at least 383 | * `subtractedValue`. 384 | */ 385 | function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { 386 | _approve(_msgSender(), spender, _allowances[_msgSender()][spender].sub(subtractedValue, "ERC20: decreased allowance below zero")); 387 | return true; 388 | } 389 | 390 | /** 391 | * @dev Moves tokens `amount` from `sender` to `recipient`. 392 | * 393 | * This is internal function is equivalent to {transfer}, and can be used to 394 | * e.g. implement automatic token fees, slashing mechanisms, etc. 395 | * 396 | * Emits a {Transfer} event. 397 | * 398 | * Requirements: 399 | * 400 | * - `sender` cannot be the zero address. 401 | * - `recipient` cannot be the zero address. 402 | * - `sender` must have a balance of at least `amount`. 403 | */ 404 | function _transfer(address sender, address recipient, uint256 amount) internal virtual { 405 | require(sender != address(0), "ERC20: transfer from the zero address"); 406 | require(recipient != address(0), "ERC20: transfer to the zero address"); 407 | 408 | _beforeTokenTransfer(sender, recipient, amount); 409 | 410 | _balances[sender] = _balances[sender].sub(amount, "ERC20: transfer amount exceeds balance"); 411 | _balances[recipient] = _balances[recipient].add(amount); 412 | emit Transfer(sender, recipient, amount); 413 | } 414 | 415 | /** @dev Creates `amount` tokens and assigns them to `account`, increasing 416 | * the total supply. 417 | * 418 | * Emits a {Transfer} event with `from` set to the zero address. 419 | * 420 | * Requirements: 421 | * 422 | * - `to` cannot be the zero address. 423 | */ 424 | function _mint(address account, uint256 amount) internal virtual { 425 | require(account != address(0), "ERC20: mint to the zero address"); 426 | 427 | _beforeTokenTransfer(address(0), account, amount); 428 | 429 | _totalSupply = _totalSupply.add(amount); 430 | _balances[account] = _balances[account].add(amount); 431 | emit Transfer(address(0), account, amount); 432 | } 433 | 434 | /** 435 | * @dev Destroys `amount` tokens from `account`, reducing the 436 | * total supply. 437 | * 438 | * Emits a {Transfer} event with `to` set to the zero address. 439 | * 440 | * Requirements: 441 | * 442 | * - `account` cannot be the zero address. 443 | * - `account` must have at least `amount` tokens. 444 | */ 445 | function _burn(address account, uint256 amount) internal virtual { 446 | require(account != address(0), "ERC20: burn from the zero address"); 447 | 448 | _beforeTokenTransfer(account, address(0), amount); 449 | 450 | _balances[account] = _balances[account].sub(amount, "ERC20: burn amount exceeds balance"); 451 | _totalSupply = _totalSupply.sub(amount); 452 | emit Transfer(account, address(0), amount); 453 | } 454 | 455 | /** 456 | * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. 457 | * 458 | * This internal function is equivalent to `approve`, and can be used to 459 | * e.g. set automatic allowances for certain subsystems, etc. 460 | * 461 | * Emits an {Approval} event. 462 | * 463 | * Requirements: 464 | * 465 | * - `owner` cannot be the zero address. 466 | * - `spender` cannot be the zero address. 467 | */ 468 | function _approve(address owner, address spender, uint256 amount) internal virtual { 469 | require(owner != address(0), "ERC20: approve from the zero address"); 470 | require(spender != address(0), "ERC20: approve to the zero address"); 471 | 472 | _allowances[owner][spender] = amount; 473 | emit Approval(owner, spender, amount); 474 | } 475 | 476 | /** 477 | * @dev Sets {decimals} to a value other than the default one of 18. 478 | * 479 | * WARNING: This function should only be called from the constructor. Most 480 | * applications that interact with token contracts will not expect 481 | * {decimals} to ever change, and may work incorrectly if it does. 482 | */ 483 | function _setupDecimals(uint8 decimals_) internal { 484 | _decimals = decimals_; 485 | } 486 | 487 | /** 488 | * @dev Hook that is called before any transfer of tokens. This includes 489 | * minting and burning. 490 | * 491 | * Calling conditions: 492 | * 493 | * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens 494 | * will be to transferred to `to`. 495 | * - when `from` is zero, `amount` tokens will be minted for `to`. 496 | * - when `to` is zero, `amount` of ``from``'s tokens will be burned. 497 | * - `from` and `to` are never both zero. 498 | * 499 | * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. 500 | */ 501 | function _beforeTokenTransfer(address from, address to, uint256 amount) internal virtual { } 502 | } 503 | 504 | library Address { 505 | /** 506 | * @dev Returns true if `account` is a contract. 507 | * 508 | * [IMPORTANT] 509 | * ==== 510 | * It is unsafe to assume that an address for which this function returns 511 | * false is an externally-owned account (EOA) and not a contract. 512 | * 513 | * Among others, `isContract` will return false for the following 514 | * types of addresses: 515 | * 516 | * - an externally-owned account 517 | * - a contract in construction 518 | * - an address where a contract will be created 519 | * - an address where a contract lived, but was destroyed 520 | * ==== 521 | */ 522 | function isContract(address account) internal view returns (bool) { 523 | // This method relies on extcodesize, which returns 0 for contracts in 524 | // construction, since the code is only stored at the end of the 525 | // constructor execution. 526 | 527 | uint256 size; 528 | // solhint-disable-next-line no-inline-assembly 529 | assembly { size := extcodesize(account) } 530 | return size > 0; 531 | } 532 | 533 | /** 534 | * @dev Replacement for Solidity's `transfer`: sends `amount` wei to 535 | * `recipient`, forwarding all available gas and reverting on errors. 536 | * 537 | * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost 538 | * of certain opcodes, possibly making contracts go over the 2300 gas limit 539 | * imposed by `transfer`, making them unable to receive funds via 540 | * `transfer`. {sendValue} removes this limitation. 541 | * 542 | * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. 543 | * 544 | * IMPORTANT: because control is transferred to `recipient`, care must be 545 | * taken to not create reentrancy vulnerabilities. Consider using 546 | * {ReentrancyGuard} or the 547 | * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. 548 | */ 549 | function sendValue(address payable recipient, uint256 amount) internal { 550 | require(address(this).balance >= amount, "Address: insufficient balance"); 551 | 552 | // solhint-disable-next-line avoid-low-level-calls, avoid-call-value 553 | (bool success, ) = recipient.call{ value: amount }(""); 554 | require(success, "Address: unable to send value, recipient may have reverted"); 555 | } 556 | 557 | /** 558 | * @dev Performs a Solidity function call using a low level `call`. A 559 | * plain`call` is an unsafe replacement for a function call: use this 560 | * function instead. 561 | * 562 | * If `target` reverts with a revert reason, it is bubbled up by this 563 | * function (like regular Solidity function calls). 564 | * 565 | * Returns the raw returned data. To convert to the expected return value, 566 | * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. 567 | * 568 | * Requirements: 569 | * 570 | * - `target` must be a contract. 571 | * - calling `target` with `data` must not revert. 572 | * 573 | * _Available since v3.1._ 574 | */ 575 | function functionCall(address target, bytes memory data) internal returns (bytes memory) { 576 | return functionCall(target, data, "Address: low-level call failed"); 577 | } 578 | 579 | /** 580 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with 581 | * `errorMessage` as a fallback revert reason when `target` reverts. 582 | * 583 | * _Available since v3.1._ 584 | */ 585 | function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { 586 | return functionCallWithValue(target, data, 0, errorMessage); 587 | } 588 | 589 | /** 590 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 591 | * but also transferring `value` wei to `target`. 592 | * 593 | * Requirements: 594 | * 595 | * - the calling contract must have an ETH balance of at least `value`. 596 | * - the called Solidity function must be `payable`. 597 | * 598 | * _Available since v3.1._ 599 | */ 600 | function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { 601 | return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); 602 | } 603 | 604 | /** 605 | * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but 606 | * with `errorMessage` as a fallback revert reason when `target` reverts. 607 | * 608 | * _Available since v3.1._ 609 | */ 610 | function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { 611 | require(address(this).balance >= value, "Address: insufficient balance for call"); 612 | require(isContract(target), "Address: call to non-contract"); 613 | 614 | // solhint-disable-next-line avoid-low-level-calls 615 | (bool success, bytes memory returndata) = target.call{ value: value }(data); 616 | return _verifyCallResult(success, returndata, errorMessage); 617 | } 618 | 619 | /** 620 | * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], 621 | * but performing a static call. 622 | * 623 | * _Available since v3.3._ 624 | */ 625 | function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { 626 | return functionStaticCall(target, data, "Address: low-level static call failed"); 627 | } 628 | 629 | /** 630 | * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], 631 | * but performing a static call. 632 | * 633 | * _Available since v3.3._ 634 | */ 635 | function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { 636 | require(isContract(target), "Address: static call to non-contract"); 637 | 638 | // solhint-disable-next-line avoid-low-level-calls 639 | (bool success, bytes memory returndata) = target.staticcall(data); 640 | return _verifyCallResult(success, returndata, errorMessage); 641 | } 642 | 643 | function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { 644 | if (success) { 645 | return returndata; 646 | } else { 647 | // Look for revert reason and bubble it up if present 648 | if (returndata.length > 0) { 649 | // The easiest way to bubble the revert reason is using memory via assembly 650 | 651 | // solhint-disable-next-line no-inline-assembly 652 | assembly { 653 | let returndata_size := mload(returndata) 654 | revert(add(32, returndata), returndata_size) 655 | } 656 | } else { 657 | revert(errorMessage); 658 | } 659 | } 660 | } 661 | } 662 | 663 | contract Shit is ERC20{ 664 | 665 | using Address for address; 666 | 667 | address public governance; 668 | mapping (address => bool) public shitTokens; 669 | mapping (address => address) public bridges; 670 | 671 | address[] public shitTokenList; 672 | 673 | uint256[] public rangeValue = [1, 10, 100, 1000, 10000, 100000]; 674 | 675 | constructor() public ERC20("ShitPlanet","SHIT"){ 676 | governance = tx.origin; 677 | _mint(msg.sender, 100000000000000000000000000); 678 | } 679 | 680 | function addShitToken(address tokenAddress, address bridge) public { 681 | require(msg.sender == governance, "!governance"); 682 | shitTokens[tokenAddress] = true; 683 | bridges[tokenAddress] = bridge; 684 | shitTokenList.push(tokenAddress); 685 | } 686 | 687 | function getShitTokenList() public view returns(address[] memory) { 688 | return shitTokenList; 689 | } 690 | 691 | function getBridgeToken(address tokenAddress) public view returns(address) { 692 | return bridges[tokenAddress]; 693 | } 694 | 695 | function removeShitToken(address tokenAddress) public { 696 | require(msg.sender == governance, "!governance"); 697 | shitTokens[tokenAddress] = false; 698 | bridges[tokenAddress] = address(0); 699 | } 700 | 701 | function isShitToken(address tokenAddress) public view returns (bool) { 702 | return shitTokens[tokenAddress]; 703 | } 704 | 705 | function setGovernance(address _governance) public { 706 | require(msg.sender == governance, "!governance"); 707 | governance = _governance; 708 | } 709 | 710 | function getRange() public view returns (uint[] memory){ 711 | return rangeValue; 712 | } 713 | } --------------------------------------------------------------------------------