编译器
0.8.19+commit.7dd6d404
文件 1 的 11: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 的 11:IDebtToken.sol
pragma solidity ^0.8.0;
interface IDebtToken {
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 burn(address _account, uint256 _amount) external;
function burnWithGasCompensation(address _account, uint256 _amount) external returns (bool);
function decreaseAllowance(address spender, uint256 subtractedValue) external returns (bool);
function enableTroveManager(address _troveManager) external;
function flashLoan(address receiver, address token, uint256 amount, bytes calldata data) 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 mint(address _account, uint256 _amount) external;
function mintWithGasCompensation(address _account, uint256 _amount) 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 returnFromPool(address _poolAddress, address _receiver, uint256 _amount) external;
function sendToSP(address _sender, uint256 _amount) 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 recipient, uint256 amount) external returns (bool);
function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
function transferOwnership(address newOwner) external;
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 DEBT_GAS_COMPENSATION() external view returns (uint256);
function DEFAULT_PAYLOAD_SIZE_LIMIT() external view returns (uint256);
function FLASH_LOAN_FEE() 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 borrowerOperationsAddress() external view returns (address);
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 factory() external view returns (address);
function failedMessages(uint16, bytes calldata, uint64) external view returns (bytes32);
function flashFee(address token, uint256 amount) external view returns (uint256);
function gasPool() external view returns (address);
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 lzEndpoint() external view returns (address);
function maxFlashLoan(address token) 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 stabilityPoolAddress() 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 troveManager(address) external view returns (bool);
function trustedRemoteLookup(uint16) external view returns (bytes memory);
function useCustomAdapterParams() external view returns (bool);
function version() external view returns (string memory);
}
文件 3 的 11: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);
}
文件 4 的 11: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);
}
文件 5 的 11:IVault.sol
pragma solidity ^0.8.0;
interface IPrismaVault {
struct InitialAllowance {
address receiver;
uint256 amount;
}
event BoostCalculatorSet(address boostCalculator);
event BoostDelegationSet(address indexed boostDelegate, bool isEnabled, uint256 feePct, address callback);
event EmissionScheduleSet(address emissionScheduler);
event IncreasedAllocation(address indexed receiver, uint256 increasedAmount);
event NewReceiverRegistered(address receiver, uint256 id);
event ReceiverIsActiveStatusModified(uint256 indexed id, bool isActive);
event UnallocatedSupplyIncreased(uint256 increasedAmount, uint256 unallocatedTotal);
event UnallocatedSupplyReduced(uint256 reducedAmount, uint256 unallocatedTotal);
function allocateNewEmissions(uint256 id) external returns (uint256);
function batchClaimRewards(
address receiver,
address boostDelegate,
address[] calldata rewardContracts,
uint256 maxFeePct
) external returns (bool);
function increaseUnallocatedSupply(uint256 amount) external returns (bool);
function registerReceiver(address receiver, uint256 count) external returns (bool);
function setBoostCalculator(address _boostCalculator) external returns (bool);
function setBoostDelegationParams(bool isEnabled, uint256 feePct, address callback) external returns (bool);
function setEmissionSchedule(address _emissionSchedule) external returns (bool);
function setInitialParameters(
address _emissionSchedule,
address _boostCalculator,
uint256 totalSupply,
uint64 initialLockWeeks,
uint128[] calldata _fixedInitialAmounts,
InitialAllowance[] calldata initialAllowances
) external;
function setReceiverIsActive(uint256 id, bool isActive) external returns (bool);
function transferAllocatedTokens(address claimant, address receiver, uint256 amount) external returns (bool);
function transferTokens(address token, address receiver, uint256 amount) external returns (bool);
function PRISMA_CORE() external view returns (address);
function allocated(address) external view returns (uint256);
function boostCalculator() external view returns (address);
function boostDelegation(address) external view returns (bool isEnabled, uint16 feePct, address callback);
function claimableRewardAfterBoost(
address account,
address receiver,
address boostDelegate,
address rewardContract
) external view returns (uint256 adjustedAmount, uint256 feeToDelegate);
function emissionSchedule() external view returns (address);
function getClaimableWithBoost(address claimant) external view returns (uint256 maxBoosted, uint256 boosted);
function getWeek() external view returns (uint256 week);
function guardian() external view returns (address);
function idToReceiver(uint256) external view returns (address account, bool isActive);
function lockWeeks() external view returns (uint64);
function locker() external view returns (address);
function owner() external view returns (address);
function claimableBoostDelegationFees(address claimant) external view returns (uint256 amount);
function prismaToken() external view returns (address);
function receiverUpdatedWeek(uint256) external view returns (uint16);
function totalUpdateWeek() external view returns (uint64);
function unallocatedTotal() external view returns (uint128);
function voter() external view returns (address);
function weeklyEmissions(uint256) external view returns (uint128);
}
文件 6 的 11:PrismaMath.sol
pragma solidity 0.8.19;
library PrismaMath {
uint256 internal constant DECIMAL_PRECISION = 1e18;
uint256 internal constant NICR_PRECISION = 1e20;
function _min(uint256 _a, uint256 _b) internal pure returns (uint256) {
return (_a < _b) ? _a : _b;
}
function _max(uint256 _a, uint256 _b) internal pure returns (uint256) {
return (_a >= _b) ? _a : _b;
}
function decMul(uint256 x, uint256 y) internal pure returns (uint256 decProd) {
uint256 prod_xy = x * y;
decProd = (prod_xy + (DECIMAL_PRECISION / 2)) / DECIMAL_PRECISION;
}
function _decPow(uint256 _base, uint256 _minutes) internal pure returns (uint256) {
if (_minutes > 525600000) {
_minutes = 525600000;
}
if (_minutes == 0) {
return DECIMAL_PRECISION;
}
uint256 y = DECIMAL_PRECISION;
uint256 x = _base;
uint256 n = _minutes;
while (n > 1) {
if (n % 2 == 0) {
x = decMul(x, x);
n = n / 2;
} else {
y = decMul(x, y);
x = decMul(x, x);
n = (n - 1) / 2;
}
}
return decMul(x, y);
}
function _getAbsoluteDifference(uint256 _a, uint256 _b) internal pure returns (uint256) {
return (_a >= _b) ? _a - _b : _b - _a;
}
function _computeNominalCR(uint256 _coll, uint256 _debt) internal pure returns (uint256) {
if (_debt > 0) {
return (_coll * NICR_PRECISION) / _debt;
}
else {
return 2 ** 256 - 1;
}
}
function _computeCR(uint256 _coll, uint256 _debt, uint256 _price) internal pure returns (uint256) {
if (_debt > 0) {
uint256 newCollRatio = (_coll * _price) / _debt;
return newCollRatio;
}
else {
return 2 ** 256 - 1;
}
}
function _computeCR(uint256 _coll, uint256 _debt) internal pure returns (uint256) {
if (_debt > 0) {
uint256 newCollRatio = (_coll) / _debt;
return newCollRatio;
}
else {
return 2 ** 256 - 1;
}
}
}
文件 7 的 11: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();
}
}
文件 8 的 11: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");
}
}
}
文件 9 的 11:StabilityPool.sol
pragma solidity 0.8.19;
import "SafeERC20.sol";
import "IERC20.sol";
import "PrismaOwnable.sol";
import "SystemStart.sol";
import "PrismaMath.sol";
import "IDebtToken.sol";
import "IVault.sol";
contract StabilityPool is PrismaOwnable, SystemStart {
using SafeERC20 for IERC20;
uint256 public constant DECIMAL_PRECISION = 1e18;
uint128 public constant SUNSET_DURATION = 180 days;
uint256 constant REWARD_DURATION = 1 weeks;
uint256 public constant emissionId = 0;
IDebtToken public immutable debtToken;
IPrismaVault public immutable vault;
address public immutable factory;
address public immutable liquidationManager;
uint128 public rewardRate;
uint32 public lastUpdate;
uint32 public periodFinish;
mapping(IERC20 collateral => uint256 index) public indexByCollateral;
IERC20[] public collateralTokens;
uint256 internal totalDebtTokenDeposits;
mapping(address => AccountDeposit) public accountDeposits;
mapping(address => Snapshots) public depositSnapshots;
mapping(address => uint256[256]) public depositSums;
mapping(address depositor => uint80[256] gains) public collateralGainsByDepositor;
mapping(address depositor => uint256 rewards) private storedPendingReward;
uint256 public P = DECIMAL_PRECISION;
uint256 public constant SCALE_FACTOR = 1e9;
uint128 public currentScale;
uint128 public currentEpoch;
mapping(uint128 => mapping(uint128 => uint256[256])) public epochToScaleToSums;
mapping(uint128 => mapping(uint128 => uint256)) public epochToScaleToG;
uint256 public lastPrismaError;
uint256 public lastCollateralError_Offset;
uint256 public lastDebtLossError_Offset;
mapping(uint16 => SunsetIndex) _sunsetIndexes;
Queue queue;
struct AccountDeposit {
uint128 amount;
uint128 timestamp;
}
struct Snapshots {
uint256 P;
uint256 G;
uint128 scale;
uint128 epoch;
}
struct SunsetIndex {
uint128 idx;
uint128 expiry;
}
struct Queue {
uint16 firstSunsetIndexKey;
uint16 nextSunsetIndexKey;
}
event StabilityPoolDebtBalanceUpdated(uint256 _newBalance);
event P_Updated(uint256 _P);
event S_Updated(uint256 idx, uint256 _S, uint128 _epoch, uint128 _scale);
event G_Updated(uint256 _G, uint128 _epoch, uint128 _scale);
event EpochUpdated(uint128 _currentEpoch);
event ScaleUpdated(uint128 _currentScale);
event DepositSnapshotUpdated(address indexed _depositor, uint256 _P, uint256 _G);
event UserDepositChanged(address indexed _depositor, uint256 _newDeposit);
event CollateralGainWithdrawn(address indexed _depositor, uint256[] _collateral);
event CollateralOverwritten(IERC20 oldCollateral, IERC20 newCollateral);
event RewardClaimed(address indexed account, address indexed recipient, uint256 claimed);
constructor(
address _prismaCore,
IDebtToken _debtTokenAddress,
IPrismaVault _vault,
address _factory,
address _liquidationManager
) PrismaOwnable(_prismaCore) SystemStart(_prismaCore) {
debtToken = _debtTokenAddress;
vault = _vault;
factory = _factory;
liquidationManager = _liquidationManager;
periodFinish = uint32(block.timestamp - 1);
}
function enableCollateral(IERC20 _collateral) external {
require(msg.sender == factory, "Not factory");
uint256 length = collateralTokens.length;
bool collateralEnabled;
for (uint256 i = 0; i < length; i++) {
if (collateralTokens[i] == _collateral) {
collateralEnabled = true;
break;
}
}
if (!collateralEnabled) {
Queue memory queueCached = queue;
if (queueCached.nextSunsetIndexKey > queueCached.firstSunsetIndexKey) {
SunsetIndex memory sIdx = _sunsetIndexes[queueCached.firstSunsetIndexKey];
if (sIdx.expiry < block.timestamp) {
delete _sunsetIndexes[queue.firstSunsetIndexKey++];
_overwriteCollateral(_collateral, sIdx.idx);
return;
}
}
collateralTokens.push(_collateral);
indexByCollateral[_collateral] = collateralTokens.length;
} else {
require(indexByCollateral[_collateral] > 0, "Collateral is sunsetting");
}
}
function _overwriteCollateral(IERC20 _newCollateral, uint256 idx) internal {
require(indexByCollateral[_newCollateral] == 0, "Collateral must be sunset");
uint256 length = collateralTokens.length;
require(idx < length, "Index too large");
uint256 externalLoopEnd = currentEpoch;
uint256 internalLoopEnd = currentScale;
for (uint128 i; i <= externalLoopEnd; ) {
for (uint128 j; j <= internalLoopEnd; ) {
epochToScaleToSums[i][j][idx] = 0;
unchecked {
++j;
}
}
unchecked {
++i;
}
}
indexByCollateral[_newCollateral] = idx + 1;
emit CollateralOverwritten(collateralTokens[idx], _newCollateral);
collateralTokens[idx] = _newCollateral;
}
function startCollateralSunset(IERC20 collateral) external onlyOwner {
require(indexByCollateral[collateral] > 0, "Collateral already sunsetting");
_sunsetIndexes[queue.nextSunsetIndexKey++] = SunsetIndex(
uint128(indexByCollateral[collateral] - 1),
uint128(block.timestamp + SUNSET_DURATION)
);
delete indexByCollateral[collateral];
}
function getTotalDebtTokenDeposits() external view returns (uint256) {
return totalDebtTokenDeposits;
}
function provideToSP(uint256 _amount) external {
require(!PRISMA_CORE.paused(), "Deposits are paused");
require(_amount > 0, "StabilityPool: Amount must be non-zero");
_triggerRewardIssuance();
_accrueDepositorCollateralGain(msg.sender);
uint256 compoundedDebtDeposit = getCompoundedDebtDeposit(msg.sender);
_accrueRewards(msg.sender);
debtToken.sendToSP(msg.sender, _amount);
uint256 newTotalDebtTokenDeposits = totalDebtTokenDeposits + _amount;
totalDebtTokenDeposits = newTotalDebtTokenDeposits;
emit StabilityPoolDebtBalanceUpdated(newTotalDebtTokenDeposits);
uint256 newDeposit = compoundedDebtDeposit + _amount;
accountDeposits[msg.sender] = AccountDeposit({
amount: uint128(newDeposit),
timestamp: uint128(block.timestamp)
});
_updateSnapshots(msg.sender, newDeposit);
emit UserDepositChanged(msg.sender, newDeposit);
}
function withdrawFromSP(uint256 _amount) external {
uint256 initialDeposit = accountDeposits[msg.sender].amount;
uint128 depositTimestamp = accountDeposits[msg.sender].timestamp;
require(initialDeposit > 0, "StabilityPool: User must have a non-zero deposit");
require(depositTimestamp < block.timestamp, "!Deposit and withdraw same block");
_triggerRewardIssuance();
_accrueDepositorCollateralGain(msg.sender);
uint256 compoundedDebtDeposit = getCompoundedDebtDeposit(msg.sender);
uint256 debtToWithdraw = PrismaMath._min(_amount, compoundedDebtDeposit);
_accrueRewards(msg.sender);
if (debtToWithdraw > 0) {
debtToken.returnFromPool(address(this), msg.sender, debtToWithdraw);
_decreaseDebt(debtToWithdraw);
}
uint256 newDeposit = compoundedDebtDeposit - debtToWithdraw;
accountDeposits[msg.sender] = AccountDeposit({ amount: uint128(newDeposit), timestamp: depositTimestamp });
_updateSnapshots(msg.sender, newDeposit);
emit UserDepositChanged(msg.sender, newDeposit);
}
function _triggerRewardIssuance() internal {
_updateG(_vestedEmissions());
uint256 _periodFinish = periodFinish;
uint256 lastUpdateWeek = (_periodFinish - startTime) / 1 weeks;
if (getWeek() >= lastUpdateWeek) {
uint256 amount = vault.allocateNewEmissions(emissionId);
if (amount > 0) {
if (block.timestamp < _periodFinish) {
uint256 remaining = _periodFinish - block.timestamp;
amount += remaining * rewardRate;
}
rewardRate = uint128(amount / REWARD_DURATION);
periodFinish = uint32(block.timestamp + REWARD_DURATION);
}
}
lastUpdate = uint32(block.timestamp);
}
function _vestedEmissions() internal view returns (uint256) {
uint256 updated = periodFinish;
if (updated > block.timestamp) updated = block.timestamp;
uint256 lastUpdateCached = lastUpdate;
if (lastUpdateCached >= updated) return 0;
uint256 duration = updated - lastUpdateCached;
return duration * rewardRate;
}
function _updateG(uint256 _prismaIssuance) internal {
uint256 totalDebt = totalDebtTokenDeposits;
if (totalDebt == 0 || _prismaIssuance == 0) {
return;
}
uint256 prismaPerUnitStaked;
prismaPerUnitStaked = _computePrismaPerUnitStaked(_prismaIssuance, totalDebt);
uint128 currentEpochCached = currentEpoch;
uint128 currentScaleCached = currentScale;
uint256 marginalPrismaGain = prismaPerUnitStaked * P;
uint256 newG = epochToScaleToG[currentEpochCached][currentScaleCached] + marginalPrismaGain;
epochToScaleToG[currentEpochCached][currentScaleCached] = newG;
emit G_Updated(newG, currentEpochCached, currentScaleCached);
}
function _computePrismaPerUnitStaked(
uint256 _prismaIssuance,
uint256 _totalDebtTokenDeposits
) internal returns (uint256) {
uint256 prismaNumerator = (_prismaIssuance * DECIMAL_PRECISION) + lastPrismaError;
uint256 prismaPerUnitStaked = prismaNumerator / _totalDebtTokenDeposits;
lastPrismaError = prismaNumerator - (prismaPerUnitStaked * _totalDebtTokenDeposits);
return prismaPerUnitStaked;
}
function offset(IERC20 collateral, uint256 _debtToOffset, uint256 _collToAdd) external virtual {
_offset(collateral, _debtToOffset, _collToAdd);
}
function _offset(IERC20 collateral, uint256 _debtToOffset, uint256 _collToAdd) internal {
require(msg.sender == liquidationManager, "StabilityPool: Caller is not Liquidation Manager");
uint256 idx = indexByCollateral[collateral];
idx -= 1;
uint256 totalDebt = totalDebtTokenDeposits;
if (totalDebt == 0 || _debtToOffset == 0) {
return;
}
_triggerRewardIssuance();
(uint256 collateralGainPerUnitStaked, uint256 debtLossPerUnitStaked) = _computeRewardsPerUnitStaked(
_collToAdd,
_debtToOffset,
totalDebt
);
_updateRewardSumAndProduct(collateralGainPerUnitStaked, debtLossPerUnitStaked, idx);
_decreaseDebt(_debtToOffset);
}
function _computeRewardsPerUnitStaked(
uint256 _collToAdd,
uint256 _debtToOffset,
uint256 _totalDebtTokenDeposits
) internal returns (uint256 collateralGainPerUnitStaked, uint256 debtLossPerUnitStaked) {
uint256 collateralNumerator = (_collToAdd * DECIMAL_PRECISION) + lastCollateralError_Offset;
if (_debtToOffset == _totalDebtTokenDeposits) {
debtLossPerUnitStaked = DECIMAL_PRECISION;
lastDebtLossError_Offset = 0;
} else {
uint256 debtLossNumerator = (_debtToOffset * DECIMAL_PRECISION) - lastDebtLossError_Offset;
debtLossPerUnitStaked = (debtLossNumerator / _totalDebtTokenDeposits) + 1;
lastDebtLossError_Offset = (debtLossPerUnitStaked * _totalDebtTokenDeposits) - debtLossNumerator;
}
collateralGainPerUnitStaked = collateralNumerator / _totalDebtTokenDeposits;
lastCollateralError_Offset = collateralNumerator - (collateralGainPerUnitStaked * _totalDebtTokenDeposits);
return (collateralGainPerUnitStaked, debtLossPerUnitStaked);
}
function _updateRewardSumAndProduct(
uint256 _collateralGainPerUnitStaked,
uint256 _debtLossPerUnitStaked,
uint256 idx
) internal {
uint256 currentP = P;
uint256 newP;
uint256 newProductFactor = uint256(DECIMAL_PRECISION) - _debtLossPerUnitStaked;
uint128 currentScaleCached = currentScale;
uint128 currentEpochCached = currentEpoch;
uint256 currentS = epochToScaleToSums[currentEpochCached][currentScaleCached][idx];
uint256 marginalCollateralGain = _collateralGainPerUnitStaked * currentP;
uint256 newS = currentS + marginalCollateralGain;
epochToScaleToSums[currentEpochCached][currentScaleCached][idx] = newS;
emit S_Updated(idx, newS, currentEpochCached, currentScaleCached);
if (newProductFactor == 0) {
currentEpoch = currentEpochCached + 1;
emit EpochUpdated(currentEpoch);
currentScale = 0;
emit ScaleUpdated(currentScale);
newP = DECIMAL_PRECISION;
} else if ((currentP * newProductFactor) / DECIMAL_PRECISION < SCALE_FACTOR) {
newP = (currentP * newProductFactor * SCALE_FACTOR) / DECIMAL_PRECISION;
currentScale = currentScaleCached + 1;
emit ScaleUpdated(currentScale);
} else {
newP = (currentP * newProductFactor) / DECIMAL_PRECISION;
}
require(newP > 0, "NewP");
P = newP;
emit P_Updated(newP);
}
function _decreaseDebt(uint256 _amount) internal {
uint256 newTotalDebtTokenDeposits = totalDebtTokenDeposits - _amount;
totalDebtTokenDeposits = newTotalDebtTokenDeposits;
emit StabilityPoolDebtBalanceUpdated(newTotalDebtTokenDeposits);
}
function getDepositorCollateralGain(address _depositor) external view returns (uint256[] memory collateralGains) {
collateralGains = new uint256[](collateralTokens.length);
uint256 P_Snapshot = depositSnapshots[_depositor].P;
if (P_Snapshot == 0) return collateralGains;
uint80[256] storage depositorGains = collateralGainsByDepositor[_depositor];
uint256 initialDeposit = accountDeposits[_depositor].amount;
uint128 epochSnapshot = depositSnapshots[_depositor].epoch;
uint128 scaleSnapshot = depositSnapshots[_depositor].scale;
uint256[256] storage sums = epochToScaleToSums[epochSnapshot][scaleSnapshot];
uint256[256] storage nextSums = epochToScaleToSums[epochSnapshot][scaleSnapshot + 1];
uint256[256] storage depSums = depositSums[_depositor];
for (uint256 i = 0; i < collateralGains.length; i++) {
collateralGains[i] = depositorGains[i];
if (sums[i] == 0) continue;
uint256 firstPortion = sums[i] - depSums[i];
uint256 secondPortion = nextSums[i] / SCALE_FACTOR;
collateralGains[i] += (initialDeposit * (firstPortion + secondPortion)) / P_Snapshot / DECIMAL_PRECISION;
}
return collateralGains;
}
function _accrueDepositorCollateralGain(address _depositor) private returns (bool hasGains) {
uint80[256] storage depositorGains = collateralGainsByDepositor[_depositor];
uint256 collaterals = collateralTokens.length;
uint256 initialDeposit = accountDeposits[_depositor].amount;
hasGains = false;
if (initialDeposit == 0) {
return hasGains;
}
uint128 epochSnapshot = depositSnapshots[_depositor].epoch;
uint128 scaleSnapshot = depositSnapshots[_depositor].scale;
uint256 P_Snapshot = depositSnapshots[_depositor].P;
uint256[256] storage sums = epochToScaleToSums[epochSnapshot][scaleSnapshot];
uint256[256] storage nextSums = epochToScaleToSums[epochSnapshot][scaleSnapshot + 1];
uint256[256] storage depSums = depositSums[_depositor];
for (uint256 i = 0; i < collaterals; i++) {
if (sums[i] == 0) continue;
hasGains = true;
uint256 firstPortion = sums[i] - depSums[i];
uint256 secondPortion = nextSums[i] / SCALE_FACTOR;
depositorGains[i] += uint80(
(initialDeposit * (firstPortion + secondPortion)) / P_Snapshot / DECIMAL_PRECISION
);
}
return (hasGains);
}
function claimableReward(address _depositor) external view returns (uint256) {
uint256 totalDebt = totalDebtTokenDeposits;
uint256 initialDeposit = accountDeposits[_depositor].amount;
if (totalDebt == 0 || initialDeposit == 0) {
return 0;
}
uint256 prismaNumerator = (_vestedEmissions() * DECIMAL_PRECISION) + lastPrismaError;
uint256 prismaPerUnitStaked = prismaNumerator / totalDebt;
uint256 marginalPrismaGain = prismaPerUnitStaked * P;
Snapshots memory snapshots = depositSnapshots[_depositor];
uint128 epochSnapshot = snapshots.epoch;
uint128 scaleSnapshot = snapshots.scale;
uint256 firstPortion;
uint256 secondPortion;
if (scaleSnapshot == currentScale) {
firstPortion = epochToScaleToG[epochSnapshot][scaleSnapshot] - snapshots.G + marginalPrismaGain;
secondPortion = epochToScaleToG[epochSnapshot][scaleSnapshot + 1] / SCALE_FACTOR;
} else {
firstPortion = epochToScaleToG[epochSnapshot][scaleSnapshot] - snapshots.G;
secondPortion = (epochToScaleToG[epochSnapshot][scaleSnapshot + 1] + marginalPrismaGain) / SCALE_FACTOR;
}
return (initialDeposit * (firstPortion + secondPortion)) / snapshots.P / DECIMAL_PRECISION;
}
function _claimableReward(address _depositor) private view returns (uint256) {
uint256 initialDeposit = accountDeposits[_depositor].amount;
if (initialDeposit == 0) {
return 0;
}
Snapshots memory snapshots = depositSnapshots[_depositor];
return _getPrismaGainFromSnapshots(initialDeposit, snapshots);
}
function _getPrismaGainFromSnapshots(
uint256 initialStake,
Snapshots memory snapshots
) internal view returns (uint256) {
uint128 epochSnapshot = snapshots.epoch;
uint128 scaleSnapshot = snapshots.scale;
uint256 G_Snapshot = snapshots.G;
uint256 P_Snapshot = snapshots.P;
uint256 firstPortion = epochToScaleToG[epochSnapshot][scaleSnapshot] - G_Snapshot;
uint256 secondPortion = epochToScaleToG[epochSnapshot][scaleSnapshot + 1] / SCALE_FACTOR;
uint256 prismaGain = (initialStake * (firstPortion + secondPortion)) / P_Snapshot / DECIMAL_PRECISION;
return prismaGain;
}
function getCompoundedDebtDeposit(address _depositor) public view returns (uint256) {
uint256 initialDeposit = accountDeposits[_depositor].amount;
if (initialDeposit == 0) {
return 0;
}
Snapshots memory snapshots = depositSnapshots[_depositor];
uint256 compoundedDeposit = _getCompoundedStakeFromSnapshots(initialDeposit, snapshots);
return compoundedDeposit;
}
function _getCompoundedStakeFromSnapshots(
uint256 initialStake,
Snapshots memory snapshots
) internal view returns (uint256) {
uint256 snapshot_P = snapshots.P;
uint128 scaleSnapshot = snapshots.scale;
uint128 epochSnapshot = snapshots.epoch;
if (epochSnapshot < currentEpoch) {
return 0;
}
uint256 compoundedStake;
uint128 scaleDiff = currentScale - scaleSnapshot;
if (scaleDiff == 0) {
compoundedStake = (initialStake * P) / snapshot_P;
} else if (scaleDiff == 1) {
compoundedStake = (initialStake * P) / snapshot_P / SCALE_FACTOR;
} else {
compoundedStake = 0;
}
if (compoundedStake < initialStake / 1e9) {
return 0;
}
return compoundedStake;
}
function claimCollateralGains(address recipient, uint256[] calldata collateralIndexes) external virtual {
_claimCollateralGains(recipient, collateralIndexes);
}
function _claimCollateralGains(address recipient, uint256[] calldata collateralIndexes) internal {
uint256 loopEnd = collateralIndexes.length;
uint256[] memory collateralGains = new uint256[](collateralTokens.length);
uint80[256] storage depositorGains = collateralGainsByDepositor[msg.sender];
for (uint256 i; i < loopEnd; ) {
uint256 collateralIndex = collateralIndexes[i];
uint256 gains = depositorGains[collateralIndex];
if (gains > 0) {
collateralGains[collateralIndex] = gains;
depositorGains[collateralIndex] = 0;
collateralTokens[collateralIndex].safeTransfer(recipient, gains);
}
unchecked {
++i;
}
}
emit CollateralGainWithdrawn(msg.sender, collateralGains);
}
function _updateSnapshots(address _depositor, uint256 _newValue) internal {
uint256 length;
if (_newValue == 0) {
delete depositSnapshots[_depositor];
length = collateralTokens.length;
for (uint256 i = 0; i < length; i++) {
depositSums[_depositor][i] = 0;
}
emit DepositSnapshotUpdated(_depositor, 0, 0);
return;
}
uint128 currentScaleCached = currentScale;
uint128 currentEpochCached = currentEpoch;
uint256 currentP = P;
uint256[256] storage currentS = epochToScaleToSums[currentEpochCached][currentScaleCached];
uint256 currentG = epochToScaleToG[currentEpochCached][currentScaleCached];
depositSnapshots[_depositor].P = currentP;
depositSnapshots[_depositor].G = currentG;
depositSnapshots[_depositor].scale = currentScaleCached;
depositSnapshots[_depositor].epoch = currentEpochCached;
length = collateralTokens.length;
for (uint256 i = 0; i < length; i++) {
depositSums[_depositor][i] = currentS[i];
}
emit DepositSnapshotUpdated(_depositor, currentP, currentG);
}
function _accrueRewards(address _depositor) internal {
uint256 amount = _claimableReward(_depositor);
storedPendingReward[_depositor] = storedPendingReward[_depositor] + amount;
}
function claimReward(address recipient) external returns (uint256 amount) {
amount = _claimReward(msg.sender);
if (amount > 0) {
vault.transferAllocatedTokens(msg.sender, recipient, amount);
}
emit RewardClaimed(msg.sender, recipient, amount);
return amount;
}
function vaultClaimReward(address claimant, address) external returns (uint256 amount) {
require(msg.sender == address(vault));
return _claimReward(claimant);
}
function _claimReward(address account) internal returns (uint256 amount) {
uint256 initialDeposit = accountDeposits[account].amount;
if (initialDeposit > 0) {
uint128 depositTimestamp = accountDeposits[account].timestamp;
_triggerRewardIssuance();
bool hasGains = _accrueDepositorCollateralGain(account);
uint256 compoundedDebtDeposit = getCompoundedDebtDeposit(account);
uint256 debtLoss = initialDeposit - compoundedDebtDeposit;
amount = _claimableReward(account);
if (debtLoss > 0 || hasGains || amount > 0) {
uint256 newDeposit = compoundedDebtDeposit;
accountDeposits[account] = AccountDeposit({ amount: uint128(newDeposit), timestamp: depositTimestamp });
_updateSnapshots(account, newDeposit);
}
}
uint256 pending = storedPendingReward[account];
if (pending > 0) {
amount += pending;
storedPendingReward[account] = 0;
}
return amount;
}
}
文件 10 的 11: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;
}
}
文件 11 的 11: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": {
"StabilityPool.sol": "StabilityPool"
},
"evmVersion": "paris",
"libraries": {},
"metadata": {
"bytecodeHash": "ipfs"
},
"optimizer": {
"enabled": true,
"runs": 200
},
"remappings": []
}
[{"inputs":[{"internalType":"address","name":"_prismaCore","type":"address"},{"internalType":"contract IDebtToken","name":"_debtTokenAddress","type":"address"},{"internalType":"contract IPrismaVault","name":"_vault","type":"address"},{"internalType":"address","name":"_factory","type":"address"},{"internalType":"address","name":"_liquidationManager","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_depositor","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_collateral","type":"uint256[]"}],"name":"CollateralGainWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20","name":"oldCollateral","type":"address"},{"indexed":false,"internalType":"contract IERC20","name":"newCollateral","type":"address"}],"name":"CollateralOverwritten","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"_P","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_G","type":"uint256"}],"name":"DepositSnapshotUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"_currentEpoch","type":"uint128"}],"name":"EpochUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_G","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"_epoch","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"_scale","type":"uint128"}],"name":"G_Updated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_P","type":"uint256"}],"name":"P_Updated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"claimed","type":"uint256"}],"name":"RewardClaimed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"idx","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_S","type":"uint256"},{"indexed":false,"internalType":"uint128","name":"_epoch","type":"uint128"},{"indexed":false,"internalType":"uint128","name":"_scale","type":"uint128"}],"name":"S_Updated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint128","name":"_currentScale","type":"uint128"}],"name":"ScaleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_newBalance","type":"uint256"}],"name":"StabilityPoolDebtBalanceUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_depositor","type":"address"},{"indexed":false,"internalType":"uint256","name":"_newDeposit","type":"uint256"}],"name":"UserDepositChanged","type":"event"},{"inputs":[],"name":"DECIMAL_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"P","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRISMA_CORE","outputs":[{"internalType":"contract IPrismaCore","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SCALE_FACTOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SUNSET_DURATION","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"accountDeposits","outputs":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint128","name":"timestamp","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256[]","name":"collateralIndexes","type":"uint256[]"}],"name":"claimCollateralGains","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"}],"name":"claimReward","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"}],"name":"claimableReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"depositor","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"collateralGainsByDepositor","outputs":[{"internalType":"uint80","name":"gains","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"collateralTokens","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentEpoch","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentScale","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtToken","outputs":[{"internalType":"contract IDebtToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"depositSnapshots","outputs":[{"internalType":"uint256","name":"P","type":"uint256"},{"internalType":"uint256","name":"G","type":"uint256"},{"internalType":"uint128","name":"scale","type":"uint128"},{"internalType":"uint128","name":"epoch","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"depositSums","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emissionId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"_collateral","type":"address"}],"name":"enableCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"","type":"uint128"},{"internalType":"uint128","name":"","type":"uint128"}],"name":"epochToScaleToG","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint128","name":"","type":"uint128"},{"internalType":"uint128","name":"","type":"uint128"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"epochToScaleToSums","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"}],"name":"getCompoundedDebtDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_depositor","type":"address"}],"name":"getDepositorCollateralGain","outputs":[{"internalType":"uint256[]","name":"collateralGains","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTotalDebtTokenDeposits","outputs":[{"internalType":"uint256","name":"","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":"contract IERC20","name":"collateral","type":"address"}],"name":"indexByCollateral","outputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastCollateralError_Offset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastDebtLossError_Offset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastPrismaError","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastUpdate","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liquidationManager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"collateral","type":"address"},{"internalType":"uint256","name":"_debtToOffset","type":"uint256"},{"internalType":"uint256","name":"_collToAdd","type":"uint256"}],"name":"offset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodFinish","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"provideToSP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardRate","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"collateral","type":"address"}],"name":"startCollateralSunset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vault","outputs":[{"internalType":"contract IPrismaVault","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"claimant","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"vaultClaimReward","outputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"withdrawFromSP","outputs":[],"stateMutability":"nonpayable","type":"function"}]