文件 1 的 9:Context.sol
pragma solidity ^0.8.0;
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
文件 2 的 9:EnumerableSet.sol
pragma solidity ^0.8.0;
library EnumerableSet {
struct Set {
bytes32[] _values;
mapping (bytes32 => uint) _indexes;
}
struct Bytes32Set {
Set _inner;
}
struct AddressSet {
Set _inner;
}
struct UintSet {
Set _inner;
}
function at (
Bytes32Set storage set,
uint index
) internal view returns (bytes32) {
return _at(set._inner, index);
}
function at (
AddressSet storage set,
uint index
) internal view returns (address) {
return address(uint160(uint(_at(set._inner, index))));
}
function at (
UintSet storage set,
uint index
) internal view returns (uint) {
return uint(_at(set._inner, index));
}
function contains (
Bytes32Set storage set,
bytes32 value
) internal view returns (bool) {
return _contains(set._inner, value);
}
function contains (
AddressSet storage set,
address value
) internal view returns (bool) {
return _contains(set._inner, bytes32(uint(uint160(value))));
}
function contains (
UintSet storage set,
uint value
) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
function indexOf (
Bytes32Set storage set,
bytes32 value
) internal view returns (uint) {
return _indexOf(set._inner, value);
}
function indexOf (
AddressSet storage set,
address value
) internal view returns (uint) {
return _indexOf(set._inner, bytes32(uint(uint160(value))));
}
function indexOf (
UintSet storage set,
uint value
) internal view returns (uint) {
return _indexOf(set._inner, bytes32(value));
}
function length (
Bytes32Set storage set
) internal view returns (uint) {
return _length(set._inner);
}
function length (
AddressSet storage set
) internal view returns (uint) {
return _length(set._inner);
}
function length (
UintSet storage set
) internal view returns (uint) {
return _length(set._inner);
}
function add (
Bytes32Set storage set,
bytes32 value
) internal returns (bool) {
return _add(set._inner, value);
}
function add (
AddressSet storage set,
address value
) internal returns (bool) {
return _add(set._inner, bytes32(uint(uint160(value))));
}
function add (
UintSet storage set,
uint value
) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
function remove (
Bytes32Set storage set,
bytes32 value
) internal returns (bool) {
return _remove(set._inner, value);
}
function remove (
AddressSet storage set,
address value
) internal returns (bool) {
return _remove(set._inner, bytes32(uint(uint160(value))));
}
function remove (
UintSet storage set,
uint value
) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
function _at (
Set storage set,
uint index
) private view returns (bytes32) {
require(set._values.length > index, 'EnumerableSet: index out of bounds');
return set._values[index];
}
function _contains (
Set storage set,
bytes32 value
) private view returns (bool) {
return set._indexes[value] != 0;
}
function _indexOf (
Set storage set,
bytes32 value
) private view returns (uint) {
unchecked {
return set._indexes[value] - 1;
}
}
function _length (
Set storage set
) private view returns (uint) {
return set._values.length;
}
function _add (
Set storage set,
bytes32 value
) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
set._indexes[value] = set._values.length;
return true;
} else {
return false;
}
}
function _remove (
Set storage set,
bytes32 value
) private returns (bool) {
uint valueIndex = set._indexes[value];
if (valueIndex != 0) {
uint index = valueIndex - 1;
bytes32 last = set._values[set._values.length - 1];
set._values[index] = last;
set._indexes[last] = index + 1;
set._values.pop();
delete set._indexes[value];
return true;
} else {
return false;
}
}
}
文件 3 的 9:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 4 的 9:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
function allowance(address owner, address spender) external view returns (uint256);
function approve(address spender, uint256 amount) external returns (bool);
function transferFrom(
address sender,
address recipient,
uint256 amount
) external returns (bool);
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
}
文件 5 的 9:IERC721.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC721 is IERC165 {
event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);
event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);
event ApprovalForAll(address indexed owner, address indexed operator, bool approved);
function balanceOf(address owner) external view returns (uint256 balance);
function ownerOf(uint256 tokenId) external view returns (address owner);
function safeTransferFrom(
address from,
address to,
uint256 tokenId
) external;
function transferFrom(
address from,
address to,
uint256 tokenId
) external;
function approve(address to, uint256 tokenId) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function setApprovalForAll(address operator, bool _approved) external;
function isApprovedForAll(address owner, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 tokenId,
bytes calldata data
) external;
}
文件 6 的 9:IERC721Receiver.sol
pragma solidity ^0.8.0;
interface IERC721Receiver {
function onERC721Received(
address operator,
address from,
uint256 tokenId,
bytes calldata data
) external returns (bytes4);
}
文件 7 的 9:MagicTreasureStaking.sol
pragma solidity ^0.8.0;
import '@openzeppelin/contracts/access/Ownable.sol';
import '@openzeppelin/contracts/token/ERC20/IERC20.sol';
import '@openzeppelin/contracts/security/ReentrancyGuard.sol';
import '@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol';
import '@openzeppelin/contracts/token/ERC721/IERC721.sol';
import '@solidstate/contracts/utils/EnumerableSet.sol';
contract MagicTreasureStaking is Ownable, ReentrancyGuard, IERC721Receiver {
using EnumerableSet for EnumerableSet.UintSet;
mapping(address => uint256) public depositBalances;
mapping(address => EnumerableSet.UintSet) private _deposits;
IERC20 public stakedToken;
address public ERC721_CONTRACT;
uint256 public totalSupply;
event StakedTreasure(address indexed user, uint256[] tokenIds);
event Staked(address indexed user, uint256 amount, uint256 timeStamp);
function balanceOf(address account) public view returns (uint256) {
return depositBalances[account];
}
function totalStaked() public view returns (uint256) {
return stakedToken.balanceOf(address(this));
}
string constant _transferErrorMessage = 'staked token transfer failed';
constructor(IERC20 _stakedToken, address _treasureContract) {
stakedToken = _stakedToken;
ERC721_CONTRACT = _treasureContract;
}
function stakeFor(address forWhom, uint256 amount) public payable {
IERC20 st = stakedToken;
if (st == IERC20(address(0))) {
unchecked {
totalSupply += msg.value;
depositBalances[forWhom] += msg.value;
}
} else {
require(msg.value == 0, 'non-zero eth');
require(amount > 0, 'Cannot stake 0');
require(
st.transferFrom(msg.sender, address(this), amount),
_transferErrorMessage
);
unchecked {
totalSupply += amount;
depositBalances[forWhom] += amount;
}
}
emit Staked(forWhom, amount, uint256(block.timestamp));
}
function stake(uint256 amount) external payable {
require(msg.sender == tx.origin, 'humans only please.');
stakeFor(msg.sender, amount);
}
function stakeTreasure(uint256[] calldata _tokenIds) external {
for (uint256 i; i < _tokenIds.length; i++) {
IERC721(ERC721_CONTRACT).safeTransferFrom(
msg.sender,
address(this),
_tokenIds[i],
''
);
_deposits[msg.sender].add(_tokenIds[i]);
}
emit StakedTreasure(msg.sender, _tokenIds);
}
function onERC721Received(
address,
address,
uint256,
bytes calldata
) external pure override returns (bytes4) {
return IERC721Receiver.onERC721Received.selector;
}
}
文件 8 的 9:Ownable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() {
_setOwner(_msgSender());
}
function owner() public view virtual returns (address) {
return _owner;
}
modifier onlyOwner() {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
_;
}
function renounceOwnership() public virtual onlyOwner {
_setOwner(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 9 的 9:ReentrancyGuard.sol
pragma solidity ^0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
{
"compilationTarget": {
"contracts/farm/MagicTreasureStaking.sol": "MagicTreasureStaking"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 10
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IERC20","name":"_stakedToken","type":"address"},{"internalType":"address","name":"_treasureContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timeStamp","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"StakedTreasure","type":"event"},{"inputs":[],"name":"ERC721_CONTRACT","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"depositBalances","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stake","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"forWhom","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"stakeFor","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"stakeTreasure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stakedToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]