编译器
0.6.12+commit.27d51765
文件 1 的 18:Address.sol
pragma solidity ^0.6.2;
library Address {
function isContract(address account) internal view returns (bool) {
bytes32 codehash;
bytes32 accountHash = 0xc5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a470;
assembly {
codehash := extcodehash(account)
}
return (codehash != accountHash && codehash != 0x0);
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, 'Address: insufficient balance');
(bool success, ) = recipient.call{value: amount}('');
require(success, 'Address: unable to send value, recipient may have reverted');
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, 'Address: low-level call failed');
}
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return _functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, 'Address: low-level call with value failed');
}
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, 'Address: insufficient balance for call');
return _functionCallWithValue(target, data, value, errorMessage);
}
function _functionCallWithValue(
address target,
bytes memory data,
uint256 weiValue,
string memory errorMessage
) private returns (bytes memory) {
require(isContract(target), 'Address: call to non-contract');
(bool success, bytes memory returndata) = target.call{value: weiValue}(data);
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 2 的 18:AddressUpgradeable.sol
pragma solidity >=0.6.12;
library AddressUpgradeable {
function isContract(address account) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(account) }
return size > 0;
}
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{ value: amount }("");
require(success, "Address: unable to send value, recipient may have reverted");
}
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCall(target, data, "Address: low-level call failed");
}
function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
require(isContract(target), "Address: call to non-contract");
(bool success, bytes memory returndata) = target.call{ value: value }(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) {
require(isContract(target), "Address: static call to non-contract");
(bool success, bytes memory returndata) = target.staticcall(data);
return _verifyCallResult(success, returndata, errorMessage);
}
function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
if (success) {
return returndata;
} else {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
}
文件 3 的 18:Context.sol
pragma solidity >=0.4.0;
contract Context {
constructor() internal {}
function _msgSender() internal view returns (address payable) {
return msg.sender;
}
function _msgData() internal view returns (bytes memory) {
this;
return msg.data;
}
}
文件 4 的 18:ContextUpgradeable.sol
pragma solidity >=0.6.0 <0.8.0;
import "../proxy/Initializable.sol";
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal initializer {
__Context_init_unchained();
}
function __Context_init_unchained() internal initializer {
}
function _msgSender() internal view virtual returns (address payable) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes memory) {
this;
return msg.data;
}
uint256[50] private __gap;
}
文件 5 的 18:Farming.sol
pragma solidity >=0.6.12;
import "./library/Math.sol";
import "./utils/SafeBEP20.sol";
import "./access/Ownable.sol";
import "./utils/ReentrancyGuard.sol";
import "./Proxy.sol";
import "./library/Whitelist.sol";
import "./interfaces/IMeerkatReferral.sol";
import "./interfaces/IERC721.sol";
interface IMeerkatToken {
function mint(address _to, uint256 _amount) external returns (bool);
function redeem(uint256 _amount) external;
function balanceOf(address account) external view returns (uint256);
function transfer(address recipient, uint256 amount) external returns (bool);
}
interface NFTController {
function getBoostRate(address token, uint tokenId) external view returns (uint boostRate);
function isWhitelistedNFT(address token) external view returns (bool);
}
interface GaugeController {
function getBoostRate(address sender, uint pid) external view returns (uint boostRate);
}
contract CitadelMaster is Ownable, ReentrancyGuard, Whitelist {
using SafeMath for uint256;
using SafeBEP20 for IBEP20;
uint256 public constant BONUS_MULTIPLIER = 1;
struct UserInfo {
uint256 amount;
uint256 rewardDebt;
}
struct PoolInfo {
IBEP20 lpToken;
uint256 allocPoint;
uint256 lastRewardBlock;
uint256 accMeerkatPerShare;
}
struct NFTSlot {
address slot1;
uint256 tokenId1;
address slot2;
uint256 tokenId2;
address slot3;
uint256 tokenId3;
}
IMeerkatToken public xMeerkat;
IMeerkatToken public meerkat;
uint256 public meerkatPerBlock;
PoolInfo[] public poolInfo;
mapping(uint256 => mapping(address => UserInfo)) public userInfo;
uint256 public totalAllocPoint;
uint256 public startBlock;
mapping(IBEP20 => bool) public poolExistence;
mapping(address => mapping(uint256 => NFTSlot)) private _depositedNFT;
bool public whitelistAll;
NFTController public controller = NFTController(address(0));
uint public nftBoostRate = 100;
IMeerkatReferral public meerkatReferral;
uint16 public referralCommissionRate = 100;
uint16 public constant MAXIMUM_REFERRAL_COMMISSION_RATE = 1000;
CitadelProxy public proxy = CitadelProxy(0x6b25EcE65a605453cfBFAA996F384F2E46337a2B);
uint16 public unlockRate = 2000;
GaugeController public gauge = GaugeController(address(0));
event Deposit(address indexed user, uint256 indexed pid, uint256 amount);
event Withdraw(address indexed user, uint256 indexed pid, uint256 amount);
event EmergencyWithdraw(address indexed user, uint256 indexed pid, uint256 amount);
event UpdateEmissionRate(address indexed user, uint256 meerkatPerBlock);
event UpdateNFTController(address indexed user, address controller);
event UpdateGaugeController(address indexed user, address controller);
event UpdateNFTBoostRate(address indexed user, uint256 controller);
event ReferralCommissionPaid(address indexed user, address indexed referrer, uint256 commissionAmount);
constructor(
IMeerkatToken _xMeerkat,
IMeerkatToken _meerkat,
uint256 _meerkatPerBlock,
uint256 _startBlock
) public {
xMeerkat = _xMeerkat;
meerkat = _meerkat;
meerkatPerBlock = _meerkatPerBlock;
startBlock = _startBlock;
totalAllocPoint = 0;
whitelistAll = false;
}
modifier nonDuplicated(IBEP20 _lpToken) {
require(poolExistence[_lpToken] == false, "nonDuplicated: duplicated");
_;
}
modifier nonContract() {
if (!isWhitelist(msg.sender) && !whitelistAll) {
require(tx.origin == msg.sender);
}
_;
}
function getBoost(address _account, uint256 _pid) public view returns (uint256) {
if (address(controller) == address(0)) return 0;
NFTSlot memory slot = _depositedNFT[_account][_pid];
uint boost1 = controller.getBoostRate(slot.slot1, slot.tokenId1);
uint boost2 = controller.getBoostRate(slot.slot2, slot.tokenId2);
uint boost3 = controller.getBoostRate(slot.slot3, slot.tokenId3);
uint boost = boost1 + boost2 + boost3;
return boost.mul(nftBoostRate).div(100);
}
function getBoostGauge(address _account, uint256 _pid) public view returns (uint256) {
if (address(gauge) == address(0)) return 0;
return gauge.getBoostRate(_account, _pid);
}
function getSlots(address _account, uint256 _pid) public view returns (address, address, address) {
NFTSlot memory slot = _depositedNFT[_account][_pid];
return (slot.slot1, slot.slot2, slot.slot3);
}
function getTokenIds(address _account, uint256 _pid) public view returns (uint256, uint256, uint256) {
NFTSlot memory slot = _depositedNFT[_account][_pid];
return (slot.tokenId1, slot.tokenId2, slot.tokenId3);
}
function poolLength() external view returns (uint256) {
return poolInfo.length;
}
function getMultiplier(uint256 _from, uint256 _to) public pure returns (uint256) {
return _to.sub(_from).mul(BONUS_MULTIPLIER);
}
function pendingMeerkat(uint256 _pid, address _user) external view returns (uint256) {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][_user];
uint256 accMeerkatPerShare = pool.accMeerkatPerShare;
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
if (block.number > pool.lastRewardBlock && lpSupply != 0) {
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 meerkatReward = multiplier.mul(meerkatPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
accMeerkatPerShare = accMeerkatPerShare.add(meerkatReward.mul(1e18).div(lpSupply));
}
return user.amount.mul(accMeerkatPerShare).div(1e18).sub(user.rewardDebt);
}
function add(uint256 _allocPoint, IBEP20 _lpToken, bool _withUpdate) public onlyOwner nonDuplicated(_lpToken) {
require(_lpToken.balanceOf(address(this)) >= 0, "Not ERC20");
if (_withUpdate) {
massUpdatePools();
}
uint256 lastRewardBlock = block.number > startBlock ? block.number : startBlock;
totalAllocPoint = totalAllocPoint.add(_allocPoint);
poolExistence[_lpToken] = true;
poolInfo.push(PoolInfo({
lpToken : _lpToken,
allocPoint : _allocPoint,
lastRewardBlock : lastRewardBlock,
accMeerkatPerShare : 0
}));
}
function set(uint256 _pid, uint256 _allocPoint, bool _withUpdate) public onlyOwner {
if (_withUpdate) {
massUpdatePools();
}
totalAllocPoint = totalAllocPoint.sub(poolInfo[_pid].allocPoint).add(_allocPoint);
poolInfo[_pid].allocPoint = _allocPoint;
}
function multiSet(uint256[] calldata _pids, uint256[] calldata _allocPoints, bool _withUpdate) public onlyOwner {
if (_withUpdate) {
massUpdatePools();
}
for (uint i = 0; i < _pids.length; ++i) {
set(_pids[i], _allocPoints[i], false);
}
}
function depositNFT(address _nft, uint256 _tokenId, uint256 _slot, uint256 _pid) public nonContract {
require(controller.isWhitelistedNFT(_nft), "only approved NFTs");
require(ERC721(_nft).balanceOf(msg.sender) > 0, "user does not have specified NFT");
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount == 0, "not allowed to deposit");
ERC721(_nft).transferFrom(msg.sender, address(this), _tokenId);
NFTSlot memory slot = _depositedNFT[msg.sender][_pid];
if (_slot == 1) slot.slot1 = _nft;
else if (_slot == 2) slot.slot2 = _nft;
else if (_slot == 3) slot.slot3 = _nft;
if (_slot == 1) slot.tokenId1 = _tokenId;
else if (_slot == 2) slot.tokenId2 = _tokenId;
else if (_slot == 3) slot.tokenId3 = _tokenId;
_depositedNFT[msg.sender][_pid] = slot;
}
function withdrawNFT(uint256 _slot, uint256 _pid) public nonContract {
address _nft;
uint256 _tokenId;
NFTSlot memory slot = _depositedNFT[msg.sender][_pid];
if (_slot == 1) _nft = slot.slot1;
else if (_slot == 2) _nft = slot.slot2;
else if (_slot == 3) _nft = slot.slot3;
if (_slot == 1) _tokenId = slot.tokenId1;
else if (_slot == 2) _tokenId = slot.tokenId2;
else if (_slot == 3) _tokenId = slot.tokenId3;
if (_slot == 1) slot.slot1 = address(0);
else if (_slot == 2) slot.slot2 = address(0);
else if (_slot == 3) slot.slot3 = address(0);
if (_slot == 1) slot.tokenId1 = uint(0);
else if (_slot == 2) slot.tokenId2 = uint(0);
else if (_slot == 3) slot.tokenId3 = uint(0);
_depositedNFT[msg.sender][_pid] = slot;
ERC721(_nft).transferFrom(address(this), msg.sender, _tokenId);
}
function massUpdatePools() public {
uint256 length = poolInfo.length;
for (uint256 pid = 0; pid < length; ++pid) {
updatePool(pid);
}
}
function updatePool(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
if (block.number <= pool.lastRewardBlock) {
return;
}
uint256 lpSupply = pool.lpToken.balanceOf(address(this));
if (lpSupply == 0 || pool.allocPoint == 0) {
pool.lastRewardBlock = block.number;
return;
}
uint256 multiplier = getMultiplier(pool.lastRewardBlock, block.number);
uint256 meerkatReward = multiplier.mul(meerkatPerBlock).mul(pool.allocPoint).div(totalAllocPoint);
xMeerkat.mint(address(proxy), meerkatReward);
pool.accMeerkatPerShare = pool.accMeerkatPerShare.add(meerkatReward.mul(1e18).div(lpSupply));
pool.lastRewardBlock = block.number;
}
function deposit(uint256 _pid, uint256 _amount, address _referrer) public nonReentrant nonContract {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
updatePool(_pid);
if (_amount > 0 && address(meerkatReferral) != address(0) && _referrer != address(0) && _referrer != msg.sender) {
meerkatReferral.recordReferral(msg.sender, _referrer);
}
if (user.amount > 0) {
uint256 pending = user.amount.mul(pool.accMeerkatPerShare).div(1e18).sub(user.rewardDebt);
if (pending > 0) {
safeMeerkatTransfer(msg.sender, pending, _pid);
}
}
if (_amount > 0) {
pool.lpToken.safeTransferFrom(address(msg.sender), address(this), _amount);
user.amount = user.amount.add(_amount);
}
user.rewardDebt = user.amount.mul(pool.accMeerkatPerShare).div(1e18);
emit Deposit(msg.sender, _pid, _amount);
}
function withdraw(uint256 _pid, uint256 _amount) public nonReentrant nonContract {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
require(user.amount >= _amount, "withdraw: not good");
updatePool(_pid);
uint256 pending = user.amount.mul(pool.accMeerkatPerShare).div(1e18).sub(user.rewardDebt);
if (pending > 0) {
safeMeerkatTransfer(msg.sender, pending, _pid);
}
if (_amount > 0) {
user.amount = user.amount.sub(_amount);
pool.lpToken.safeTransfer(address(msg.sender), _amount);
}
user.rewardDebt = user.amount.mul(pool.accMeerkatPerShare).div(1e18);
emit Withdraw(msg.sender, _pid, _amount);
}
function emergencyWithdraw(uint256 _pid) public nonReentrant {
PoolInfo storage pool = poolInfo[_pid];
UserInfo storage user = userInfo[_pid][msg.sender];
uint256 amount = user.amount;
user.amount = 0;
user.rewardDebt = 0;
pool.lpToken.safeTransfer(address(msg.sender), amount);
emit EmergencyWithdraw(msg.sender, _pid, amount);
}
function safeMeerkatTransfer(address _to, uint256 _amount, uint256 _pid) internal {
uint256 boost = 0;
_amount = proxy.safeMeerkatTransfer(address(this), _amount);
uint unlockedAmt = _amount.mul(unlockRate).div(10000);
xMeerkat.redeem(unlockedAmt);
meerkat.transfer(_to, unlockedAmt);
xMeerkat.transfer(_to, _amount.sub(unlockedAmt));
boost = getBoost(_to, _pid).mul(_amount).div(100);
boost = boost.add(getBoostGauge(_to, _pid).mul(_amount).div(10000));
payReferralCommission(msg.sender, _amount);
if (boost > 0) meerkat.mint(_to, boost);
}
function updateEmissionRate(uint256 _meerkatPerBlock) public onlyOwner {
massUpdatePools();
meerkatPerBlock = _meerkatPerBlock;
emit UpdateEmissionRate(msg.sender, _meerkatPerBlock);
}
function setNftController(address _controller) public onlyOwner {
controller = NFTController(_controller);
emit UpdateNFTController(msg.sender, _controller);
}
function setGaugeController(address _controller) public onlyOwner {
gauge = GaugeController(_controller);
emit UpdateGaugeController(msg.sender, _controller);
}
function setNftBoostRate(uint256 _rate) public onlyOwner {
require(_rate > 50 && _rate < 500, "boost must be within range");
nftBoostRate = _rate;
emit UpdateNFTBoostRate(msg.sender, _rate);
}
function setMeerkatReferral(IMeerkatReferral _meerkatReferral) public onlyOwner {
meerkatReferral = _meerkatReferral;
}
function flipWhitelistAll() public onlyOwner {
whitelistAll = !whitelistAll;
}
function setReferralCommissionRate(uint16 _referralCommissionRate) public onlyOwner {
require(_referralCommissionRate <= MAXIMUM_REFERRAL_COMMISSION_RATE, "setReferralCommissionRate: invalid referral commission rate basis points");
referralCommissionRate = _referralCommissionRate;
}
function setUnlockRate(uint16 _unlockRate) public onlyOwner {
require(_unlockRate <= 10000, "setUnlockRate: invalid unlock rate basis points");
unlockRate = _unlockRate;
}
function setProxy(address _proxy) public onlyOwner {
require(_proxy != address(0), "setProxy: invalid proxy");
proxy = CitadelProxy(_proxy);
}
function payReferralCommission(address _user, uint256 _pending) internal {
if (address(meerkatReferral) != address(0) && referralCommissionRate > 0) {
address referrer = meerkatReferral.getReferrer(_user);
uint256 commissionAmount = _pending.mul(referralCommissionRate).div(10000);
if (referrer != address(0) && commissionAmount > 0) {
meerkat.mint(referrer, commissionAmount);
meerkatReferral.recordReferralCommission(referrer, commissionAmount);
emit ReferralCommissionPaid(_user, referrer, commissionAmount);
}
}
}
}
文件 6 的 18:IBEP20.sol
pragma solidity >=0.4.0;
interface IBEP20 {
function totalSupply() external view returns (uint256);
function decimals() external view returns (uint8);
function symbol() external view returns (string memory);
function name() external view returns (string memory);
function getOwner() external view returns (address);
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);
}
文件 7 的 18:IERC721.sol
pragma solidity ^0.6.12;
interface ERC721 {
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);
function ownerOf(uint256 _tokenId) external view returns (address);
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes memory data) external payable;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external payable;
function transferFrom(address _from, address _to, uint256 _tokenId) external payable;
function approve(address _approved, uint256 _tokenId) external payable;
function setApprovalForAll(address _operator, bool _approved) external;
function getApproved(uint256 _tokenId) external view returns (address);
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
function tokenURI(uint256 _tokenId) external view returns (string memory);
function totalSupply() external view returns (uint256);
function tokenByIndex(uint256 _index) external view returns (uint256);
function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
function burn(uint256 tokenId) external;
}
interface ERC165 {
function supportsInterface(bytes4 interfaceID) external view returns (bool);
}
文件 8 的 18:IMeerkatReferral.sol
pragma solidity 0.6.12;
interface IMeerkatReferral {
function recordReferral(address user, address referrer) external;
function recordReferralCommission(address referrer, uint256 commission) external;
function getReferrer(address user) external view returns (address);
}
文件 9 的 18:Initializable.sol
pragma solidity >=0.4.24 <0.8.0;
import "../utils/AddressUpgradeable.sol";
abstract contract Initializable {
bool private _initialized;
bool private _initializing;
modifier initializer() {
require(_initializing || _isConstructor() || !_initialized, "Initializable: contract is already initialized");
bool isTopLevelCall = !_initializing;
if (isTopLevelCall) {
_initializing = true;
_initialized = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
}
}
function _isConstructor() private view returns (bool) {
return !AddressUpgradeable.isContract(address(this));
}
}
文件 10 的 18:Math.sol
pragma solidity >=0.6.0 <0.8.0;
library Math {
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a >= b ? a : b;
}
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
function average(uint256 a, uint256 b) internal pure returns (uint256) {
return (a / 2) + (b / 2) + ((a % 2 + b % 2) / 2);
}
}
文件 11 的 18:Ownable.sol
pragma solidity >=0.4.0;
import './Context.sol';
contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
constructor() internal {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), msgSender);
}
function owner() public view returns (address) {
return _owner;
}
modifier onlyOwner() {
require(_owner == _msgSender(), 'Ownable: caller is not the owner');
_;
}
function renounceOwnership() public onlyOwner {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public onlyOwner {
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal {
require(newOwner != address(0), 'Ownable: new owner is the zero address');
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
}
文件 12 的 18:OwnableUpgradeable.sol
pragma solidity >=0.6.12;
import "../utils/ContextUpgradeable.sol";
import "../proxy/Initializable.sol";
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
function __Ownable_init() internal initializer {
__Context_init_unchained();
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal initializer {
address msgSender = _msgSender();
_owner = msgSender;
emit OwnershipTransferred(address(0), 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 {
emit OwnershipTransferred(_owner, address(0));
_owner = address(0);
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
emit OwnershipTransferred(_owner, newOwner);
_owner = newOwner;
}
uint256[49] private __gap;
}
文件 13 的 18:Proxy.sol
pragma solidity >=0.6.12;
import "./utils/SafeBEP20.sol";
import "./access/OwnableUpgradeable.sol";
import "./library/WhitelistUpgradeable.sol";
contract CitadelProxy is OwnableUpgradeable, WhitelistUpgradeable {
using SafeBEP20 for IBEP20;
IBEP20 private token;
function initialize(IBEP20 _token) external initializer {
__Ownable_init();
token = _token;
}
function safeMeerkatTransfer(address to, uint256 amount) external onlyWhitelisted returns (uint256) {
uint256 meerkatBal = token.balanceOf(address(this));
if (amount > meerkatBal) {
token.transfer(to, meerkatBal);
return meerkatBal;
} else {
token.transfer(to, amount);
return amount;
}
}
function recoverToken(IBEP20 _token, uint256 _amount, address _to) external onlyOwner {
require(address(_token) != address(token));
_token.safeTransfer(_to, _amount);
}
}
文件 14 的 18:ReentrancyGuard.sol
pragma solidity >=0.6.0 <0.8.0;
abstract contract ReentrancyGuard {
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor () internal {
_status = _NOT_ENTERED;
}
modifier nonReentrant() {
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
_status = _ENTERED;
_;
_status = _NOT_ENTERED;
}
}
文件 15 的 18:SafeBEP20.sol
pragma solidity ^0.6.0;
import '../interfaces/IBEP20.sol';
import '../library/SafeMath.sol';
import './Address.sol';
library SafeBEP20 {
using SafeMath for uint256;
using Address for address;
function safeTransfer(
IBEP20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IBEP20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(
IBEP20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
'SafeBEP20: approve from non-zero to non-zero allowance'
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IBEP20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender).add(value);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IBEP20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender).sub(
value,
'SafeBEP20: decreased allowance below zero'
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function _callOptionalReturn(IBEP20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, 'SafeBEP20: low-level call failed');
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), 'SafeBEP20: BEP20 operation did not succeed');
}
}
}
文件 16 的 18:SafeMath.sol
pragma solidity >=0.4.0;
library SafeMath {
function add(uint256 a, uint256 b) internal pure returns (uint256) {
uint256 c = a + b;
require(c >= a, 'SafeMath: addition overflow');
return c;
}
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return sub(a, b, 'SafeMath: subtraction overflow');
}
function sub(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b <= a, errorMessage);
uint256 c = a - b;
return c;
}
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
uint256 c = a * b;
require(c / a == b, 'SafeMath: multiplication overflow');
return c;
}
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return div(a, b, 'SafeMath: division by zero');
}
function div(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b > 0, errorMessage);
uint256 c = a / b;
return c;
}
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return mod(a, b, 'SafeMath: modulo by zero');
}
function mod(
uint256 a,
uint256 b,
string memory errorMessage
) internal pure returns (uint256) {
require(b != 0, errorMessage);
return a % b;
}
function min(uint256 x, uint256 y) internal pure returns (uint256 z) {
z = x < y ? x : y;
}
function sqrt(uint256 y) internal pure returns (uint256 z) {
if (y > 3) {
z = y;
uint256 x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
}
}
文件 17 的 18:Whitelist.sol
pragma solidity ^0.6.12;
import "../access/Ownable.sol";
contract Whitelist is Ownable {
mapping(address => bool) private _whitelist;
bool private _disable;
event Whitelisted(address indexed _address, bool whitelist);
event EnableWhitelist();
event DisableWhitelist();
modifier onlyWhitelisted {
require(_disable || _whitelist[msg.sender], "Whitelist: caller is not on the whitelist");
_;
}
function isWhitelist(address _address) public view returns (bool) {
return _whitelist[_address];
}
function setWhitelist(address _address, bool _on) external onlyOwner {
_whitelist[_address] = _on;
emit Whitelisted(_address, _on);
}
function disableWhitelist(bool disable) external onlyOwner {
_disable = disable;
if (disable) {
emit DisableWhitelist();
} else {
emit EnableWhitelist();
}
}
}
文件 18 的 18:WhitelistUpgradeable.sol
pragma solidity >=0.6.12;
import "../access/OwnableUpgradeable.sol";
contract WhitelistUpgradeable is OwnableUpgradeable {
mapping (address => bool) private _whitelist;
bool private _disable;
event Whitelisted(address indexed _address, bool whitelist);
event EnableWhitelist();
event DisableWhitelist();
modifier onlyWhitelisted {
require(_disable || _whitelist[msg.sender], "Whitelist: caller is not on the whitelist");
_;
}
function __WhitelistUpgradeable_init() internal initializer {
__Ownable_init();
}
function isWhitelist(address _address) public view returns(bool) {
return _whitelist[_address];
}
function setWhitelist(address _address, bool _on) external onlyOwner {
_whitelist[_address] = _on;
emit Whitelisted(_address, _on);
}
function disableWhitelist(bool disable) external onlyOwner {
_disable = disable;
if (disable) {
emit DisableWhitelist();
} else {
emit EnableWhitelist();
}
}
uint256[49] private __gap;
}
{
"compilationTarget": {
"contracts/Farming.sol": "CitadelMaster"
},
"evmVersion": "istanbul",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IMeerkatToken","name":"_xMeerkat","type":"address"},{"internalType":"contract IMeerkatToken","name":"_meerkat","type":"address"},{"internalType":"uint256","name":"_meerkatPerBlock","type":"uint256"},{"internalType":"uint256","name":"_startBlock","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[],"name":"DisableWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EmergencyWithdraw","type":"event"},{"anonymous":false,"inputs":[],"name":"EnableWhitelist","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"referrer","type":"address"},{"indexed":false,"internalType":"uint256","name":"commissionAmount","type":"uint256"}],"name":"ReferralCommissionPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"meerkatPerBlock","type":"uint256"}],"name":"UpdateEmissionRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"controller","type":"address"}],"name":"UpdateGaugeController","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"controller","type":"uint256"}],"name":"UpdateNFTBoostRate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"address","name":"controller","type":"address"}],"name":"UpdateNFTController","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_address","type":"address"},{"indexed":false,"internalType":"bool","name":"whitelist","type":"bool"}],"name":"Whitelisted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"BONUS_MULTIPLIER","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAXIMUM_REFERRAL_COMMISSION_RATE","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"contract IBEP20","name":"_lpToken","type":"address"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"add","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"contract NFTController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"address","name":"_referrer","type":"address"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nft","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_slot","type":"uint256"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"depositNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"disable","type":"bool"}],"name":"disableWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipWhitelistAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"gauge","outputs":[{"internalType":"contract GaugeController","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getBoost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getBoostGauge","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_from","type":"uint256"},{"internalType":"uint256","name":"_to","type":"uint256"}],"name":"getMultiplier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getSlots","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_account","type":"address"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getTokenIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"meerkat","outputs":[{"internalType":"contract IMeerkatToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"meerkatPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"meerkatReferral","outputs":[{"internalType":"contract IMeerkatReferral","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"},{"internalType":"uint256[]","name":"_allocPoints","type":"uint256[]"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"multiSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nftBoostRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingMeerkat","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IBEP20","name":"","type":"address"}],"name":"poolExistence","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"contract IBEP20","name":"lpToken","type":"address"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardBlock","type":"uint256"},{"internalType":"uint256","name":"accMeerkatPerShare","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"proxy","outputs":[{"internalType":"contract CitadelProxy","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"referralCommissionRate","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"bool","name":"_withUpdate","type":"bool"}],"name":"set","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setGaugeController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IMeerkatReferral","name":"_meerkatReferral","type":"address"}],"name":"setMeerkatReferral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_rate","type":"uint256"}],"name":"setNftBoostRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_controller","type":"address"}],"name":"setNftController","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_proxy","type":"address"}],"name":"setProxy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_referralCommissionRate","type":"uint16"}],"name":"setReferralCommissionRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_unlockRate","type":"uint16"}],"name":"setUnlockRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"bool","name":"_on","type":"bool"}],"name":"setWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unlockRate","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_meerkatPerBlock","type":"uint256"}],"name":"updateEmissionRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"userInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"rewardDebt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_slot","type":"uint256"},{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"withdrawNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"xMeerkat","outputs":[{"internalType":"contract IMeerkatToken","name":"","type":"address"}],"stateMutability":"view","type":"function"}]