文件 1 的 1:XARAclaim.sol
pragma solidity ^0.8.0;
contract ERC20 {
function proxyMint(address reciever, uint256 amount) external {}
function proxyTransfer(address from, address to, uint256 amount) external {}
function balanceOf(address account) public view returns (uint256) {}
function getUserStakedContracts( address staker ) external view returns (address[] memory){}
function getUserStakedTokenIndex( address staker ) external view returns (uint256[] memory){}
function getUserStakedTokenIds( address staker ) external view returns (uint256[] memory){}
function getUserStakedTimestamps( address staker ) external view returns (uint256[] memory){}
function maxSupply() public view returns (uint256){}
function totalSupply() public view returns (uint256){}
}
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
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 0x address");
_setOwner(newOwner);
}
function _setOwner(address newOwner) private {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
abstract contract Functional {
function toString(uint256 value) internal pure returns (string memory) {
if (value == 0) {
return "0";
}
uint256 temp = value;
uint256 digits;
while (temp != 0) {
digits++;
temp /= 10;
}
bytes memory buffer = new bytes(digits);
while (value != 0) {
digits -= 1;
buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
value /= 10;
}
return string(buffer);
}
bool private _reentryKey = false;
modifier reentryLock {
require(!_reentryKey, "attempt reenter locked function");
_reentryKey = true;
_;
_reentryKey = false;
}
}
contract XARAclaim is Functional, Ownable {
mapping(address => uint256) private _balances;
mapping(address => mapping(address => uint256)) private _allowances;
uint256 public constant DAY = 86400;
uint256 public constant MONTH = 30 * DAY;
uint256 public X_RewardsPerMonth;
uint256 public L_RewardsPerMonth;
uint256 public C_RewardsPerMonth;
uint256 public B_RewardsPerMonth;
uint256 public Z_RewardsPerMonth;
uint256 public currentIndex;
mapping (uint256 => uint256) stakedTimestamp;
address XAR;
address LAND;
address CITY;
address VR;
ERC20 XARA;
constructor() {
X_RewardsPerMonth = 92 * (10 ** 18);
C_RewardsPerMonth = 80 * (10 ** 18);
L_RewardsPerMonth = 60 * (10 ** 18);
Z_RewardsPerMonth = 40 * (10 ** 18);
B_RewardsPerMonth = 45 * (10 ** 18);
XAR = address(0xe207578AB49f553534c025ee348Ac33e81cc6018);
LAND = address(0xb820fa56a477E120b3f55ae049eE3Ee8E2f55250);
CITY = address(0x17AD54d4D457bc3D57ABDD94DdfE52d792a227aA);
XARA = ERC20(0x140670B39F936fa211cE00d12F86f78a3F7dfE23);
}
function claimRewards() public reentryLock {
uint256 rewardDue = checkRewards(_msgSender());
uint256 maxSupply = XARA.maxSupply();
uint256 totalSupply = XARA.totalSupply();
uint256 [] memory sIndex = XARA.getUserStakedTokenIndex( _msgSender() );
for (uint256 i=0; i < sIndex.length; i++){
stakedTimestamp[sIndex[i]] = block.timestamp;
}
if (rewardDue + totalSupply <= maxSupply){
XARA.proxyMint(_msgSender(), rewardDue);
}else{
XARA.proxyMint(_msgSender(), maxSupply - totalSupply);
}
}
function checkRewards(address claimer) public view returns (uint256) {
address [] memory sContract = XARA.getUserStakedContracts( claimer );
uint256 [] memory sIndex = XARA.getUserStakedTokenIndex( claimer );
uint256 [] memory sTimestamp = XARA.getUserStakedTimestamps( claimer );
uint256 rewardPerSec = 0;
uint256 index = 0;
uint256 iTimestamp = 0;
uint256 citiesStaked = 0;
uint256 landStaked = 0;
uint256 totalRewards = 0;
uint256 bonusTimestamp = 0;
for (uint256 i=0; i<sIndex.length; i++){
index = sIndex[i];
if (stakedTimestamp[index] < sTimestamp[i]){
iTimestamp = sTimestamp[i];
} else {
iTimestamp = stakedTimestamp[index];
}
if (sContract[i] == XAR){
rewardPerSec = X_RewardsPerMonth / MONTH;
}
if (sContract[i] == LAND){
rewardPerSec = L_RewardsPerMonth / MONTH;
landStaked += 1;
bonusTimestamp = iTimestamp;
}
if (sContract[i] == CITY){
rewardPerSec = C_RewardsPerMonth / MONTH;
citiesStaked += 1;
bonusTimestamp = iTimestamp;
}
if (sContract[i] == VR){
rewardPerSec = Z_RewardsPerMonth / MONTH;
}
totalRewards += (block.timestamp - iTimestamp) * rewardPerSec;
}
if (bonusTimestamp != 0){
if ( landStaked >= citiesStaked){
totalRewards += (citiesStaked * B_RewardsPerMonth / MONTH) * (block.timestamp - bonusTimestamp);
} else {
totalRewards += (landStaked * B_RewardsPerMonth / MONTH) * (block.timestamp - bonusTimestamp);
}
}
return totalRewards;
}
function setXara(address contractAddress) external onlyOwner {
XAR = contractAddress;
}
function setLand(address contractAddress) external onlyOwner {
LAND = contractAddress;
}
function setCity(address contractAddress) external onlyOwner {
CITY = contractAddress;
}
function setVR(address contractAddress) external onlyOwner {
VR = contractAddress;
}
function setRewardsPerMonthWholeCoins( uint256 xaraReward, uint256 landReward, uint256 cityReward, uint256 bonusReward, uint256 ZReward) external onlyOwner {
X_RewardsPerMonth = xaraReward * (10 ** 18);
L_RewardsPerMonth = landReward * (10 ** 18);
C_RewardsPerMonth = cityReward * (10 ** 18);
B_RewardsPerMonth = bonusReward * (10 ** 18);
Z_RewardsPerMonth = ZReward * (10 ** 18);
}
function getUserStakedTimestamps( address staker ) external view returns (uint256[] memory){
uint256 [] memory sIndex = XARA.getUserStakedTokenIndex( staker );
uint256 [] memory sTimestamp = XARA.getUserStakedTimestamps( staker );
uint256 arraylen = sIndex.length;
uint256[] memory exportTimestamps = new uint256[](arraylen);
uint256 index = 0;
for (uint256 i=0; i < arraylen; i++){
index = sIndex[i];
if (stakedTimestamp[index] < sTimestamp[i]){
exportTimestamps[i] = sTimestamp[i];
} else {
exportTimestamps[i] = stakedTimestamp[index];
}
}
return exportTimestamps;
}
receive() external payable {}
fallback() external payable {}
}
{
"compilationTarget": {
"XARAclaim.sol": "XARAclaim"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": false,
"runs": 200
},
"remappings": []
}