编译器
0.8.20+commit.a1b79de6
文件 1 的 21:AnimaStakingRewards.sol
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/security/Pausable.sol";
import "../Manager/ManagerModifier.sol";
import "../Realm/IRealm.sol";
import "./IAnimaStaker.sol";
import "./IAnimaStakingRewards.sol";
import "./IAnimaStakingRewardsStorage.sol";
import "./IAnimaChamberData.sol";
import "./IAnimaStakingRewardsCalculator.sol";
import "./IAnimaChamber.sol";
import "../ERC20/ITokenMinter.sol";
import "../Resource/IResource.sol";
import "../lib/FloatingPointConstants.sol";
import "../Resource/IResource.sol";
import "../Resource/ResourceConstants.sol";
import "../Utils/ArrayUtils.sol";
import "./IAnimaStakingRewardsEmitter.sol";
error NotOwner(
address _owner,
address _sender,
address _tokenAddress,
uint256 _tokenId
);
contract AnimaStakingRewards is
ManagerModifier,
IAnimaStakingRewards,
Pausable
{
IRealm public immutable REALM;
IAnimaChamber public immutable ANIMA_CHAMBER;
IAnimaChamberData public ANIMA_CHAMBER_DATA;
IAnimaStakingRewardsStorage public ANIMA_STAKING_REWARDS_STORAGE;
IAnimaStakingRewardsCalculator public ANIMA_STAKING_REWARDS_CALCULATOR;
IAnimaStakingRewardsEmitter public REWARDS_EMITTER;
IResource public RESOURCE;
uint256 public CAPACITY_EXCEEDED_REWARDS = 20000;
uint256 public MAX_REWARDS_PERIOD;
uint256 public immutable YEAR = 365 days;
constructor(
address _manager,
address _realm,
address _animaChamber,
address _animaChamberData,
address _animaStakingRewardsData,
address _animaStakingRewardsCalculator,
address _rewardsEmitter,
address _resource
) ManagerModifier(_manager) {
REALM = IRealm(_realm);
ANIMA_CHAMBER = IAnimaChamber(_animaChamber);
ANIMA_CHAMBER_DATA = IAnimaChamberData(_animaChamberData);
ANIMA_STAKING_REWARDS_STORAGE = IAnimaStakingRewardsStorage(
_animaStakingRewardsData
);
ANIMA_STAKING_REWARDS_CALCULATOR = IAnimaStakingRewardsCalculator(
_animaStakingRewardsCalculator
);
MAX_REWARDS_PERIOD = ANIMA_STAKING_REWARDS_CALCULATOR.MAX_REWARDS_PERIOD();
REWARDS_EMITTER = IAnimaStakingRewardsEmitter(_rewardsEmitter);
RESOURCE = IResource(_resource);
}
function availableStakerRewards(
uint[] calldata _tokenIds,
uint[][] calldata _params
) external view returns (uint[] memory, uint[] memory) {
uint[] memory rewards = new uint[](_tokenIds.length);
uint[] memory vestedAmounts = new uint[](_tokenIds.length);
for (uint i = 0; i < _tokenIds.length; i++) {
ChamberRewardsStorage memory info = ANIMA_STAKING_REWARDS_STORAGE
.loadChamberInfo(_tokenIds[i]);
uint chamberAnima = ANIMA_CHAMBER_DATA.stakedAnima(_tokenIds[i]);
(
uint stakerRewards,
,
uint vestedAmount
) = ANIMA_STAKING_REWARDS_CALCULATOR.calculateRewardsView(
chamberAnima,
info,
_params[i]
);
rewards[i] = stakerRewards;
vestedAmounts[i] = vestedAmount;
}
return (rewards, vestedAmounts);
}
function availableRealmerRewards(
uint[] calldata _realmIds
) external view returns (uint[] memory) {
ArrayUtils.checkForDuplicates(_realmIds);
uint[] memory rewards = new uint[](_realmIds.length);
uint totalRewards = 0;
uint totalStake = 0;
for (uint i = 0; i < _realmIds.length; i++) {
RealmRewardsStorage memory realmInfo = ANIMA_STAKING_REWARDS_STORAGE
.loadRealmInfo(_realmIds[i]);
_calculateAvailableCapacityBasedOnTimeElapsed(realmInfo);
uint[] memory chamberIds = ANIMA_STAKING_REWARDS_STORAGE.realmChamberIds(
_realmIds[i]
);
for (uint j = 0; j < chamberIds.length; j++) {
ChamberRewardsStorage memory chamberInfo = ANIMA_STAKING_REWARDS_STORAGE
.loadChamberInfo(chamberIds[j]);
uint chamberAnima = ANIMA_CHAMBER_DATA.stakedAnima(chamberIds[j]);
(
,
uint realmerRewards,
uint vestedStake
) = ANIMA_STAKING_REWARDS_CALCULATOR.calculateRewardsView(
chamberAnima,
chamberInfo,
new uint[](0)
);
(
realmerRewards,
realmInfo.lastCapacityUsed
) = _updateRealmerRewardsBasedOnCapacity(
realmInfo.lastCapacityUsed,
chamberInfo.realmId,
chamberInfo.lastRealmerCollectedAt,
realmerRewards,
vestedStake
);
rewards[i] += realmerRewards;
totalRewards += realmerRewards;
totalStake += vestedStake;
}
}
return rewards;
}
function stakerCollect(
uint256 _tokenId,
bool _compound,
uint[] calldata _params
) external whenNotPaused {
_collect(_tokenId, true, false, true, _compound, _params);
}
function stakerCollectBatch(
uint256[] calldata _tokenId,
bool[] calldata _compound,
uint[][] calldata _params
) external whenNotPaused {
for (uint256 i = 0; i < _tokenId.length; i++) {
_collect(_tokenId[i], true, false, true, _compound[i], _params[i]);
}
}
function realmerCollect(uint256 _realmId) external whenNotPaused {
_realmerCollect(_realmId);
}
function realmerCollectBatch(
uint256[] calldata _realmIds
) external whenNotPaused {
ArrayUtils.checkForDuplicates(_realmIds);
for (uint256 i = 0; i < _realmIds.length; i++) {
_realmerCollect(_realmIds[i]);
}
}
function _realmerCollect(uint256 _realmId) internal {
uint[] memory chamberIds = ANIMA_STAKING_REWARDS_STORAGE.realmChamberIds(
_realmId
);
for (uint i = 0; i < chamberIds.length; i++) {
_collect(chamberIds[i], false, true, true, false, new uint[](0));
}
}
function collectManager(
uint256 _tokenId,
bool _forStaker,
bool _forRealmer
) external onlyManager whenNotPaused {
_collect(_tokenId, _forStaker, _forRealmer, false, false, new uint[](0));
}
function registerChamberStaked(
uint256 _chamberId,
uint256 _realmId
) external onlyManager {
_collect(_chamberId, true, true, false, false, new uint[](0));
ANIMA_STAKING_REWARDS_STORAGE.registerChamberStaked(_chamberId, _realmId);
}
function unregisterChamberStaked(
uint256 _chamberId
) external onlyManager returns (bool wasStaked, uint realmId) {
(wasStaked, realmId) = ANIMA_STAKING_REWARDS_STORAGE.checkStaked(
_chamberId
);
if (wasStaked) {
_collect(_chamberId, true, true, false, false, new uint[](0));
ANIMA_STAKING_REWARDS_STORAGE.unregisterChamberStaked(
_chamberId,
realmId
);
}
}
function unregisterChamberStaked(
uint256 _chamberId,
uint256 _realmId
) external onlyManager returns (bool success) {
(bool isStaked, uint realmId) = ANIMA_STAKING_REWARDS_STORAGE.checkStaked(
_chamberId
);
if (isStaked && realmId == _realmId) {
_collect(_chamberId, true, true, false, false, new uint[](0));
ANIMA_STAKING_REWARDS_STORAGE.unregisterChamberStaked(
_chamberId,
_realmId
);
success = true;
}
}
function _collect(
uint256 _tokenId,
bool _forStaker,
bool _forRealmer,
bool _verifyOwnership,
bool _compound,
uint[] memory params
) internal {
require(
_forStaker || _forRealmer,
"AnimaStakingRewards: no rewards to emit"
);
ChamberRewardsStorage memory info = ANIMA_STAKING_REWARDS_STORAGE
.loadChamberInfo(_tokenId);
uint chamberAnima = ANIMA_CHAMBER_DATA.stakedAnima(_tokenId);
(
uint stakerRewards,
uint realmerRewards,
uint vestedStake
) = ANIMA_STAKING_REWARDS_CALCULATOR.calculateRewards(
chamberAnima,
info,
params
);
if (_forStaker && stakerRewards > 0) {
address chamberOwner = ANIMA_CHAMBER.ownerOf(_tokenId);
if (_verifyOwnership && chamberOwner != msg.sender) {
revert NotOwner(
chamberOwner,
msg.sender,
address(ANIMA_CHAMBER),
_tokenId
);
}
REWARDS_EMITTER.emitStakerRewards(_tokenId, stakerRewards, _compound);
}
RealmRewardsStorage memory realmInfo;
if (_forRealmer && realmerRewards > 0 && info.stakedAt > 0) {
address realmOwner = REALM.ownerOf(info.realmId);
if (_verifyOwnership && realmOwner != msg.sender) {
revert NotOwner(realmOwner, msg.sender, address(REALM), _tokenId);
}
realmInfo = ANIMA_STAKING_REWARDS_STORAGE.loadRealmInfo(info.realmId);
_calculateAvailableCapacityBasedOnTimeElapsed(realmInfo);
(
realmerRewards,
realmInfo.lastCapacityUsed
) = _updateRealmerRewardsBasedOnCapacity(
realmInfo.lastCapacityUsed,
info.realmId,
info.lastRealmerCollectedAt,
realmerRewards,
vestedStake
);
REWARDS_EMITTER.emitRealmerRewards(
_tokenId,
info.realmId,
realmerRewards
);
}
ANIMA_STAKING_REWARDS_STORAGE.updateStakingRewards(
_tokenId,
_forStaker && stakerRewards > 0,
_forRealmer && realmerRewards > 0,
realmInfo.lastCapacityUsed
);
}
function _calculateAvailableCapacityBasedOnTimeElapsed(
RealmRewardsStorage memory _info
) internal view {
uint elapsedTime = block.timestamp - uint(_info.lastCapacityAdjustedAt);
_info.lastCapacityAdjustedAt = uint32(block.timestamp);
if (elapsedTime > MAX_REWARDS_PERIOD) {
_info.lastCapacityUsed = 0;
return;
}
_info.lastCapacityUsed =
(_info.lastCapacityUsed * (MAX_REWARDS_PERIOD - elapsedTime)) /
MAX_REWARDS_PERIOD;
}
function _updateRealmerRewardsBasedOnCapacity(
uint _lastUsedCapacity,
uint _realmId,
uint _lastRealmerCollectedAt,
uint _realmerRewards,
uint _vestedStake
) internal view returns (uint, uint) {
if (_vestedStake <= 0 || _realmerRewards <= 0) {
return (0, 0);
}
uint _realmCapacity = RESOURCE.data(_realmId, resources.ANIMA_CAPACITY);
uint availableCapacity;
if (_realmCapacity > _lastUsedCapacity) {
availableCapacity = _realmCapacity - _lastUsedCapacity;
}
uint timeSinceLastCollected = block.timestamp - _lastRealmerCollectedAt;
if (timeSinceLastCollected > MAX_REWARDS_PERIOD) {
timeSinceLastCollected = MAX_REWARDS_PERIOD;
}
uint usedCapacity;
if (timeSinceLastCollected > 0) {
usedCapacity =
(_vestedStake * timeSinceLastCollected) /
MAX_REWARDS_PERIOD;
}
if (usedCapacity <= availableCapacity) {
return (_realmerRewards, _lastUsedCapacity + usedCapacity);
}
uint _fullRewards = (_realmerRewards * availableCapacity) / usedCapacity;
uint _capacityExceededRewards = ((_realmerRewards - _fullRewards) *
CAPACITY_EXCEEDED_REWARDS) / ONE_HUNDRED;
return (_fullRewards + _capacityExceededRewards, _realmCapacity);
}
function pause() external onlyPauser {
_pause();
}
function unpause() external onlyAdmin {
_unpause();
}
function updateAnimaChamberData(
address _animaChamberData
) external onlyAdmin {
ANIMA_CHAMBER_DATA = IAnimaChamberData(_animaChamberData);
}
function updateAnimaRewardsStorage(
address _animaRewardsStorage
) external onlyAdmin {
ANIMA_STAKING_REWARDS_STORAGE = IAnimaStakingRewardsStorage(
_animaRewardsStorage
);
}
function updateAnimaRewardsCalculator(
address _animaStakingRewardsCalculator
) external onlyAdmin {
ANIMA_STAKING_REWARDS_CALCULATOR = IAnimaStakingRewardsCalculator(
_animaStakingRewardsCalculator
);
MAX_REWARDS_PERIOD = ANIMA_STAKING_REWARDS_CALCULATOR.MAX_REWARDS_PERIOD();
}
function updateAnimaStakingRewardsEmitter(
address _rewardsEmitter
) external onlyAdmin {
REWARDS_EMITTER = IAnimaStakingRewardsEmitter(_rewardsEmitter);
}
function updateCapacityExceededRewards(
uint256 _capacity
) external onlyConfigManager {
CAPACITY_EXCEEDED_REWARDS = _capacity;
}
}
文件 2 的 21:ArrayUtils.sol
pragma solidity ^0.8.17;
library ArrayUtils {
error ArrayLengthMismatch(uint _length1, uint _length2);
error InvalidArrayOrder(uint index);
function ensureSameLength(uint _l1, uint _l2) internal pure {
if (_l1 != _l2) {
revert ArrayLengthMismatch(_l1, _l2);
}
}
function ensureSameLength(uint _l1, uint _l2, uint _l3) internal pure {
ensureSameLength(_l1, _l2);
ensureSameLength(_l1, _l3);
}
function ensureSameLength(
uint _l1,
uint _l2,
uint _l3,
uint _l4
) internal pure {
ensureSameLength(_l1, _l2);
ensureSameLength(_l1, _l3);
ensureSameLength(_l1, _l4);
}
function ensureSameLength(
uint _l1,
uint _l2,
uint _l3,
uint _l4,
uint _l5
) internal pure {
ensureSameLength(_l1, _l2);
ensureSameLength(_l1, _l3);
ensureSameLength(_l1, _l4);
ensureSameLength(_l1, _l5);
}
function checkForDuplicates(uint[] memory _ids) internal pure {
int lastId = -1;
for (uint i = 0; i < _ids.length; i++) {
if (int(_ids[i]) <= lastId) {
revert InvalidArrayOrder(i);
}
lastId = int(_ids[i]);
}
}
function checkForDuplicates(
address[] memory _tokenAddrs,
uint[] memory _tokenIds
) internal pure {
address lastAddress;
int256 lastTokenId = -1;
for (uint i = 0; i < _tokenAddrs.length; i++) {
if (_tokenAddrs[i] > lastAddress) {
lastTokenId = -1;
}
if (_tokenAddrs[i] < lastAddress || int(_tokenIds[i]) <= lastTokenId) {
revert InvalidArrayOrder(i);
}
lastAddress = _tokenAddrs[i];
lastTokenId = int(_tokenIds[i]);
}
}
function toSingleValueDoubleArray(
uint[] memory _vals
) internal pure returns (uint[][] memory result) {
result = new uint[][](_vals.length);
for (uint i = 0; i < _vals.length; i++) {
result[i] = ArrayUtils.toMemoryArray(_vals[i], 1);
}
}
function toMemoryArray(
uint _value,
uint _length
) internal pure returns (uint[] memory result) {
result = new uint[](_length);
for (uint i = 0; i < _length; i++) {
result[i] = _value;
}
}
function toMemoryArray(
uint[] calldata _value
) internal pure returns (uint[] memory result) {
result = new uint[](_value.length);
for (uint i = 0; i < _value.length; i++) {
result[i] = _value[i];
}
}
function toMemoryArray(
address _address,
uint _length
) internal pure returns (address[] memory result) {
result = new address[](_length);
for (uint i = 0; i < _length; i++) {
result[i] = _address;
}
}
function toMemoryArray(
address[] calldata _addresses
) internal pure returns (address[] memory result) {
result = new address[](_addresses.length);
for (uint i = 0; i < _addresses.length; i++) {
result[i] = _addresses[i];
}
}
}
文件 3 的 21: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;
}
}
文件 4 的 21:FloatingPointConstants.sol
pragma solidity ^0.8.17;
uint256 constant DECIMAL_POINT = 10 ** 3;
uint256 constant ROUNDING_ADJUSTER = DECIMAL_POINT - 1;
int256 constant SIGNED_DECIMAL_POINT = int256(DECIMAL_POINT);
uint256 constant ONE_HUNDRED = 100 * DECIMAL_POINT;
uint256 constant ONE_HUNDRED_SQUARE = ONE_HUNDRED * ONE_HUNDRED;
int256 constant SIGNED_ONE_HUNDRED = 100 * SIGNED_DECIMAL_POINT;
int256 constant SIGNED_ONE_HUNDRED_SQUARE = SIGNED_ONE_HUNDRED * SIGNED_ONE_HUNDRED;
int256 constant SIGNED_ZERO = 0;
文件 5 的 21:IAnimaChamber.sol
pragma solidity ^0.8.17;
import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
interface IAnimaChamber is IERC721 {
function burn(uint256 _tokenId) external;
function mintFor(address _for) external returns (uint256);
function tokensOfOwner(
address _owner
) external view returns (uint256[] memory);
}
文件 6 的 21:IAnimaChamberData.sol
pragma solidity ^0.8.17;
interface IAnimaChamberData {
function stakedAnima(uint256 _tokenId) external view returns (uint256);
function mintedAt(uint256 _tokenId) external view returns (uint256);
function stakedAnimaBatch(
uint256[] calldata _tokenId
) external view returns (uint256[] memory result);
function setStakedAnima(uint256 _tokenId, uint256 _amount) external;
function getAndResetStakedAnima(
uint _tokenId
) external returns (uint256 result);
}
文件 7 的 21:IAnimaStaker.sol
pragma solidity ^0.8.17;
interface IAnimaStaker {
function stake(uint256 _amount) external;
function stakeBatch(uint256[] calldata _amounts) external;
function unstake(uint256 _tokenId) external;
function unstakeBatch(uint256[] calldata _tokenId) external;
}
文件 8 的 21:IAnimaStakingRewards.sol
pragma solidity ^0.8.17;
interface IAnimaStakingRewards {
function stakerCollect(
uint256 _tokenId,
bool _compound,
uint[] calldata _params
) external;
function stakerCollectBatch(
uint256[] calldata _tokenId,
bool[] calldata _compound,
uint[][] calldata _params
) external;
function realmerCollect(uint256 _realmId) external;
function realmerCollectBatch(uint256[] calldata _realmIds) external;
function collectManager(
uint256 _tokenId,
bool _forStaker,
bool _forRealmer
) external;
function registerChamberStaked(uint256 _chamberId, uint256 _realmId) external;
function unregisterChamberStaked(
uint256 _chamberId
) external returns (bool wasStaked, uint realmId);
function unregisterChamberStaked(
uint256 _chamberId,
uint256 _realmId
) external returns (bool success);
}
文件 9 的 21:IAnimaStakingRewardsCalculator.sol
pragma solidity ^0.8.17;
import "./IAnimaStakingRewardsStorage.sol";
interface IAnimaStakingRewardsCalculator {
function MAX_REWARDS_PERIOD() external view returns (uint256);
function currentBaseRewards()
external
view
returns (
uint stakerRewards,
uint realmerRewards,
uint burnRatio,
uint rewardsPool
);
function baseRewardsAtEpochBatch(
uint startEpoch,
uint endEpoch
)
external
view
returns (
uint[] memory stakerRewards,
uint[] memory realmerRewards,
uint[] memory burnRatios,
uint[] memory rewardPools
);
function estimateChamberRewards(
uint _additionalAnima,
uint _realmId
) external view returns (uint boost, uint rewards, uint stakedAverage);
function estimateChamberRewardsBatch(
uint _additionalAnima,
uint[] calldata _realmId
)
external
view
returns (
uint[] memory bonuses,
uint[] memory rewards,
uint[] memory stakedAverage
);
function calculateRewardsView(
uint _animaAmount,
ChamberRewardsStorage memory _chamberInfo,
uint256[] calldata params
)
external
view
returns (
uint256 stakerRewards,
uint256 realmerRewards,
uint256 vestedStake
);
function calculateRewards(
uint _animaAmount,
ChamberRewardsStorage memory _chamberInfo,
uint256[] calldata params
)
external
returns (
uint256 stakerRewards,
uint256 realmerRewards,
uint256 vestedStake
);
}
文件 10 的 21:IAnimaStakingRewardsEmitter.sol
pragma solidity ^0.8.17;
interface IAnimaStakingRewardsEmitter {
event StakerRewardsEmitted(
uint _tokenId,
uint _amount,
address _receiver,
bool _compounded,
uint _totalAnimaStaked
);
event RealmerRewardsEmitted(
uint _tokenId,
uint _realmId,
uint _amount,
address _receiver
);
function emitStakerRewards(
uint _tokenId,
uint _rewardsAmount,
bool _compound
) external;
function emitRealmerRewards(
uint _tokenId,
uint _realmId,
uint _rewardsAmount
) external;
}
文件 11 的 21:IAnimaStakingRewardsStorage.sol
pragma solidity ^0.8.17;
struct ChamberRewardsStorage {
uint32 realmId;
uint32 mintedAt;
uint32 stakedAt;
uint32 chamberStakedIndex;
uint32 lastRealmerCollectedAt;
uint32 lastStakerCollectedAt;
}
struct RealmRewardsStorage {
uint32 lastCapacityAdjustedAt;
uint lastCapacityUsed;
}
error ChamberAlreadyStaked(uint _realmId, uint _chamberId);
error ChamberNotStaked(uint _realmId, uint _chamberId);
interface IAnimaStakingRewardsStorage {
function realmChamberIds(uint _realmId) external view returns (uint[] memory);
function loadChamberInfo(
uint256 _chamberId
) external view returns (ChamberRewardsStorage memory);
function loadRealmInfo(
uint256 _realmId
) external view returns (RealmRewardsStorage memory);
function updateStakingRewards(
uint256 _chamberId,
bool _updateStakerTimestamp,
bool _updateRealmerTimestamp,
uint256 _lastUsedCapacity
) external;
function stakedAmountWithDeltas(
uint _realmId,
uint _startEpoch,
uint _endEpoch
) external view returns (uint current, int[] memory deltas);
function checkStaked(
uint256 _chamberId
) external view returns (bool, uint256);
function registerChamberStaked(uint256 _chamberId, uint256 _realmId) external;
function registerChamberCompound(
uint256 _chamberId,
uint _rewardsAmount
) external;
function unregisterChamberStaked(
uint256 _chamberId,
uint256 _realmId
) external;
}
文件 12 的 21:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 13 的 21: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,
bytes calldata data
) external;
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 setApprovalForAll(address operator, bool _approved) external;
function getApproved(uint256 tokenId) external view returns (address operator);
function isApprovedForAll(address owner, address operator) external view returns (bool);
}
文件 14 的 21:IEpochConfigurable.sol
pragma solidity ^0.8.17;
interface IEpochConfigurable {
function currentEpoch() external view returns (uint);
function epochAtTimestamp(uint _timestamp) external view returns (uint);
}
文件 15 的 21:IManager.sol
pragma solidity ^0.8.4;
interface IManager {
function isAdmin(address _addr) external view returns (bool);
function isManager(address _addr, uint256 _type) external view returns (bool);
function addManager(address _addr, uint256 _type) external;
function removeManager(address _addr, uint256 _type) external;
function addAdmin(address _addr) external;
function removeAdmin(address _addr) external;
}
文件 16 的 21:IRealm.sol
pragma solidity ^0.8.4;
interface IRealm {
function balanceOf(address owner) external view returns (uint256);
function ownerOf(uint256 _realmId) external view returns (address owner);
function safeTransferFrom(address from, address to, uint256 tokenId) external;
function isApprovedForAll(
address owner,
address operator
) external returns (bool);
function realmFeatures(
uint256 realmId,
uint256 index
) external view returns (uint256);
}
文件 17 的 21:IResource.sol
pragma solidity ^0.8.4;
interface IResource {
function data(
uint256 _realmId,
uint256 _resourceId
) external view returns (uint256);
function add(uint256 _realmId, uint256 _resourceId, uint256 _amount) external;
function remove(
uint256 _realmId,
uint256 _resourceId,
uint256 _amount
) external;
}
文件 18 的 21:ITokenMinter.sol
pragma solidity ^0.8.17;
import "../Utils/IEpochConfigurable.sol";
uint constant MINTER_ADVENTURER_BUCKET = 1;
uint constant MINTER_REALM_BUCKET = 2;
uint constant MINTER_STAKER_BUCKET = 3;
interface ITokenMinter is IEpochConfigurable {
function getEpochValue(uint _epoch) external view returns (uint);
function getEpochValueBatch(
uint startEpoch,
uint endEpoch
) external view returns (uint[] memory result);
function getBucketEpochValueBatch(
uint _startEpoch,
uint _endEpoch,
uint _bucket
) external view returns (uint[] memory result);
function getEpochValueBatchTotal(
uint startEpoch,
uint endEpoch
) external view returns (uint result);
function getBucketEpochValueBatchTotal(
uint _startEpoch,
uint _endEpoch,
uint _bucket
) external view returns (uint result);
function mint(address _owner, uint _amount, uint _bucket) external;
}
文件 19 的 21:ManagerModifier.sol
pragma solidity ^0.8.4;
import "../Manager/IManager.sol";
abstract contract ManagerModifier {
IManager public immutable MANAGER;
constructor(address _manager) {
MANAGER = IManager(_manager);
}
modifier onlyAdmin() {
require(MANAGER.isAdmin(msg.sender), "Manager: Not an Admin");
_;
}
modifier onlyManager() {
require(MANAGER.isManager(msg.sender, 0), "Manager: Not manager");
_;
}
modifier onlyMinter() {
require(MANAGER.isManager(msg.sender, 1), "Manager: Not minter");
_;
}
modifier onlyTokenMinter() {
require(MANAGER.isManager(msg.sender, 2), "Manager: Not token minter");
_;
}
modifier onlyBinder() {
require(MANAGER.isManager(msg.sender, 3), "Manager: Not binder");
_;
}
modifier onlyConfigManager() {
require(MANAGER.isManager(msg.sender, 4), "Manager: Not config manager");
_;
}
modifier onlyTokenSpender() {
require(MANAGER.isManager(msg.sender, 5), "Manager: Not token spender");
_;
}
modifier onlyTokenEmitter() {
require(MANAGER.isManager(msg.sender, 6), "Manager: Not token emitter");
_;
}
modifier onlyPauser() {
require(
MANAGER.isAdmin(msg.sender) || MANAGER.isManager(msg.sender, 6),
"Manager: Not pauser"
);
_;
}
}
文件 20 的 21:Pausable.sol
pragma solidity ^0.8.0;
import "../utils/Context.sol";
abstract contract Pausable is Context {
event Paused(address account);
event Unpaused(address account);
bool private _paused;
constructor() {
_paused = false;
}
modifier whenNotPaused() {
_requireNotPaused();
_;
}
modifier whenPaused() {
_requirePaused();
_;
}
function paused() public view virtual returns (bool) {
return _paused;
}
function _requireNotPaused() internal view virtual {
require(!paused(), "Pausable: paused");
}
function _requirePaused() internal view virtual {
require(paused(), "Pausable: not paused");
}
function _pause() internal virtual whenNotPaused {
_paused = true;
emit Paused(_msgSender());
}
function _unpause() internal virtual whenPaused {
_paused = false;
emit Unpaused(_msgSender());
}
}
文件 21 的 21:ResourceConstants.sol
pragma solidity ^0.8.17;
library resources {
uint256 public constant MINERAL_DEPOSIT = 0;
uint256 public constant LAND_ABUNDANCE = 1;
uint256 public constant AQUATIC_RESOURCES = 2;
uint256 public constant ANCIENT_ARTIFACTS = 3;
uint256 public constant ANIMA_CAPACITY = 100;
uint256 public constant PARTICLE_CAPACITY = 110;
}
{
"compilationTarget": {
"contracts/AnimaStaking/AnimaStakingRewards.sol": "AnimaStakingRewards"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_manager","type":"address"},{"internalType":"address","name":"_realm","type":"address"},{"internalType":"address","name":"_animaChamber","type":"address"},{"internalType":"address","name":"_animaChamberData","type":"address"},{"internalType":"address","name":"_animaStakingRewardsData","type":"address"},{"internalType":"address","name":"_animaStakingRewardsCalculator","type":"address"},{"internalType":"address","name":"_rewardsEmitter","type":"address"},{"internalType":"address","name":"_resource","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"InvalidArrayOrder","type":"error"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_sender","type":"address"},{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"NotOwner","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"ANIMA_CHAMBER","outputs":[{"internalType":"contract IAnimaChamber","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ANIMA_CHAMBER_DATA","outputs":[{"internalType":"contract IAnimaChamberData","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ANIMA_STAKING_REWARDS_CALCULATOR","outputs":[{"internalType":"contract IAnimaStakingRewardsCalculator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ANIMA_STAKING_REWARDS_STORAGE","outputs":[{"internalType":"contract IAnimaStakingRewardsStorage","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"CAPACITY_EXCEEDED_REWARDS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MANAGER","outputs":[{"internalType":"contract IManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_REWARDS_PERIOD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REALM","outputs":[{"internalType":"contract IRealm","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RESOURCE","outputs":[{"internalType":"contract IResource","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REWARDS_EMITTER","outputs":[{"internalType":"contract IAnimaStakingRewardsEmitter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_realmIds","type":"uint256[]"}],"name":"availableRealmerRewards","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"uint256[][]","name":"_params","type":"uint256[][]"}],"name":"availableStakerRewards","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_forStaker","type":"bool"},{"internalType":"bool","name":"_forRealmer","type":"bool"}],"name":"collectManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_realmId","type":"uint256"}],"name":"realmerCollect","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_realmIds","type":"uint256[]"}],"name":"realmerCollectBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chamberId","type":"uint256"},{"internalType":"uint256","name":"_realmId","type":"uint256"}],"name":"registerChamberStaked","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_compound","type":"bool"},{"internalType":"uint256[]","name":"_params","type":"uint256[]"}],"name":"stakerCollect","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_tokenId","type":"uint256[]"},{"internalType":"bool[]","name":"_compound","type":"bool[]"},{"internalType":"uint256[][]","name":"_params","type":"uint256[][]"}],"name":"stakerCollectBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chamberId","type":"uint256"}],"name":"unregisterChamberStaked","outputs":[{"internalType":"bool","name":"wasStaked","type":"bool"},{"internalType":"uint256","name":"realmId","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_chamberId","type":"uint256"},{"internalType":"uint256","name":"_realmId","type":"uint256"}],"name":"unregisterChamberStaked","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_animaChamberData","type":"address"}],"name":"updateAnimaChamberData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_animaStakingRewardsCalculator","type":"address"}],"name":"updateAnimaRewardsCalculator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_animaRewardsStorage","type":"address"}],"name":"updateAnimaRewardsStorage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsEmitter","type":"address"}],"name":"updateAnimaStakingRewardsEmitter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_capacity","type":"uint256"}],"name":"updateCapacityExceededRewards","outputs":[],"stateMutability":"nonpayable","type":"function"}]