文件 1 的 15:Address.sol
pragma solidity ^0.8.1;
library Address {
function isContract(address account) internal view returns (bool) {
return account.code.length > 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 functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
require(isContract(target), "Address: delegate call to non-contract");
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResult(success, returndata, errorMessage);
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal 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);
}
}
}
}
文件 2 的 15: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;
}
}
文件 3 的 15:ERC1155Holder.sol
pragma solidity ^0.8.0;
import "./ERC1155Receiver.sol";
contract ERC1155Holder is ERC1155Receiver {
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
return this.onERC1155BatchReceived.selector;
}
}
文件 4 的 15:ERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
}
}
文件 5 的 15:ERC165.sol
pragma solidity ^0.8.0;
import "./IERC165.sol";
abstract contract ERC165 is IERC165 {
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
文件 6 的 15:EthAndPrimeRewards.sol
pragma solidity 0.8.7;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
import "@openzeppelin/contracts/utils/math/SafeCast.sol";
import "./PrimeRewards.sol";
contract EthAndPrimeRewards is PrimeRewards {
using SafeERC20 for IERC20;
using SafeCast for uint256;
using SafeCast for int256;
struct EthCacheInfo {
int256 rewardDebt;
}
struct EthPoolInfo {
uint256 accEthPerShare;
uint256 allocPoint;
uint256 lastRewardTimestamp;
}
EthPoolInfo[] public ethPoolInfo;
uint256 public ethStartTimestamp;
uint256 public ethEndTimestamp;
uint256 public ethAmount;
uint256 public ethAmountPerSecond;
uint256 public constant ethAmountPerSecondPrecision = 1e18;
uint256 public ethTotalAllocPoint;
mapping(uint256 => mapping(address => EthCacheInfo)) public ethCacheInfo;
constructor(IERC20 _prime, IERC1155 _parallelAlpha)
PrimeRewards(_prime, _parallelAlpha)
{}
function addPool(uint256 _allocPoint, uint256[] memory _tokenIds)
public
override
onlyOwner
{
for (uint256 i = 0; i < ethPoolInfo.length; ++i) {
updateEthPool(i);
}
ethTotalAllocPoint += _allocPoint;
ethPoolInfo.push(
EthPoolInfo({
accEthPerShare: 0,
allocPoint: _allocPoint,
lastRewardTimestamp: Math.max(
block.timestamp,
ethStartTimestamp
)
})
);
PrimeRewards.addPool(_allocPoint, _tokenIds);
emit LogPoolSetAllocPoint(
ethPoolInfo.length - 1,
_allocPoint,
ethTotalAllocPoint,
ID_ETH
);
}
function setEthPerSecond(
uint256 _ethStartTimestamp,
uint256 _ethEndTimestamp
) external payable onlyOwner {
require(
_ethStartTimestamp < _ethEndTimestamp,
"endTimestamp cant be less than startTimestamp"
);
require(
block.timestamp < ethStartTimestamp ||
ethEndTimestamp < block.timestamp,
"Only updates after ethEndTimestamp or before ethStartTimestamp"
);
for (uint256 i = 0; i < ethPoolInfo.length; ++i) {
updateEthPool(i);
ethPoolInfo[i].lastRewardTimestamp = _ethStartTimestamp;
}
ethAmount = msg.value;
ethStartTimestamp = _ethStartTimestamp;
ethEndTimestamp = _ethEndTimestamp;
ethAmountPerSecond =
(msg.value * ethAmountPerSecondPrecision) /
(_ethEndTimestamp - _ethStartTimestamp);
emit LogSetPerSecond(
msg.value,
_ethStartTimestamp,
_ethEndTimestamp,
ID_ETH
);
}
function setEthEndTimestamp(uint256 _ethEndTimestamp) external onlyOwner {
require(
ethStartTimestamp < block.timestamp,
"Caching period has not started"
);
require(block.timestamp < _ethEndTimestamp, "invalid end timestamp");
for (uint256 i = 0; i < ethPoolInfo.length; ++i) {
updateEthPool(i);
}
ethStartTimestamp = block.timestamp;
ethEndTimestamp = _ethEndTimestamp;
ethAmountPerSecond =
(ethAmount * ethAmountPerSecondPrecision) /
(ethEndTimestamp - ethStartTimestamp);
emit EndTimestampUpdated(_ethEndTimestamp, ID_ETH);
}
function addEthAmount() external payable onlyOwner {
require(
ethStartTimestamp < block.timestamp &&
block.timestamp < ethEndTimestamp,
"Can only addEthAmount during period"
);
for (uint256 i = 0; i < ethPoolInfo.length; ++i) {
updateEthPool(i);
}
ethAmount += msg.value;
ethAmountPerSecond =
(ethAmount * ethAmountPerSecondPrecision) /
(ethEndTimestamp - block.timestamp);
emit RewardIncrease(msg.value, ID_ETH);
}
function removeEthAmount(uint256 _removeEthAmount) external onlyOwner {
require(
ethStartTimestamp < block.timestamp &&
block.timestamp < ethEndTimestamp,
"Can only removeEthAmount during period"
);
for (uint256 i = 0; i < ethPoolInfo.length; ++i) {
updateEthPool(i);
}
_removeEthAmount = Math.min(_removeEthAmount, ethAmount);
ethAmount -= _removeEthAmount;
ethAmountPerSecond =
(ethAmount * ethAmountPerSecondPrecision) /
(ethEndTimestamp - block.timestamp);
(bool sent, ) = msg.sender.call{ value: _removeEthAmount }("");
require(sent, "Failed to send Ether");
emit RewardDecrease(_removeEthAmount, ID_ETH);
}
function setEthPoolAllocPoint(uint256 _pid, uint256 _allocPoint)
external
onlyOwner
{
for (uint256 i = 0; i < ethPoolInfo.length; ++i) {
updateEthPool(i);
}
ethTotalAllocPoint =
ethTotalAllocPoint -
ethPoolInfo[_pid].allocPoint +
_allocPoint;
ethPoolInfo[_pid].allocPoint = _allocPoint;
emit LogPoolSetAllocPoint(
_pid,
_allocPoint,
ethTotalAllocPoint,
ID_ETH
);
}
function pendingEth(uint256 _pid, address _user)
external
view
returns (uint256 pending)
{
PoolInfo memory pool = poolInfo[_pid];
CacheInfo storage cache_ = cacheInfo[_pid][_user];
EthPoolInfo memory ethPool = ethPoolInfo[_pid];
EthCacheInfo storage ethCache = ethCacheInfo[_pid][_user];
uint256 accEthPerShare = ethPool.accEthPerShare;
uint256 totalSupply = pool.totalSupply;
if (
ethStartTimestamp <= block.timestamp &&
ethPool.lastRewardTimestamp < block.timestamp &&
totalSupply > 0
) {
uint256 updateToTimestamp = Math.min(
block.timestamp,
ethEndTimestamp
);
uint256 seconds_ = updateToTimestamp - ethPool.lastRewardTimestamp;
uint256 ethReward = (seconds_ *
ethAmountPerSecond *
ethPool.allocPoint) / ethTotalAllocPoint;
accEthPerShare += ethReward / totalSupply;
}
pending =
((cache_.amount * accEthPerShare).toInt256() - ethCache.rewardDebt)
.toUint256() /
ethAmountPerSecondPrecision;
}
function massUpdateEthPools(uint256[] calldata _pids) external {
uint256 len = _pids.length;
for (uint256 i = 0; i < len; ++i) {
updateEthPool(_pids[i]);
}
}
function updateEthPool(uint256 _pid) public {
PoolInfo memory pool = poolInfo[_pid];
EthPoolInfo storage ethPool = ethPoolInfo[_pid];
uint256 totalSupply = pool.totalSupply;
if (
ethStartTimestamp > block.timestamp ||
ethPool.lastRewardTimestamp >= block.timestamp ||
(ethStartTimestamp == 0 && ethEndTimestamp == 0)
) {
return;
}
uint256 updateToTimestamp = Math.min(block.timestamp, ethEndTimestamp);
uint256 seconds_ = updateToTimestamp - ethPool.lastRewardTimestamp;
uint256 ethReward = (seconds_ *
ethAmountPerSecond *
ethPool.allocPoint) / ethTotalAllocPoint;
ethAmount -= ethReward / ethAmountPerSecondPrecision;
if (totalSupply > 0) {
ethPool.accEthPerShare += ethReward / totalSupply;
}
ethPool.lastRewardTimestamp = updateToTimestamp;
emit LogUpdatePool(
_pid,
ethPool.lastRewardTimestamp,
totalSupply,
ethPool.accEthPerShare,
ID_ETH
);
}
function cache(uint256 _pid, uint256 _amount) public virtual override {
require(_amount > 0, "Specify valid token amount to cache");
updateEthPool(_pid);
EthCacheInfo storage ethCache = ethCacheInfo[_pid][msg.sender];
ethCache.rewardDebt += (_amount * ethPoolInfo[_pid].accEthPerShare)
.toInt256();
PrimeRewards.cache(_pid, _amount);
}
function withdraw(uint256 _pid, uint256 _amount) public virtual override {
updateEthPool(_pid);
EthCacheInfo storage ethCache = ethCacheInfo[_pid][msg.sender];
ethCache.rewardDebt -= (_amount * ethPoolInfo[_pid].accEthPerShare)
.toInt256();
PrimeRewards.withdraw(_pid, _amount);
}
function claimEth(uint256 _pid) public {
updateEthPool(_pid);
CacheInfo storage cache_ = cacheInfo[_pid][msg.sender];
EthCacheInfo storage ethCache = ethCacheInfo[_pid][msg.sender];
int256 accumulatedEth = (cache_.amount *
ethPoolInfo[_pid].accEthPerShare).toInt256();
uint256 _pendingEth = (accumulatedEth - ethCache.rewardDebt)
.toUint256() / ethAmountPerSecondPrecision;
ethCache.rewardDebt = accumulatedEth;
if (_pendingEth != 0) {
(bool sent, ) = msg.sender.call{ value: _pendingEth }("");
require(sent, "Failed to send Ether");
}
emit Claim(msg.sender, _pid, _pendingEth, ID_ETH);
}
function claimEthAndPrime(uint256 _pid) public virtual {
PrimeRewards.claimPrime(_pid);
claimEth(_pid);
}
function claimPools(uint256[] calldata _pids) external virtual {
for (uint256 i = 0; i < _pids.length; ++i) {
claimEthAndPrime(_pids[i]);
}
}
function withdrawAndClaimPrime(uint256 _pid, uint256 _amount)
public
virtual
override
{
updateEthPool(_pid);
EthCacheInfo storage ethCache = ethCacheInfo[_pid][msg.sender];
ethCache.rewardDebt -= (_amount * ethPoolInfo[_pid].accEthPerShare)
.toInt256();
PrimeRewards.withdrawAndClaimPrime(_pid, _amount);
}
function withdrawAndClaimEthAndPrime(uint256 _pid, uint256 _amount)
external
virtual
{
updateEthPool(_pid);
CacheInfo storage cache_ = cacheInfo[_pid][msg.sender];
EthCacheInfo storage ethCache = ethCacheInfo[_pid][msg.sender];
int256 accumulatedEth = (cache_.amount *
ethPoolInfo[_pid].accEthPerShare).toInt256();
uint256 _pendingEth = (accumulatedEth - ethCache.rewardDebt)
.toUint256() / ethAmountPerSecondPrecision;
ethCache.rewardDebt =
accumulatedEth -
(_amount * ethPoolInfo[_pid].accEthPerShare).toInt256();
if (_pendingEth != 0) {
(bool sent, ) = msg.sender.call{ value: _pendingEth }("");
require(sent, "Error sending eth");
}
PrimeRewards.withdrawAndClaimPrime(_pid, _amount);
emit Claim(msg.sender, _pid, _pendingEth, ID_ETH);
}
function emergencyWithdraw(uint256 _pid) public virtual override {
EthCacheInfo storage ethCache = ethCacheInfo[_pid][msg.sender];
ethCache.rewardDebt = 0;
PrimeRewards.emergencyWithdraw(_pid);
}
function sweepETH(address payable to, uint256 amount) public onlyOwner {
(bool sent, ) = to.call{ value: amount }("");
require(sent, "Failed to send Ether");
}
}
文件 7 的 15:IERC1155.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155 is IERC165 {
event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);
event TransferBatch(
address indexed operator,
address indexed from,
address indexed to,
uint256[] ids,
uint256[] values
);
event ApprovalForAll(address indexed account, address indexed operator, bool approved);
event URI(string value, uint256 indexed id);
function balanceOf(address account, uint256 id) external view returns (uint256);
function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
external
view
returns (uint256[] memory);
function setApprovalForAll(address operator, bool approved) external;
function isApprovedForAll(address account, address operator) external view returns (bool);
function safeTransferFrom(
address from,
address to,
uint256 id,
uint256 amount,
bytes calldata data
) external;
function safeBatchTransferFrom(
address from,
address to,
uint256[] calldata ids,
uint256[] calldata amounts,
bytes calldata data
) external;
}
文件 8 的 15:IERC1155Receiver.sol
pragma solidity ^0.8.0;
import "../../utils/introspection/IERC165.sol";
interface IERC1155Receiver is IERC165 {
function onERC1155Received(
address operator,
address from,
uint256 id,
uint256 value,
bytes calldata data
) external returns (bytes4);
function onERC1155BatchReceived(
address operator,
address from,
uint256[] calldata ids,
uint256[] calldata values,
bytes calldata data
) external returns (bytes4);
}
文件 9 的 15:IERC165.sol
pragma solidity ^0.8.0;
interface IERC165 {
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
文件 10 的 15:IERC20.sol
pragma solidity ^0.8.0;
interface IERC20 {
event Transfer(address indexed from, address indexed to, uint256 value);
event Approval(address indexed owner, address indexed spender, uint256 value);
function totalSupply() external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function transfer(address to, 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 from,
address to,
uint256 amount
) external returns (bool);
}
文件 11 的 15:Math.sol
pragma solidity ^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 & b) + (a ^ b) / 2;
}
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b + (a % b == 0 ? 0 : 1);
}
}
文件 12 的 15: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() {
_transferOwnership(_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 {
_transferOwnership(address(0));
}
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
文件 13 的 15:PrimeRewards.sol
pragma solidity 0.8.7;
pragma experimental ABIEncoderV2;
import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeCast.sol";
import "@openzeppelin/contracts/utils/math/Math.sol";
contract PrimeRewards is Ownable, ERC1155Holder {
using SafeERC20 for IERC20;
using SafeCast for uint256;
using SafeCast for int256;
struct CacheInfo {
uint256 amount;
int256 rewardDebt;
}
struct PoolInfo {
uint256 accPrimePerShare;
uint256 allocPoint;
uint256 lastRewardTimestamp;
uint256[] tokenIds;
uint256 totalSupply;
}
IERC20 public PRIME;
IERC1155 public immutable parallelAlpha;
PoolInfo[] public poolInfo;
mapping(uint256 => mapping(address => CacheInfo)) public cacheInfo;
uint256 public startTimestamp;
uint256 public endTimestamp;
uint256 public primeAmount;
uint256 public primeAmountPerSecond;
uint256 public constant primeAmountPerSecondPrecision = 1e18;
uint256 public primeUpdateCutoff = 1667304000;
uint256 public maxNumPools = 500;
uint256 public totalAllocPoint;
bool public cachingPaused;
uint256 public constant ID_PRIME = 0;
uint256 public constant ID_ETH = 1;
bool public onReceiveLocked = true;
event Cache(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 Claim(
address indexed user,
uint256 indexed pid,
uint256 amount,
uint256 indexed currencyId
);
event LogPoolAddition(uint256 indexed pid, uint256[] tokenIds);
event EndTimestampUpdated(uint256 endTimestamp, uint256 indexed currencyID);
event RewardIncrease(uint256 amount, uint256 indexed currencyID);
event RewardDecrease(uint256 amount, uint256 indexed currencyID);
event CachingPaused(bool cachingPaused);
event LogPoolSetAllocPoint(
uint256 indexed pid,
uint256 allocPoint,
uint256 totalAllocPoint,
uint256 indexed currencyId
);
event LogUpdatePool(
uint256 indexed pid,
uint256 lastRewardTimestamp,
uint256 supply,
uint256 accPerShare,
uint256 indexed currencyId
);
event LogSetPerSecond(
uint256 amount,
uint256 startTimestamp,
uint256 endTimestamp,
uint256 indexed currencyId
);
constructor(IERC20 _prime, IERC1155 _parallelAlpha) {
parallelAlpha = _parallelAlpha;
PRIME = _prime;
}
function setPrimeTokenAddress(IERC20 _prime) external onlyOwner {
require(
block.timestamp < primeUpdateCutoff,
"PRIME address update window has has passed"
);
PRIME = _prime;
}
function setMaxNumPools(uint256 _maxNumPools) external onlyOwner {
require(
_maxNumPools >= poolLength(),
"Can't set maxNumPools less than poolLength"
);
maxNumPools = _maxNumPools;
}
function poolLength() public view returns (uint256 pools) {
pools = poolInfo.length;
}
function getPoolTokenIds(uint256 _pid)
external
view
returns (uint256[] memory)
{
return poolInfo[_pid].tokenIds;
}
function updateAllPools() internal {
uint256 len = poolLength();
for (uint256 i = 0; i < len; ++i) {
updatePool(i);
}
}
function addPool(uint256 _allocPoint, uint256[] memory _tokenIds)
public
virtual
onlyOwner
{
require(poolInfo.length < maxNumPools, "Max num pools reached");
require(_tokenIds.length > 0, "TokenIds cannot be empty");
require(_allocPoint > 0, "Allocation point cannot be 0 or negative");
for (uint256 i = 0; i < poolInfo.length; ++i) {
updatePool(i);
require(
keccak256(abi.encodePacked(poolInfo[i].tokenIds)) !=
keccak256(abi.encodePacked(_tokenIds)),
"Pool with same tokenIds exists"
);
}
totalAllocPoint += _allocPoint;
poolInfo.push(
PoolInfo({
accPrimePerShare: 0,
allocPoint: _allocPoint,
lastRewardTimestamp: Math.max(block.timestamp, startTimestamp),
tokenIds: _tokenIds,
totalSupply: 0
})
);
emit LogPoolAddition(poolInfo.length - 1, _tokenIds);
emit LogPoolSetAllocPoint(
poolInfo.length - 1,
_allocPoint,
totalAllocPoint,
ID_PRIME
);
}
function setPrimePerSecond(
uint256 _startTimestamp,
uint256 _endTimestamp,
uint256 _primeAmount
) external onlyOwner {
require(
_startTimestamp < _endTimestamp,
"endTimestamp cant be less than startTimestamp"
);
require(
block.timestamp < startTimestamp || endTimestamp < block.timestamp,
"Only updates after endTimestamp or before startTimestamp"
);
for (uint256 i = 0; i < poolInfo.length; ++i) {
updatePool(i);
poolInfo[i].lastRewardTimestamp = _startTimestamp;
}
primeAmount = _primeAmount;
startTimestamp = _startTimestamp;
endTimestamp = _endTimestamp;
primeAmountPerSecond =
(_primeAmount * primeAmountPerSecondPrecision) /
(_endTimestamp - _startTimestamp);
emit LogSetPerSecond(
_primeAmount,
_startTimestamp,
_endTimestamp,
ID_PRIME
);
}
function setEndTimestamp(uint256 _endTimestamp) external onlyOwner {
require(
startTimestamp < block.timestamp,
"caching period has not started yet"
);
require(block.timestamp < _endTimestamp, "invalid end timestamp");
updateAllPools();
startTimestamp = block.timestamp;
endTimestamp = _endTimestamp;
primeAmountPerSecond =
(primeAmount * primeAmountPerSecondPrecision) /
(endTimestamp - startTimestamp);
emit EndTimestampUpdated(_endTimestamp, ID_PRIME);
}
function addPrimeAmount(uint256 _addPrimeAmount) external onlyOwner {
require(
startTimestamp < block.timestamp && block.timestamp < endTimestamp,
"Can only addPrimeAmount during period"
);
updateAllPools();
primeAmount += _addPrimeAmount;
primeAmountPerSecond =
(primeAmount * primeAmountPerSecondPrecision) /
(endTimestamp - block.timestamp);
emit RewardIncrease(_addPrimeAmount, ID_PRIME);
}
function removePrimeAmount(uint256 _removePrimeAmount) external onlyOwner {
require(
startTimestamp < block.timestamp && block.timestamp < endTimestamp,
"Can only removePrimeAmount during a period"
);
updateAllPools();
_removePrimeAmount = Math.min(_removePrimeAmount, primeAmount);
primeAmount -= _removePrimeAmount;
primeAmountPerSecond =
(primeAmount * primeAmountPerSecondPrecision) /
(endTimestamp - block.timestamp);
emit RewardDecrease(_removePrimeAmount, ID_PRIME);
}
function setPoolAllocPoint(uint256 _pid, uint256 _allocPoint)
external
onlyOwner
{
updateAllPools();
totalAllocPoint =
totalAllocPoint -
poolInfo[_pid].allocPoint +
_allocPoint;
poolInfo[_pid].allocPoint = _allocPoint;
emit LogPoolSetAllocPoint(_pid, _allocPoint, totalAllocPoint, ID_PRIME);
}
function setCachingPaused(bool _cachingPaused) external onlyOwner {
cachingPaused = _cachingPaused;
emit CachingPaused(cachingPaused);
}
function getPoolCacheAmounts(
uint256[] calldata _pids,
address[] calldata _addresses
) external view returns (uint256[] memory) {
require(
_pids.length == _addresses.length,
"pids and addresses length mismatch"
);
uint256[] memory amounts = new uint256[](_pids.length);
for (uint256 i = 0; i < _pids.length; ++i) {
amounts[i] = cacheInfo[_pids[i]][_addresses[i]].amount;
}
return amounts;
}
function pendingPrime(uint256 _pid, address _user)
external
view
returns (uint256 pending)
{
PoolInfo memory pool = poolInfo[_pid];
CacheInfo storage _cache = cacheInfo[_pid][_user];
uint256 accPrimePerShare = pool.accPrimePerShare;
uint256 totalSupply = pool.totalSupply;
if (
startTimestamp <= block.timestamp &&
pool.lastRewardTimestamp < block.timestamp &&
totalSupply > 0
) {
uint256 updateToTimestamp = Math.min(block.timestamp, endTimestamp);
uint256 seconds_ = updateToTimestamp - pool.lastRewardTimestamp;
uint256 primeReward = (seconds_ *
primeAmountPerSecond *
pool.allocPoint) / totalAllocPoint;
accPrimePerShare += primeReward / totalSupply;
}
pending =
((_cache.amount * accPrimePerShare).toInt256() - _cache.rewardDebt)
.toUint256() /
primeAmountPerSecondPrecision;
}
function massUpdatePools(uint256[] calldata _pids) external {
uint256 len = _pids.length;
for (uint256 i = 0; i < len; ++i) {
updatePool(_pids[i]);
}
}
function updatePool(uint256 _pid) public {
PoolInfo storage pool = poolInfo[_pid];
if (
startTimestamp > block.timestamp ||
pool.lastRewardTimestamp >= block.timestamp ||
(startTimestamp == 0 && endTimestamp == 0)
) {
return;
}
uint256 updateToTimestamp = Math.min(block.timestamp, endTimestamp);
uint256 totalSupply = pool.totalSupply;
uint256 seconds_ = updateToTimestamp - pool.lastRewardTimestamp;
uint256 primeReward = (seconds_ *
primeAmountPerSecond *
pool.allocPoint) / totalAllocPoint;
primeAmount -= primeReward / primeAmountPerSecondPrecision;
if (totalSupply > 0) {
pool.accPrimePerShare += primeReward / totalSupply;
}
pool.lastRewardTimestamp = updateToTimestamp;
emit LogUpdatePool(
_pid,
pool.lastRewardTimestamp,
totalSupply,
pool.accPrimePerShare,
ID_PRIME
);
}
function cache(uint256 _pid, uint256 _amount) public virtual {
require(!cachingPaused, "Caching is paused");
require(_amount > 0, "Specify valid amount to cache");
updatePool(_pid);
CacheInfo storage _cache = cacheInfo[_pid][msg.sender];
uint256[] memory amounts = new uint256[](
poolInfo[_pid].tokenIds.length
);
for (uint256 i = 0; i < amounts.length; i++) {
amounts[i] = _amount;
}
poolInfo[_pid].totalSupply += _amount;
_cache.amount += _amount;
_cache.rewardDebt += (_amount * poolInfo[_pid].accPrimePerShare)
.toInt256();
onReceiveLocked = false;
parallelAlpha.safeBatchTransferFrom(
msg.sender,
address(this),
poolInfo[_pid].tokenIds,
amounts,
bytes("")
);
onReceiveLocked = true;
emit Cache(msg.sender, _pid, _amount);
}
function withdraw(uint256 _pid, uint256 _amount) public virtual {
updatePool(_pid);
CacheInfo storage _cache = cacheInfo[_pid][msg.sender];
uint256[] memory amounts = new uint256[](
poolInfo[_pid].tokenIds.length
);
for (uint256 i = 0; i < amounts.length; i++) {
amounts[i] = _amount;
}
poolInfo[_pid].totalSupply -= _amount;
_cache.rewardDebt -= (_amount * poolInfo[_pid].accPrimePerShare)
.toInt256();
_cache.amount -= _amount;
parallelAlpha.safeBatchTransferFrom(
address(this),
msg.sender,
poolInfo[_pid].tokenIds,
amounts,
bytes("")
);
emit Withdraw(msg.sender, _pid, _amount);
}
function claimPrime(uint256 _pid) public {
updatePool(_pid);
CacheInfo storage _cache = cacheInfo[_pid][msg.sender];
int256 accumulatedPrime = (_cache.amount *
poolInfo[_pid].accPrimePerShare).toInt256();
uint256 _pendingPrime = (accumulatedPrime - _cache.rewardDebt)
.toUint256() / primeAmountPerSecondPrecision;
_cache.rewardDebt = accumulatedPrime;
if (_pendingPrime != 0) {
PRIME.safeTransfer(msg.sender, _pendingPrime);
}
emit Claim(msg.sender, _pid, _pendingPrime, ID_PRIME);
}
function claimPrimePools(uint256[] calldata _pids) external virtual {
for (uint256 i = 0; i < _pids.length; ++i) {
claimPrime(_pids[i]);
}
}
function withdrawAndClaimPrime(uint256 _pid, uint256 _amount)
public
virtual
{
updatePool(_pid);
CacheInfo storage _cache = cacheInfo[_pid][msg.sender];
int256 accumulatedPrime = (_cache.amount *
poolInfo[_pid].accPrimePerShare).toInt256();
uint256 _pendingPrime = (accumulatedPrime - _cache.rewardDebt)
.toUint256() / primeAmountPerSecondPrecision;
uint256[] memory amounts = new uint256[](
poolInfo[_pid].tokenIds.length
);
for (uint256 i = 0; i < amounts.length; i++) {
amounts[i] = _amount;
}
poolInfo[_pid].totalSupply -= _amount;
_cache.rewardDebt =
accumulatedPrime -
(_amount * poolInfo[_pid].accPrimePerShare).toInt256();
_cache.amount -= _amount;
if (_pendingPrime != 0) {
PRIME.safeTransfer(msg.sender, _pendingPrime);
}
parallelAlpha.safeBatchTransferFrom(
address(this),
msg.sender,
poolInfo[_pid].tokenIds,
amounts,
bytes("")
);
emit Withdraw(msg.sender, _pid, _amount);
emit Claim(msg.sender, _pid, _pendingPrime, ID_PRIME);
}
function emergencyWithdraw(uint256 _pid) public virtual {
CacheInfo storage _cache = cacheInfo[_pid][msg.sender];
uint256 amount = _cache.amount;
uint256[] memory amounts = new uint256[](
poolInfo[_pid].tokenIds.length
);
for (uint256 i = 0; i < amounts.length; i++) {
amounts[i] = amount;
}
poolInfo[_pid].totalSupply -= amount;
_cache.rewardDebt = 0;
_cache.amount = 0;
parallelAlpha.safeBatchTransferFrom(
address(this),
msg.sender,
poolInfo[_pid].tokenIds,
amounts,
bytes("")
);
emit EmergencyWithdraw(msg.sender, _pid, amount);
}
function sweepERC20(
IERC20 erc20,
address to,
uint256 amount
) external onlyOwner {
erc20.transfer(to, amount);
}
function renounceOwnership() public virtual override onlyOwner {
revert("Ownership cannot be renounced");
}
function onERC1155Received(
address,
address,
uint256,
uint256,
bytes memory
) public virtual override returns (bytes4) {
require(onReceiveLocked == false, "onReceive is locked");
return this.onERC1155Received.selector;
}
function onERC1155BatchReceived(
address,
address,
uint256[] memory,
uint256[] memory,
bytes memory
) public virtual override returns (bytes4) {
require(onReceiveLocked == false, "onReceive is locked");
return this.onERC1155BatchReceived.selector;
}
}
文件 14 的 15:SafeCast.sol
pragma solidity ^0.8.0;
library SafeCast {
function toUint224(uint256 value) internal pure returns (uint224) {
require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
return uint224(value);
}
function toUint128(uint256 value) internal pure returns (uint128) {
require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
return uint128(value);
}
function toUint96(uint256 value) internal pure returns (uint96) {
require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
return uint96(value);
}
function toUint64(uint256 value) internal pure returns (uint64) {
require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
return uint64(value);
}
function toUint32(uint256 value) internal pure returns (uint32) {
require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
return uint32(value);
}
function toUint16(uint256 value) internal pure returns (uint16) {
require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
return uint16(value);
}
function toUint8(uint256 value) internal pure returns (uint8) {
require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
return uint8(value);
}
function toUint256(int256 value) internal pure returns (uint256) {
require(value >= 0, "SafeCast: value must be positive");
return uint256(value);
}
function toInt128(int256 value) internal pure returns (int128) {
require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
return int128(value);
}
function toInt64(int256 value) internal pure returns (int64) {
require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
return int64(value);
}
function toInt32(int256 value) internal pure returns (int32) {
require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
return int32(value);
}
function toInt16(int256 value) internal pure returns (int16) {
require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
return int16(value);
}
function toInt8(int256 value) internal pure returns (int8) {
require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
return int8(value);
}
function toInt256(uint256 value) internal pure returns (int256) {
require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
return int256(value);
}
}
文件 15 的 15:SafeERC20.sol
pragma solidity ^0.8.0;
import "../IERC20.sol";
import "../../../utils/Address.sol";
library SafeERC20 {
using Address for address;
function safeTransfer(
IERC20 token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20 token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
function safeApprove(
IERC20 token,
address spender,
uint256 value
) internal {
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20 token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function _callOptionalReturn(IERC20 token, bytes memory data) private {
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
{
"compilationTarget": {
"contracts/caching/EthAndPrimeRewards.sol": "EthAndPrimeRewards"
},
"evmVersion": "london",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs",
"useLiteralContent": true
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"contract IERC20","name":"_prime","type":"address"},{"internalType":"contract IERC1155","name":"_parallelAlpha","type":"address"}],"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":"Cache","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"cachingPaused","type":"bool"}],"name":"CachingPaused","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"},{"indexed":true,"internalType":"uint256","name":"currencyId","type":"uint256"}],"name":"Claim","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":[{"indexed":false,"internalType":"uint256","name":"endTimestamp","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyID","type":"uint256"}],"name":"EndTimestampUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"LogPoolAddition","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"allocPoint","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalAllocPoint","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyId","type":"uint256"}],"name":"LogPoolSetAllocPoint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTimestamp","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyId","type":"uint256"}],"name":"LogSetPerSecond","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"pid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"supply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"accPerShare","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyId","type":"uint256"}],"name":"LogUpdatePool","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":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyID","type":"uint256"}],"name":"RewardDecrease","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"currencyID","type":"uint256"}],"name":"RewardIncrease","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":"ID_ETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ID_PRIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRIME","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"addEthAmount","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_allocPoint","type":"uint256"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"addPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_addPrimeAmount","type":"uint256"}],"name":"addPrimeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"cache","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"cacheInfo","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"int256","name":"rewardDebt","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cachingPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"claimEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"claimEthAndPrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"}],"name":"claimPools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"claimPrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"}],"name":"claimPrimePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"endTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethAmountPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethAmountPerSecondPrecision","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"ethCacheInfo","outputs":[{"internalType":"int256","name":"rewardDebt","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethEndTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ethPoolInfo","outputs":[{"internalType":"uint256","name":"accEthPerShare","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethStartTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ethTotalAllocPoint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"},{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"getPoolCacheAmounts","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"getPoolTokenIds","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"}],"name":"massUpdateEthPools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_pids","type":"uint256[]"}],"name":"massUpdatePools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxNumPools","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":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"onReceiveLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"parallelAlpha","outputs":[{"internalType":"contract IERC1155","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingEth","outputs":[{"internalType":"uint256","name":"pending","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"address","name":"_user","type":"address"}],"name":"pendingPrime","outputs":[{"internalType":"uint256","name":"pending","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"poolInfo","outputs":[{"internalType":"uint256","name":"accPrimePerShare","type":"uint256"},{"internalType":"uint256","name":"allocPoint","type":"uint256"},{"internalType":"uint256","name":"lastRewardTimestamp","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolLength","outputs":[{"internalType":"uint256","name":"pools","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"primeAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"primeAmountPerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"primeAmountPerSecondPrecision","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"primeUpdateCutoff","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_removeEthAmount","type":"uint256"}],"name":"removeEthAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_removePrimeAmount","type":"uint256"}],"name":"removePrimeAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_cachingPaused","type":"bool"}],"name":"setCachingPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_endTimestamp","type":"uint256"}],"name":"setEndTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ethEndTimestamp","type":"uint256"}],"name":"setEthEndTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ethStartTimestamp","type":"uint256"},{"internalType":"uint256","name":"_ethEndTimestamp","type":"uint256"}],"name":"setEthPerSecond","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"}],"name":"setEthPoolAllocPoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxNumPools","type":"uint256"}],"name":"setMaxNumPools","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_allocPoint","type":"uint256"}],"name":"setPoolAllocPoint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_startTimestamp","type":"uint256"},{"internalType":"uint256","name":"_endTimestamp","type":"uint256"},{"internalType":"uint256","name":"_primeAmount","type":"uint256"}],"name":"setPrimePerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_prime","type":"address"}],"name":"setPrimeTokenAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"erc20","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sweepERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"sweepETH","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updateEthPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"}],"name":"updatePool","outputs":[],"stateMutability":"nonpayable","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":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawAndClaimEthAndPrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_pid","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawAndClaimPrime","outputs":[],"stateMutability":"nonpayable","type":"function"}]