编译器
0.8.19+commit.7dd6d404
文件 1 的 14: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 functionCallWithValue(target, data, 0, "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");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, 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) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
if (returndata.length > 0) {
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
文件 2 的 14:IBoostCalculator.sol
pragma solidity ^0.8.0;
interface IBoostCalculator {
function getBoostedAmountWrite(
address account,
uint256 amount,
uint256 previousAmount,
uint256 totalWeeklyEmissions
) external returns (uint256 adjustedAmount);
function MAX_BOOST_GRACE_WEEKS() external view returns (uint256);
function getBoostedAmount(
address account,
uint256 amount,
uint256 previousAmount,
uint256 totalWeeklyEmissions
) external view returns (uint256 adjustedAmount);
function getClaimableWithBoost(
address claimant,
uint256 previousAmount,
uint256 totalWeeklyEmissions
) external view returns (uint256 maxBoosted, uint256 boosted);
function getWeek() external view returns (uint256 week);
function locker() external view returns (address);
}
文件 3 的 14:IBoostDelegate.sol
pragma solidity 0.8.19;
interface IBoostDelegate {
function getFeePct(
address claimant,
address receiver,
uint amount,
uint previousAmount,
uint totalWeeklyEmissions
) external view returns (uint256 feePct);
function delegatedBoostCallback(
address claimant,
address receiver,
uint amount,
uint adjustedAmount,
uint fee,
uint previousAmount,
uint totalWeeklyEmissions
) external returns (bool success);
}
文件 4 的 14: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);
}
文件 5 的 14:IEmissionSchedule.sol
pragma solidity ^0.8.0;
interface IEmissionSchedule {
event LockParametersSet(uint256 lockWeeks, uint256 lockDecayWeeks);
event WeeklyPctScheduleSet(uint64[2][] schedule);
function getReceiverWeeklyEmissions(
uint256 id,
uint256 week,
uint256 totalWeeklyEmissions
) external returns (uint256);
function getTotalWeeklyEmissions(
uint256 week,
uint256 unallocatedTotal
) external returns (uint256 amount, uint256 lock);
function setLockParameters(uint64 _lockWeeks, uint64 _lockDecayWeeks) external returns (bool);
function setWeeklyPctSchedule(uint64[2][] calldata _schedule) external returns (bool);
function MAX_LOCK_WEEKS() external view returns (uint256);
function PRISMA_CORE() external view returns (address);
function getWeek() external view returns (uint256 week);
function getWeeklyPctSchedule() external view returns (uint64[2][] memory);
function guardian() external view returns (address);
function lockDecayWeeks() external view returns (uint64);
function lockWeeks() external view returns (uint64);
function owner() external view returns (address);
function vault() external view returns (address);
function voter() external view returns (address);
function weeklyPct() external view returns (uint64);
}
文件 6 的 14:IIncentiveVoting.sol
pragma solidity ^0.8.0;
interface IIncentiveVoting {
struct Vote {
uint256 id;
uint256 points;
}
struct LockData {
uint256 amount;
uint256 weeksToUnlock;
}
event AccountWeightRegistered(
address indexed account,
uint256 indexed week,
uint256 frozenBalance,
LockData[] registeredLockData
);
event ClearedVotes(address indexed account, uint256 indexed week);
event NewVotes(address indexed account, uint256 indexed week, Vote[] newVotes, uint256 totalPointsUsed);
function clearRegisteredWeight(address account) external returns (bool);
function clearVote(address account) external;
function getReceiverVotePct(uint256 id, uint256 week) external returns (uint256);
function getReceiverWeightWrite(uint256 idx) external returns (uint256);
function getTotalWeightWrite() external returns (uint256);
function registerAccountWeight(address account, uint256 minWeeks) external;
function registerAccountWeightAndVote(address account, uint256 minWeeks, Vote[] calldata votes) external;
function registerNewReceiver() external returns (uint256);
function setDelegateApproval(address _delegate, bool _isApproved) external;
function unfreeze(address account, bool keepVote) external returns (bool);
function vote(address account, Vote[] calldata votes, bool clearPrevious) external;
function MAX_LOCK_WEEKS() external view returns (uint256);
function MAX_POINTS() external view returns (uint256);
function getAccountCurrentVotes(address account) external view returns (Vote[] memory votes);
function getAccountRegisteredLocks(
address account
) external view returns (uint256 frozenWeight, LockData[] memory lockData);
function getReceiverWeight(uint256 idx) external view returns (uint256);
function getReceiverWeightAt(uint256 idx, uint256 week) external view returns (uint256);
function getTotalWeight() external view returns (uint256);
function getTotalWeightAt(uint256 week) external view returns (uint256);
function getWeek() external view returns (uint256 week);
function isApprovedDelegate(address owner, address caller) external view returns (bool isApproved);
function receiverCount() external view returns (uint256);
function receiverDecayRate(uint256) external view returns (uint32);
function receiverUpdatedWeek(uint256) external view returns (uint16);
function receiverWeeklyUnlocks(uint256, uint256) external view returns (uint32);
function tokenLocker() external view returns (address);
function totalDecayRate() external view returns (uint32);
function totalUpdatedWeek() external view returns (uint16);
function totalWeeklyUnlocks(uint256) external view returns (uint32);
function vault() external view returns (address);
}
文件 7 的 14:IPrismaCore.sol
pragma solidity ^0.8.0;
interface IPrismaCore {
event FeeReceiverSet(address feeReceiver);
event GuardianSet(address guardian);
event NewOwnerAccepted(address oldOwner, address owner);
event NewOwnerCommitted(address owner, address pendingOwner, uint256 deadline);
event NewOwnerRevoked(address owner, address revokedOwner);
event Paused();
event PriceFeedSet(address priceFeed);
event Unpaused();
function acceptTransferOwnership() external;
function commitTransferOwnership(address newOwner) external;
function revokeTransferOwnership() external;
function setFeeReceiver(address _feeReceiver) external;
function setGuardian(address _guardian) external;
function setPaused(bool _paused) external;
function setPriceFeed(address _priceFeed) external;
function OWNERSHIP_TRANSFER_DELAY() external view returns (uint256);
function feeReceiver() external view returns (address);
function guardian() external view returns (address);
function owner() external view returns (address);
function ownershipTransferDeadline() external view returns (uint256);
function paused() external view returns (bool);
function pendingOwner() external view returns (address);
function priceFeed() external view returns (address);
function startTime() external view returns (uint256);
}
文件 8 的 14:IPrismaToken.sol
pragma solidity ^0.8.0;
interface IPrismaToken {
event Approval(address indexed owner, address indexed spender, uint256 value);
event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
event ReceiveFromChain(uint16 indexed _srcChainId, address indexed _to, uint256 _amount);
event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);
event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes _toAddress, uint256 _amount);
event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint256 _minDstGas);
event SetPrecrime(address precrime);
event SetTrustedRemote(uint16 _remoteChainId, bytes _path);
event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);
event SetUseCustomAdapterParams(bool _useCustomAdapterParams);
event Transfer(address indexed from, address indexed to, uint256 value);
function approve(address spender, uint256 amount) external returns (bool);
function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);
function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;
function increaseAllowance(address spender, uint256 addedValue) external returns (bool);
function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;
function mintToVault(uint256 _totalSupply) external returns (bool);
function nonblockingLzReceive(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint64 _nonce,
bytes calldata _payload
) external;
function permit(
address owner,
address spender,
uint256 amount,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function renounceOwnership() external;
function setConfig(uint16 _version, uint16 _chainId, uint256 _configType, bytes calldata _config) external;
function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint256 _minGas) external;
function setPayloadSizeLimit(uint16 _dstChainId, uint256 _size) external;
function setPrecrime(address _precrime) external;
function setReceiveVersion(uint16 _version) external;
function setSendVersion(uint16 _version) external;
function setTrustedRemote(uint16 _srcChainId, bytes calldata _path) external;
function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external;
function setUseCustomAdapterParams(bool _useCustomAdapterParams) external;
function transfer(address to, uint256 amount) external returns (bool);
function transferFrom(address from, address to, uint256 amount) external returns (bool);
function transferOwnership(address newOwner) external;
function transferToLocker(address sender, uint256 amount) external returns (bool);
function retryMessage(
uint16 _srcChainId,
bytes calldata _srcAddress,
uint64 _nonce,
bytes calldata _payload
) external payable;
function sendFrom(
address _from,
uint16 _dstChainId,
bytes calldata _toAddress,
uint256 _amount,
address _refundAddress,
address _zroPaymentAddress,
bytes calldata _adapterParams
) external payable;
function DEFAULT_PAYLOAD_SIZE_LIMIT() external view returns (uint256);
function NO_EXTRA_GAS() external view returns (uint256);
function PT_SEND() external view returns (uint16);
function allowance(address owner, address spender) external view returns (uint256);
function balanceOf(address account) external view returns (uint256);
function circulatingSupply() external view returns (uint256);
function decimals() external view returns (uint8);
function domainSeparator() external view returns (bytes32);
function estimateSendFee(
uint16 _dstChainId,
bytes calldata _toAddress,
uint256 _amount,
bool _useZro,
bytes calldata _adapterParams
) external view returns (uint256 nativeFee, uint256 zroFee);
function failedMessages(uint16, bytes calldata, uint64) external view returns (bytes32);
function getConfig(
uint16 _version,
uint16 _chainId,
address,
uint256 _configType
) external view returns (bytes memory);
function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory);
function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);
function locker() external view returns (address);
function lzEndpoint() external view returns (address);
function maxTotalSupply() external view returns (uint256);
function minDstGasLookup(uint16, uint16) external view returns (uint256);
function name() external view returns (string memory);
function nonces(address owner) external view returns (uint256);
function owner() external view returns (address);
function payloadSizeLimitLookup(uint16) external view returns (uint256);
function permitTypeHash() external view returns (bytes32);
function precrime() external view returns (address);
function supportsInterface(bytes4 interfaceId) external view returns (bool);
function symbol() external view returns (string memory);
function token() external view returns (address);
function totalSupply() external view returns (uint256);
function trustedRemoteLookup(uint16) external view returns (bytes memory);
function useCustomAdapterParams() external view returns (bool);
function vault() external view returns (address);
function version() external view returns (string memory);
}
文件 9 的 14:ITokenLocker.sol
pragma solidity ^0.8.0;
interface ITokenLocker {
struct LockData {
uint256 amount;
uint256 weeksToUnlock;
}
struct ExtendLockData {
uint256 amount;
uint256 currentWeeks;
uint256 newWeeks;
}
event LockCreated(address indexed account, uint256 amount, uint256 _weeks);
event LockExtended(address indexed account, uint256 amount, uint256 _weeks, uint256 newWeeks);
event LocksCreated(address indexed account, LockData[] newLocks);
event LocksExtended(address indexed account, ExtendLockData[] locks);
event LocksFrozen(address indexed account, uint256 amount);
event LocksUnfrozen(address indexed account, uint256 amount);
event LocksWithdrawn(address indexed account, uint256 withdrawn, uint256 penalty);
function extendLock(uint256 _amount, uint256 _weeks, uint256 _newWeeks) external returns (bool);
function extendMany(ExtendLockData[] calldata newExtendLocks) external returns (bool);
function freeze() external;
function getAccountWeightWrite(address account) external returns (uint256);
function getTotalWeightWrite() external returns (uint256);
function lock(address _account, uint256 _amount, uint256 _weeks) external returns (bool);
function lockMany(address _account, LockData[] calldata newLocks) external returns (bool);
function setPenaltyWithdrawalsEnabled(bool _enabled) external returns (bool);
function unfreeze(bool keepIncentivesVote) external;
function withdrawExpiredLocks(uint256 _weeks) external returns (bool);
function withdrawWithPenalty(uint256 amountToWithdraw) external returns (uint256);
function MAX_LOCK_WEEKS() external view returns (uint256);
function PRISMA_CORE() external view returns (address);
function getAccountActiveLocks(
address account,
uint256 minWeeks
) external view returns (LockData[] memory lockData, uint256 frozenAmount);
function getAccountBalances(address account) external view returns (uint256 locked, uint256 unlocked);
function getAccountWeight(address account) external view returns (uint256);
function getAccountWeightAt(address account, uint256 week) external view returns (uint256);
function getTotalWeight() external view returns (uint256);
function getTotalWeightAt(uint256 week) external view returns (uint256);
function getWeek() external view returns (uint256 week);
function getWithdrawWithPenaltyAmounts(
address account,
uint256 amountToWithdraw
) external view returns (uint256 amountWithdrawn, uint256 penaltyAmountPaid);
function guardian() external view returns (address);
function incentiveVoter() external view returns (address);
function lockToTokenRatio() external view returns (uint256);
function lockToken() external view returns (address);
function owner() external view returns (address);
function penaltyWithdrawalsEnabled() external view returns (bool);
function prismaCore() external view returns (address);
function totalDecayRate() external view returns (uint32);
function totalUpdatedWeek() external view returns (uint16);
}
文件 10 的 14:PrismaOwnable.sol
pragma solidity 0.8.19;
import "IPrismaCore.sol";
contract PrismaOwnable {
IPrismaCore public immutable PRISMA_CORE;
constructor(address _prismaCore) {
PRISMA_CORE = IPrismaCore(_prismaCore);
}
modifier onlyOwner() {
require(msg.sender == PRISMA_CORE.owner(), "Only owner");
_;
}
function owner() public view returns (address) {
return PRISMA_CORE.owner();
}
function guardian() public view returns (address) {
return PRISMA_CORE.guardian();
}
}
文件 11 的 14:SafeERC20.sol
pragma solidity ^0.8.0;
import "IERC20.sol";
import "draft-IERC20Permit.sol";
import "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 safePermit(
IERC20Permit token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
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");
}
}
}
文件 12 的 14:SystemStart.sol
pragma solidity 0.8.19;
import "IPrismaCore.sol";
contract SystemStart {
uint256 immutable startTime;
constructor(address prismaCore) {
startTime = IPrismaCore(prismaCore).startTime();
}
function getWeek() public view returns (uint256 week) {
return (block.timestamp - startTime) / 1 weeks;
}
}
文件 13 的 14:Vault.sol
pragma solidity 0.8.19;
import "SafeERC20.sol";
import "Address.sol";
import "PrismaOwnable.sol";
import "SystemStart.sol";
import "IPrismaToken.sol";
import "IEmissionSchedule.sol";
import "IIncentiveVoting.sol";
import "ITokenLocker.sol";
import "IBoostDelegate.sol";
import "IBoostCalculator.sol";
interface IEmissionReceiver {
function notifyRegisteredId(uint256[] memory assignedIds) external returns (bool);
}
interface IRewards {
function vaultClaimReward(address claimant, address receiver) external returns (uint256);
function claimableReward(address account) external view returns (uint256);
}
contract PrismaVault is PrismaOwnable, SystemStart {
using Address for address;
using SafeERC20 for IERC20;
IPrismaToken public immutable prismaToken;
ITokenLocker public immutable locker;
IIncentiveVoting public immutable voter;
address public immutable deploymentManager;
uint256 immutable lockToTokenRatio;
IEmissionSchedule public emissionSchedule;
IBoostCalculator public boostCalculator;
uint128 public unallocatedTotal;
uint64 public totalUpdateWeek;
uint64 public lockWeeks;
uint16[65535] public receiverUpdatedWeek;
mapping(uint256 => Receiver) public idToReceiver;
uint128[65535] public weeklyEmissions;
mapping(address => uint256) public allocated;
mapping(address => uint128[65535]) accountWeeklyEarned;
mapping(address => uint256) private storedPendingReward;
mapping(address => Delegation) public boostDelegation;
struct Receiver {
address account;
bool isActive;
}
struct Delegation {
bool isEnabled;
uint16 feePct;
IBoostDelegate callback;
}
struct InitialAllowance {
address receiver;
uint256 amount;
}
event NewReceiverRegistered(address receiver, uint256 id);
event ReceiverIsActiveStatusModified(uint256 indexed id, bool isActive);
event UnallocatedSupplyReduced(uint256 reducedAmount, uint256 unallocatedTotal);
event UnallocatedSupplyIncreased(uint256 increasedAmount, uint256 unallocatedTotal);
event IncreasedAllocation(address indexed receiver, uint256 increasedAmount);
event EmissionScheduleSet(address emissionScheduler);
event BoostCalculatorSet(address boostCalculator);
event BoostDelegationSet(address indexed boostDelegate, bool isEnabled, uint256 feePct, address callback);
constructor(
address _prismaCore,
IPrismaToken _token,
ITokenLocker _locker,
IIncentiveVoting _voter,
address _stabilityPool,
address _manager
) PrismaOwnable(_prismaCore) SystemStart(_prismaCore) {
prismaToken = _token;
locker = _locker;
voter = _voter;
lockToTokenRatio = _locker.lockToTokenRatio();
deploymentManager = _manager;
_voter.registerNewReceiver();
idToReceiver[0] = Receiver({ account: _stabilityPool, isActive: true });
emit NewReceiverRegistered(_stabilityPool, 0);
}
function setInitialParameters(
IEmissionSchedule _emissionSchedule,
IBoostCalculator _boostCalculator,
uint256 totalSupply,
uint64 initialLockWeeks,
uint128[] memory _fixedInitialAmounts,
InitialAllowance[] memory initialAllowances
) external {
require(msg.sender == deploymentManager, "!deploymentManager");
emissionSchedule = _emissionSchedule;
boostCalculator = _boostCalculator;
prismaToken.mintToVault(totalSupply);
uint256 totalAllocated;
uint256 length = _fixedInitialAmounts.length;
uint256 offset = getWeek() + 1;
for (uint256 i = 0; i < length; i++) {
uint128 amount = _fixedInitialAmounts[i];
weeklyEmissions[i + offset] = amount;
totalAllocated += amount;
}
length = initialAllowances.length;
for (uint256 i = 0; i < length; i++) {
uint256 amount = initialAllowances[i].amount;
address receiver = initialAllowances[i].receiver;
totalAllocated += amount;
prismaToken.increaseAllowance(receiver, amount);
}
unallocatedTotal = uint128(totalSupply - totalAllocated);
totalUpdateWeek = uint64(_fixedInitialAmounts.length + offset - 1);
lockWeeks = initialLockWeeks;
emit EmissionScheduleSet(address(_emissionSchedule));
emit BoostCalculatorSet(address(_boostCalculator));
emit UnallocatedSupplyReduced(totalAllocated, unallocatedTotal);
}
function registerReceiver(address receiver, uint256 count) external onlyOwner returns (bool) {
uint256[] memory assignedIds = new uint256[](count);
uint16 week = uint16(getWeek());
for (uint256 i = 0; i < count; i++) {
uint256 id = voter.registerNewReceiver();
assignedIds[i] = id;
receiverUpdatedWeek[id] = week;
idToReceiver[id] = Receiver({ account: receiver, isActive: true });
emit NewReceiverRegistered(receiver, id);
}
IEmissionReceiver(receiver).notifyRegisteredId(assignedIds);
return true;
}
function setReceiverIsActive(uint256 id, bool isActive) external onlyOwner returns (bool) {
Receiver memory receiver = idToReceiver[id];
require(receiver.account != address(0), "ID not set");
receiver.isActive = isActive;
idToReceiver[id] = receiver;
emit ReceiverIsActiveStatusModified(id, isActive);
return true;
}
function setEmissionSchedule(IEmissionSchedule _emissionSchedule) external onlyOwner returns (bool) {
_allocateTotalWeekly(emissionSchedule, getWeek());
emissionSchedule = _emissionSchedule;
emit EmissionScheduleSet(address(_emissionSchedule));
return true;
}
function setBoostCalculator(IBoostCalculator _boostCalculator) external onlyOwner returns (bool) {
boostCalculator = _boostCalculator;
emit BoostCalculatorSet(address(_boostCalculator));
return true;
}
function transferTokens(IERC20 token, address receiver, uint256 amount) external onlyOwner returns (bool) {
if (address(token) == address(prismaToken)) {
require(receiver != address(this), "Self transfer denied");
uint256 unallocated = unallocatedTotal - amount;
unallocatedTotal = uint128(unallocated);
emit UnallocatedSupplyReduced(amount, unallocated);
}
token.safeTransfer(receiver, amount);
return true;
}
function increaseUnallocatedSupply(uint256 amount) external returns (bool) {
prismaToken.transferFrom(msg.sender, address(this), amount);
uint256 unallocated = unallocatedTotal + amount;
unallocatedTotal = uint128(unallocated);
emit UnallocatedSupplyIncreased(amount, unallocated);
return true;
}
function _allocateTotalWeekly(IEmissionSchedule _emissionSchedule, uint256 currentWeek) internal {
uint256 week = totalUpdateWeek;
if (week >= currentWeek) return;
if (address(_emissionSchedule) == address(0)) {
totalUpdateWeek = uint64(currentWeek);
return;
}
uint256 lock;
uint256 weeklyAmount;
uint256 unallocated = unallocatedTotal;
while (week < currentWeek) {
++week;
(weeklyAmount, lock) = _emissionSchedule.getTotalWeeklyEmissions(week, unallocated);
weeklyEmissions[week] = uint128(weeklyAmount);
unallocated = unallocated - weeklyAmount;
emit UnallocatedSupplyReduced(weeklyAmount, unallocated);
}
unallocatedTotal = uint128(unallocated);
totalUpdateWeek = uint64(currentWeek);
lockWeeks = uint64(lock);
}
function allocateNewEmissions(uint256 id) external returns (uint256) {
Receiver memory receiver = idToReceiver[id];
require(receiver.account == msg.sender, "Receiver not registered");
uint256 week = receiverUpdatedWeek[id];
uint256 currentWeek = getWeek();
if (week == currentWeek) return 0;
IEmissionSchedule _emissionSchedule = emissionSchedule;
_allocateTotalWeekly(_emissionSchedule, currentWeek);
if (address(_emissionSchedule) == address(0)) {
receiverUpdatedWeek[id] = uint16(currentWeek);
return 0;
}
uint256 amount;
while (week < currentWeek) {
++week;
amount = amount + _emissionSchedule.getReceiverWeeklyEmissions(id, week, weeklyEmissions[week]);
}
receiverUpdatedWeek[id] = uint16(currentWeek);
if (receiver.isActive) {
allocated[msg.sender] = allocated[msg.sender] + amount;
emit IncreasedAllocation(msg.sender, amount);
return amount;
} else {
uint256 unallocated = unallocatedTotal + amount;
unallocatedTotal = uint128(unallocated);
emit UnallocatedSupplyIncreased(amount, unallocated);
return 0;
}
}
function transferAllocatedTokens(address claimant, address receiver, uint256 amount) external returns (bool) {
if (amount > 0) {
allocated[msg.sender] -= amount;
_transferAllocated(0, claimant, receiver, address(0), amount);
}
return true;
}
function batchClaimRewards(
address receiver,
address boostDelegate,
IRewards[] calldata rewardContracts,
uint256 maxFeePct
) external returns (bool) {
require(maxFeePct <= 10000, "Invalid maxFeePct");
uint256 total;
uint256 length = rewardContracts.length;
for (uint256 i = 0; i < length; i++) {
uint256 amount = rewardContracts[i].vaultClaimReward(msg.sender, receiver);
allocated[address(rewardContracts[i])] -= amount;
total += amount;
}
_transferAllocated(maxFeePct, msg.sender, receiver, boostDelegate, total);
return true;
}
function claimBoostDelegationFees(address receiver) external returns (bool) {
uint256 amount = storedPendingReward[msg.sender];
require(amount >= lockToTokenRatio, "Nothing to claim");
_transferOrLock(msg.sender, receiver, amount);
return true;
}
function _transferAllocated(
uint256 maxFeePct,
address account,
address receiver,
address boostDelegate,
uint256 amount
) internal {
if (amount > 0) {
uint256 week = getWeek();
uint256 totalWeekly = weeklyEmissions[week];
address claimant = boostDelegate == address(0) ? account : boostDelegate;
uint256 previousAmount = accountWeeklyEarned[claimant][week];
uint256 fee;
IBoostDelegate delegateCallback;
if (boostDelegate != address(0)) {
Delegation memory data = boostDelegation[boostDelegate];
delegateCallback = data.callback;
require(data.isEnabled, "Invalid delegate");
if (data.feePct == type(uint16).max) {
fee = delegateCallback.getFeePct(account, receiver, amount, previousAmount, totalWeekly);
require(fee <= 10000, "Invalid delegate fee");
} else fee = data.feePct;
require(fee <= maxFeePct, "fee exceeds maxFeePct");
}
uint256 adjustedAmount = boostCalculator.getBoostedAmountWrite(
claimant,
amount,
previousAmount,
totalWeekly
);
{
uint256 boostUnclaimed = amount - adjustedAmount;
if (boostUnclaimed > 0) {
uint256 unallocated = unallocatedTotal + boostUnclaimed;
unallocatedTotal = uint128(unallocated);
emit UnallocatedSupplyIncreased(boostUnclaimed, unallocated);
}
}
accountWeeklyEarned[claimant][week] = uint128(previousAmount + amount);
if (fee != 0) {
fee = (adjustedAmount * fee) / 10000;
adjustedAmount -= fee;
}
adjustedAmount += storedPendingReward[account];
_transferOrLock(account, receiver, adjustedAmount);
if (fee != 0) storedPendingReward[boostDelegate] += fee;
if (address(delegateCallback) != address(0)) {
require(
delegateCallback.delegatedBoostCallback(
account,
receiver,
amount,
adjustedAmount,
fee,
previousAmount,
totalWeekly
),
"Delegate callback rejected"
);
}
}
}
function _transferOrLock(address claimant, address receiver, uint256 amount) internal {
uint256 _lockWeeks = lockWeeks;
if (_lockWeeks == 0) {
storedPendingReward[claimant] = 0;
prismaToken.transfer(receiver, amount);
} else {
uint256 lockAmount = amount / lockToTokenRatio;
storedPendingReward[claimant] = amount - lockAmount * lockToTokenRatio;
if (lockAmount > 0) locker.lock(receiver, lockAmount, _lockWeeks);
}
}
function claimableRewardAfterBoost(
address account,
address receiver,
address boostDelegate,
IRewards rewardContract
) external view returns (uint256 adjustedAmount, uint256 feeToDelegate) {
uint256 amount = rewardContract.claimableReward(account);
uint256 week = getWeek();
uint256 totalWeekly = weeklyEmissions[week];
address claimant = boostDelegate == address(0) ? account : boostDelegate;
uint256 previousAmount = accountWeeklyEarned[claimant][week];
uint256 fee;
if (boostDelegate != address(0)) {
Delegation memory data = boostDelegation[boostDelegate];
if (!data.isEnabled) return (0, 0);
fee = data.feePct;
if (fee == type(uint16).max) {
try data.callback.getFeePct(claimant, receiver, amount, previousAmount, totalWeekly) returns (
uint256 _fee
) {
fee = _fee;
} catch {
return (0, 0);
}
}
if (fee > 10000) return (0, 0);
}
adjustedAmount = boostCalculator.getBoostedAmount(claimant, amount, previousAmount, totalWeekly);
fee = (adjustedAmount * fee) / 10000;
return (adjustedAmount, fee);
}
function setBoostDelegationParams(bool isEnabled, uint256 feePct, address callback) external returns (bool) {
if (isEnabled) {
require(feePct <= 10000 || feePct == type(uint16).max, "Invalid feePct");
if (callback != address(0) || feePct == type(uint16).max) {
require(callback.isContract(), "Callback must be a contract");
}
boostDelegation[msg.sender] = Delegation({
isEnabled: true,
feePct: uint16(feePct),
callback: IBoostDelegate(callback)
});
} else {
delete boostDelegation[msg.sender];
}
emit BoostDelegationSet(msg.sender, isEnabled, feePct, callback);
return true;
}
function getClaimableWithBoost(address claimant) external view returns (uint256 maxBoosted, uint256 boosted) {
uint256 week = getWeek();
uint256 totalWeekly = weeklyEmissions[week];
uint256 previousAmount = accountWeeklyEarned[claimant][week];
return boostCalculator.getClaimableWithBoost(claimant, previousAmount, totalWeekly);
}
function claimableBoostDelegationFees(address claimant) external view returns (uint256 amount) {
amount = storedPendingReward[claimant];
return amount >= lockToTokenRatio ? amount : 0;
}
}
文件 14 的 14:draft-IERC20Permit.sol
pragma solidity ^0.8.0;
interface IERC20Permit {
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
function nonces(address owner) external view returns (uint256);
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
{
"compilationTarget": {
"Vault.sol": "PrismaVault"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_prismaCore","type":"address"},{"internalType":"contract IPrismaToken","name":"_token","type":"address"},{"internalType":"contract ITokenLocker","name":"_locker","type":"address"},{"internalType":"contract IIncentiveVoting","name":"_voter","type":"address"},{"internalType":"address","name":"_stabilityPool","type":"address"},{"internalType":"address","name":"_manager","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"boostCalculator","type":"address"}],"name":"BoostCalculatorSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"boostDelegate","type":"address"},{"indexed":false,"internalType":"bool","name":"isEnabled","type":"bool"},{"indexed":false,"internalType":"uint256","name":"feePct","type":"uint256"},{"indexed":false,"internalType":"address","name":"callback","type":"address"}],"name":"BoostDelegationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"emissionScheduler","type":"address"}],"name":"EmissionScheduleSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"increasedAmount","type":"uint256"}],"name":"IncreasedAllocation","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"}],"name":"NewReceiverRegistered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isActive","type":"bool"}],"name":"ReceiverIsActiveStatusModified","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"increasedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unallocatedTotal","type":"uint256"}],"name":"UnallocatedSupplyIncreased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reducedAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unallocatedTotal","type":"uint256"}],"name":"UnallocatedSupplyReduced","type":"event"},{"inputs":[],"name":"PRISMA_CORE","outputs":[{"internalType":"contract IPrismaCore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"allocateNewEmissions","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allocated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"boostDelegate","type":"address"},{"internalType":"contract IRewards[]","name":"rewardContracts","type":"address[]"},{"internalType":"uint256","name":"maxFeePct","type":"uint256"}],"name":"batchClaimRewards","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"boostCalculator","outputs":[{"internalType":"contract IBoostCalculator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"boostDelegation","outputs":[{"internalType":"bool","name":"isEnabled","type":"bool"},{"internalType":"uint16","name":"feePct","type":"uint16"},{"internalType":"contract IBoostDelegate","name":"callback","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"claimBoostDelegationFees","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"claimant","type":"address"}],"name":"claimableBoostDelegationFees","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"address","name":"boostDelegate","type":"address"},{"internalType":"contract IRewards","name":"rewardContract","type":"address"}],"name":"claimableRewardAfterBoost","outputs":[{"internalType":"uint256","name":"adjustedAmount","type":"uint256"},{"internalType":"uint256","name":"feeToDelegate","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"deploymentManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emissionSchedule","outputs":[{"internalType":"contract IEmissionSchedule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"claimant","type":"address"}],"name":"getClaimableWithBoost","outputs":[{"internalType":"uint256","name":"maxBoosted","type":"uint256"},{"internalType":"uint256","name":"boosted","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWeek","outputs":[{"internalType":"uint256","name":"week","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"idToReceiver","outputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"isActive","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"increaseUnallocatedSupply","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lockWeeks","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"locker","outputs":[{"internalType":"contract ITokenLocker","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"prismaToken","outputs":[{"internalType":"contract IPrismaToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"receiverUpdatedWeek","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"registerReceiver","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IBoostCalculator","name":"_boostCalculator","type":"address"}],"name":"setBoostCalculator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"isEnabled","type":"bool"},{"internalType":"uint256","name":"feePct","type":"uint256"},{"internalType":"address","name":"callback","type":"address"}],"name":"setBoostDelegationParams","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IEmissionSchedule","name":"_emissionSchedule","type":"address"}],"name":"setEmissionSchedule","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IEmissionSchedule","name":"_emissionSchedule","type":"address"},{"internalType":"contract IBoostCalculator","name":"_boostCalculator","type":"address"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint64","name":"initialLockWeeks","type":"uint64"},{"internalType":"uint128[]","name":"_fixedInitialAmounts","type":"uint128[]"},{"components":[{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct PrismaVault.InitialAllowance[]","name":"initialAllowances","type":"tuple[]"}],"name":"setInitialParameters","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bool","name":"isActive","type":"bool"}],"name":"setReceiverIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalUpdateWeek","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"claimant","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferAllocatedTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"address","name":"receiver","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferTokens","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unallocatedTotal","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"voter","outputs":[{"internalType":"contract IIncentiveVoting","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"weeklyEmissions","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"}]