文件 1 的 3:Farm.sol
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/security/ReentrancyGuard.sol";
contract Farm is ReentrancyGuard {
IERC20 public ROYAL;
IERC20 public MUSE;
mapping(address => uint256) public museStaked;
mapping(address => uint256) public royalStaked;
mapping(address => uint256) public startedStakingMuse;
mapping(address => uint256) public startedStakingRoyal;
constructor(address _royal, address _muse) {
ROYAL = IERC20(_royal);
MUSE = IERC20(_muse);
}
function getPoints(address _user)
public
view
returns (uint256 musepoints, uint256 royalpoints)
{
return (
startedStakingMuse[_user] == 0
? 0
: block.timestamp - startedStakingMuse[_user],
startedStakingRoyal[_user] == 0
? 0
: block.timestamp - startedStakingRoyal[_user]
);
}
function stakeMuse(uint256 _amount) external nonReentrant {
if (museStaked[msg.sender] == 0) {
startedStakingMuse[msg.sender] = block.timestamp;
}
museStaked[msg.sender] += _amount;
MUSE.transferFrom(msg.sender, address(this), _amount);
}
function stakeRoyal(uint256 _amount) external nonReentrant {
if (royalStaked[msg.sender] == 0) {
startedStakingRoyal[msg.sender] = block.timestamp;
}
royalStaked[msg.sender] += _amount;
ROYAL.transferFrom(msg.sender, address(this), _amount);
}
function unstake() external nonReentrant {
uint256 muse = museStaked[msg.sender];
uint256 royal = royalStaked[msg.sender];
museStaked[msg.sender] = 0;
royalStaked[msg.sender] = 0;
startedStakingRoyal[msg.sender] = 0;
startedStakingMuse[msg.sender] = 0;
if (royal > 0) {
ROYAL.transfer(msg.sender, royal);
}
if (muse > 0) {
MUSE.transfer(msg.sender, muse);
}
}
}
文件 2 的 3: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);
}
文件 3 的 3: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.sol": "Farm"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_royal","type":"address"},{"internalType":"address","name":"_muse","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"MUSE","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ROYAL","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"getPoints","outputs":[{"internalType":"uint256","name":"musepoints","type":"uint256"},{"internalType":"uint256","name":"royalpoints","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"museStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"royalStaked","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeMuse","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"stakeRoyal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"startedStakingMuse","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"startedStakingRoyal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unstake","outputs":[],"stateMutability":"nonpayable","type":"function"}]