More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 476 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Provide To SP | 21757846 | 9 days ago | IN | 0 ETH | 0.00051943 | ||||
Withdraw From SP | 21754411 | 10 days ago | IN | 0 ETH | 0.00044054 | ||||
Provide To SP | 21686727 | 19 days ago | IN | 0 ETH | 0.00167394 | ||||
Withdraw From SP | 21624120 | 28 days ago | IN | 0 ETH | 0.00185639 | ||||
Withdraw From SP | 21617984 | 29 days ago | IN | 0 ETH | 0.00102854 | ||||
Withdraw From SP | 21513732 | 43 days ago | IN | 0 ETH | 0.00037425 | ||||
Withdraw From SP | 21503874 | 45 days ago | IN | 0 ETH | 0.00051339 | ||||
Provide To SP | 21499563 | 45 days ago | IN | 0 ETH | 0.00067493 | ||||
Withdraw From SP | 21491166 | 46 days ago | IN | 0 ETH | 0.00043326 | ||||
Provide To SP | 21475007 | 49 days ago | IN | 0 ETH | 0.00059111 | ||||
Provide To SP | 21453662 | 52 days ago | IN | 0 ETH | 0.00139111 | ||||
Withdraw From SP | 21450781 | 52 days ago | IN | 0 ETH | 0.00116196 | ||||
Withdraw From SP | 21443624 | 53 days ago | IN | 0 ETH | 0.00806468 | ||||
Provide To SP | 21359680 | 65 days ago | IN | 0 ETH | 0.00154777 | ||||
Withdraw From SP | 21199080 | 87 days ago | IN | 0 ETH | 0.00269699 | ||||
Provide To SP | 21140219 | 95 days ago | IN | 0 ETH | 0.00187243 | ||||
Provide To SP | 21084062 | 103 days ago | IN | 0 ETH | 0.0011995 | ||||
Provide To SP | 21040471 | 109 days ago | IN | 0 ETH | 0.00074398 | ||||
Provide To SP | 20974936 | 119 days ago | IN | 0 ETH | 0.00127873 | ||||
Provide To SP | 20961214 | 120 days ago | IN | 0 ETH | 0.00191561 | ||||
Claim Collateral... | 20902029 | 129 days ago | IN | 0 ETH | 0.00031628 | ||||
Claim Collateral... | 20902027 | 129 days ago | IN | 0 ETH | 0.00036399 | ||||
Claim Collateral... | 20902027 | 129 days ago | IN | 0 ETH | 0.00036399 | ||||
Claim Collateral... | 20902025 | 129 days ago | IN | 0 ETH | 0.00038789 | ||||
Claim Collateral... | 20902024 | 129 days ago | IN | 0 ETH | 0.00035633 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
StabilityPool
Compiler Version
v0.8.19+commit.7dd6d404
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import "contracts/token/ERC20/utils/SafeERC20.sol"; import "contracts/token/ERC20/IERC20.sol"; import "contracts/dependencies/PrismaOwnable.sol"; import "contracts/dependencies/SystemStart.sol"; import "contracts/dependencies/PrismaMath.sol"; import "contracts/interfaces/IDebtToken.sol"; import "contracts/interfaces/IVault.sol"; /** @title Prisma Stability Pool @notice Based on Liquity's `StabilityPool` https://github.com/liquity/dev/blob/main/packages/contracts/contracts/StabilityPool.sol Prisma's implementation is modified to support multiple collaterals. Deposits into the stability pool may be used to liquidate any supported collateral type. */ 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 emissionId; 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; // Tracker for Debt held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset. uint256 internal totalDebtTokenDeposits; mapping(address => AccountDeposit) public accountDeposits; // depositor address -> initial deposit mapping(address => Snapshots) public depositSnapshots; // depositor address -> snapshots struct // index values are mapped against the values within `collateralTokens` mapping(address => uint256[256]) public depositSums; // depositor address -> sums mapping(address depositor => uint80[256] gains) public collateralGainsByDepositor; mapping(address depositor => uint256 rewards) private storedPendingReward; /* Product 'P': Running product by which to multiply an initial deposit, in order to find the current compounded deposit, * after a series of liquidations have occurred, each of which cancel some debt with the deposit. * * During its lifetime, a deposit's value evolves from d_t to d_t * P / P_t , where P_t * is the snapshot of P taken at the instant the deposit was made. 18-digit decimal. */ uint256 public P = DECIMAL_PRECISION; uint256 public constant SCALE_FACTOR = 1e9; // Each time the scale of P shifts by SCALE_FACTOR, the scale is incremented by 1 uint128 public currentScale; // With each offset that fully empties the Pool, the epoch is incremented by 1 uint128 public currentEpoch; /* collateral Gain sum 'S': During its lifetime, each deposit d_t earns a collateral gain of ( d_t * [S - S_t] )/P_t, where S_t * is the depositor's snapshot of S taken at the time t when the deposit was made. * * The 'S' sums are stored in a nested mapping (epoch => scale => sum): * * - The inner mapping records the sum S at different scales * - The outer mapping records the (scale => sum) mappings, for different epochs. */ // index values are mapped against the values within `collateralTokens` mapping(uint128 => mapping(uint128 => uint256[256])) public epochToScaleToSums; /* * Similarly, the sum 'G' is used to calculate Prisma gains. During it's lifetime, each deposit d_t earns a Prisma gain of * ( d_t * [G - G_t] )/P_t, where G_t is the depositor's snapshot of G taken at time t when the deposit was made. * * Prisma reward events occur are triggered by depositor operations (new deposit, topup, withdrawal), and liquidations. * In each case, the Prisma reward is issued (i.e. G is updated), before other state changes are made. */ mapping(uint128 => mapping(uint128 => uint256)) public epochToScaleToG; // Error tracker for the error correction in the Prisma issuance calculation uint256 public lastPrismaError; // Error trackers for the error correction in the offset calculation uint256[256] public lastCollateralError_Offset; uint256 public lastDebtLossError_Offset; mapping(uint16 => SunsetIndex) _sunsetIndexes; Queue queue; struct AccountDeposit { uint128 amount; uint128 timestamp; // timestamp of the last deposit } 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 notifyRegisteredId(uint256[] calldata _assignedIds) external returns (bool) { require(msg.sender == address(vault)); require(emissionId == 0, "Already assigned"); require(_assignedIds.length == 1, "Incorrect ID count"); emissionId = _assignedIds[0]; return true; } 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 { // revert if the factory is trying to deploy a new TM with a sunset collateral 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; } /** * @notice Starts sunsetting a collateral * During sunsetting liquidated collateral handoff to the SP will revert @dev IMPORTANT: When sunsetting a collateral, `TroveManager.startSunset` should be called on all TM linked to that collateral @param collateral Collateral to sunset */ 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]; //This will prevent calls to the SP in case of liquidations } function getTotalDebtTokenDeposits() external view returns (uint256) { return totalDebtTokenDeposits; } // --- External Depositor Functions --- /* provideToSP(): * * - Triggers a Prisma issuance, based on time passed since the last issuance. The Prisma issuance is shared between *all* depositors and front ends * - Tags the deposit with the provided front end tag param, if it's a new deposit * - Sends depositor's accumulated gains (Prisma, collateral) to depositor * - Sends the tagged front end's accumulated Prisma gains to the tagged front end * - Increases deposit and tagged front end's stake, and takes new snapshots for each. */ 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); } /* withdrawFromSP(): * * - Triggers a Prisma issuance, based on time passed since the last issuance. The Prisma issuance is shared between *all* depositors and front ends * - Removes the deposit's front end tag if it is a full withdrawal * - Sends all depositor's accumulated gains (Prisma, collateral) to depositor * - Sends the tagged front end's accumulated Prisma gains to the tagged front end * - Decreases deposit and tagged front end's stake, and takes new snapshots for each. * * If _amount > userDeposit, the user withdraws all of their compounded deposit. */ 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); } // Update deposit uint256 newDeposit = compoundedDebtDeposit - debtToWithdraw; accountDeposits[msg.sender] = AccountDeposit({ amount: uint128(newDeposit), timestamp: depositTimestamp }); _updateSnapshots(msg.sender, newDeposit); emit UserDepositChanged(msg.sender, newDeposit); } // --- Prisma issuance functions --- function _triggerRewardIssuance() internal { _updateG(_vestedEmissions()); uint256 _periodFinish = periodFinish; uint256 lastUpdateWeek = (_periodFinish - startTime) / 1 weeks; // If the last claim was a week earlier we reclaim if (getWeek() >= lastUpdateWeek) { uint256 amount = vault.allocateNewEmissions(emissionId); if (amount > 0) { // If the previous period is not finished we combine new and pending old rewards 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; // Period is not ended we max at current timestamp if (updated > block.timestamp) updated = block.timestamp; // if the last update was after the current update time it means all rewards have been vested already uint256 lastUpdateCached = lastUpdate; if (lastUpdateCached >= updated) return 0; //Nothing to claim uint256 duration = updated - lastUpdateCached; return duration * rewardRate; } function _updateG(uint256 _prismaIssuance) internal { uint256 totalDebt = totalDebtTokenDeposits; // cached to save an SLOAD /* * When total deposits is 0, G is not updated. In this case, the Prisma issued can not be obtained by later * depositors - it is missed out on, and remains in the balanceof the Treasury contract. * */ 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) { /* * Calculate the Prisma-per-unit staked. Division uses a "feedback" error correction, to keep the * cumulative error low in the running total G: * * 1) Form a numerator which compensates for the floor division error that occurred the last time this * function was called. * 2) Calculate "per-unit-staked" ratio. * 3) Multiply the ratio back by its denominator, to reveal the current floor division error. * 4) Store this error for use in the next correction when this function is called. * 5) Note: static analysis tools complain about this "division before multiplication", however, it is intended. */ uint256 prismaNumerator = (_prismaIssuance * DECIMAL_PRECISION) + lastPrismaError; uint256 prismaPerUnitStaked = prismaNumerator / _totalDebtTokenDeposits; lastPrismaError = prismaNumerator - (prismaPerUnitStaked * _totalDebtTokenDeposits); return prismaPerUnitStaked; } // --- Liquidation functions --- /* * Cancels out the specified debt against the Debt contained in the Stability Pool (as far as possible) */ 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; // cached to save an SLOAD if (totalDebt == 0 || _debtToOffset == 0) { return; } _triggerRewardIssuance(); (uint256 collateralGainPerUnitStaked, uint256 debtLossPerUnitStaked) = _computeRewardsPerUnitStaked( _collToAdd, _debtToOffset, totalDebt, idx ); _updateRewardSumAndProduct(collateralGainPerUnitStaked, debtLossPerUnitStaked, idx); // updates S and P // Cancel the liquidated Debt debt with the Debt in the stability pool _decreaseDebt(_debtToOffset); } // --- Offset helper functions --- function _computeRewardsPerUnitStaked( uint256 _collToAdd, uint256 _debtToOffset, uint256 _totalDebtTokenDeposits, uint256 idx ) internal returns (uint256 collateralGainPerUnitStaked, uint256 debtLossPerUnitStaked) { /* * Compute the Debt and collateral rewards. Uses a "feedback" error correction, to keep * the cumulative error in the P and S state variables low: * * 1) Form numerators which compensate for the floor division errors that occurred the last time this * function was called. * 2) Calculate "per-unit-staked" ratios. * 3) Multiply each ratio back by its denominator, to reveal the current floor division error. * 4) Store these errors for use in the next correction when this function is called. * 5) Note: static analysis tools complain about this "division before multiplication", however, it is intended. */ uint256 collateralNumerator = (_collToAdd * DECIMAL_PRECISION) + lastCollateralError_Offset[idx]; if (_debtToOffset == _totalDebtTokenDeposits) { debtLossPerUnitStaked = DECIMAL_PRECISION; // When the Pool depletes to 0, so does each deposit lastDebtLossError_Offset = 0; } else { uint256 debtLossNumerator = (_debtToOffset * DECIMAL_PRECISION) - lastDebtLossError_Offset; /* * Add 1 to make error in quotient positive. We want "slightly too much" Debt loss, * which ensures the error in any given compoundedDebtDeposit favors the Stability Pool. */ debtLossPerUnitStaked = (debtLossNumerator / _totalDebtTokenDeposits) + 1; lastDebtLossError_Offset = (debtLossPerUnitStaked * _totalDebtTokenDeposits) - debtLossNumerator; } collateralGainPerUnitStaked = collateralNumerator / _totalDebtTokenDeposits; lastCollateralError_Offset[idx] = collateralNumerator - (collateralGainPerUnitStaked * _totalDebtTokenDeposits); return (collateralGainPerUnitStaked, debtLossPerUnitStaked); } // Update the Stability Pool reward sum S and product P function _updateRewardSumAndProduct( uint256 _collateralGainPerUnitStaked, uint256 _debtLossPerUnitStaked, uint256 idx ) internal { uint256 currentP = P; uint256 newP; /* * The newProductFactor is the factor by which to change all deposits, due to the depletion of Stability Pool Debt in the liquidation. * We make the product factor 0 if there was a pool-emptying. Otherwise, it is (1 - DebtLossPerUnitStaked) */ uint256 newProductFactor = uint256(DECIMAL_PRECISION) - _debtLossPerUnitStaked; uint128 currentScaleCached = currentScale; uint128 currentEpochCached = currentEpoch; uint256 currentS = epochToScaleToSums[currentEpochCached][currentScaleCached][idx]; /* * Calculate the new S first, before we update P. * The collateral gain for any given depositor from a liquidation depends on the value of their deposit * (and the value of totalDeposits) prior to the Stability being depleted by the debt in the liquidation. * * Since S corresponds to collateral gain, and P to deposit loss, we update S first. */ uint256 marginalCollateralGain = _collateralGainPerUnitStaked * currentP; uint256 newS = currentS + marginalCollateralGain; epochToScaleToSums[currentEpochCached][currentScaleCached][idx] = newS; emit S_Updated(idx, newS, currentEpochCached, currentScaleCached); // If the Stability Pool was emptied, increment the epoch, and reset the scale and product P if (newProductFactor == 0) { currentEpoch = currentEpochCached + 1; emit EpochUpdated(currentEpoch); currentScale = 0; emit ScaleUpdated(currentScale); newP = DECIMAL_PRECISION; // If multiplying P by a non-zero product factor would reduce P below the scale boundary, increment the scale } 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); } // --- Reward calculator functions for depositor and front end --- /* Calculates the collateral gain earned by the deposit since its last snapshots were taken. * Given by the formula: E = d0 * (S - S(0))/P(0) * where S(0) and P(0) are the depositor's snapshots of the sum S and product P, respectively. * d0 is the last recorded deposit value. */ 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; // Collateral was overwritten or not gains 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; // Collateral was overwritten or not gains 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); } /* * Calculate the Prisma gain earned by a deposit since its last snapshots were taken. * Given by the formula: Prisma = d0 * (G - G(0))/P(0) * where G(0) and P(0) are the depositor's snapshots of the sum G and product P, respectively. * d0 is the last recorded deposit value. */ function claimableReward(address _depositor) external view returns (uint256) { uint256 totalDebt = totalDebtTokenDeposits; uint256 initialDeposit = accountDeposits[_depositor].amount; if (totalDebt == 0 || initialDeposit == 0) { return storedPendingReward[_depositor]; } 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 storedPendingReward[_depositor] + (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) { /* * Grab the sum 'G' from the epoch at which the stake was made. The Prisma gain may span up to one scale change. * If it does, the second portion of the Prisma gain is scaled by 1e9. * If the gain spans no scale change, the second portion will be 0. */ 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; } // --- Compounded deposit and compounded front end stake --- /* * Return the user's compounded deposit. Given by the formula: d = d0 * P/P(0) * where P(0) is the depositor's snapshot of the product P, taken when they last updated their deposit. */ 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; } // Internal function, used to calculcate compounded deposits and compounded front end stakes. 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 stake was made before a pool-emptying event, then it has been fully cancelled with debt -- so, return 0 if (epochSnapshot < currentEpoch) { return 0; } uint256 compoundedStake; uint128 scaleDiff = currentScale - scaleSnapshot; /* Compute the compounded stake. If a scale change in P was made during the stake's lifetime, * account for it. If more than one scale change was made, then the stake has decreased by a factor of * at least 1e-9 -- so return 0. */ if (scaleDiff == 0) { compoundedStake = (initialStake * P) / snapshot_P; } else if (scaleDiff == 1) { compoundedStake = (initialStake * P) / snapshot_P / SCALE_FACTOR; } else { // if scaleDiff >= 2 compoundedStake = 0; } /* * If compounded deposit is less than a billionth of the initial deposit, return 0. * * NOTE: originally, this line was in place to stop rounding errors making the deposit too large. However, the error * corrections should ensure the error in P "favors the Pool", i.e. any given compounded deposit should slightly less * than it's theoretical value. * * Thus it's unclear whether this line is still really needed. */ if (compoundedStake < initialStake / 1e9) { return 0; } return compoundedStake; } // --- Sender functions for Debt deposit, collateral gains and Prisma gains --- function claimCollateralGains(address recipient, uint256[] calldata collateralIndexes) public virtual { _accrueDepositorCollateralGain(msg.sender); 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); } // --- Stability Pool Deposit Functionality --- 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; // Get S and G for the current epoch and current scale uint256[256] storage currentS = epochToScaleToSums[currentEpochCached][currentScaleCached]; uint256 currentG = epochToScaleToG[currentEpochCached][currentScaleCached]; // Record new snapshots of the latest running product P, sum S, and sum G, for the depositor 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); } //This assumes the snapshot gets updated in the caller 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); // we update only if the snapshot has changed if (debtLoss > 0 || hasGains || amount > 0) { // Update deposit 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "contracts/token/ERC20/IERC20.sol"; import "contracts/token/ERC20/extensions/IERC20Permit.sol"; import "contracts/utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' 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)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ 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"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ 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"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ 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"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ 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"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ 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); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ 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); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ 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); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ 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 { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import "contracts/interfaces/IPrismaCore.sol"; /** @title Prisma Ownable @notice Contracts inheriting `PrismaOwnable` have the same owner as `PrismaCore`. The ownership cannot be independently modified or renounced. */ 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(); } }
// SPDX-License-Identifier: MIT 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); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import "contracts/interfaces/IPrismaCore.sol"; /** @title Prisma System Start Time @dev Provides a unified `startTime` and `getWeek`, used for emissions. */ 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; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; library PrismaMath { uint256 internal constant DECIMAL_PRECISION = 1e18; /* Precision for Nominal ICR (independent of price). Rationale for the value: * * - Making it “too high” could lead to overflows. * - Making it “too low” could lead to an ICR equal to zero, due to truncation from Solidity floor division. * * This value of 1e20 is chosen for safety: the NICR will only overflow for numerator > ~1e39, * and will only truncate to 0 if the denominator is at least 1e20 times greater than the numerator. * */ 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; } /* * Multiply two decimal numbers and use normal rounding rules: * -round product up if 19'th mantissa digit >= 5 * -round product down if 19'th mantissa digit < 5 * * Used only inside the exponentiation, _decPow(). */ function decMul(uint256 x, uint256 y) internal pure returns (uint256 decProd) { uint256 prod_xy = x * y; decProd = (prod_xy + (DECIMAL_PRECISION / 2)) / DECIMAL_PRECISION; } /* * _decPow: Exponentiation function for 18-digit decimal base, and integer exponent n. * * Uses the efficient "exponentiation by squaring" algorithm. O(log(n)) complexity. * * Called by two functions that represent time in units of minutes: * 1) TroveManager._calcDecayedBaseRate * 2) CommunityIssuance._getCumulativeIssuanceFraction * * The exponent is capped to avoid reverting due to overflow. The cap 525600000 equals * "minutes in 1000 years": 60 * 24 * 365 * 1000 * * If a period of > 1000 years is ever used as an exponent in either of the above functions, the result will be * negligibly different from just passing the cap, since: * * In function 1), the decayed base rate will be 0 for 1000 years or > 1000 years * In function 2), the difference in tokens issued at 1000 years and any time > 1000 years, will be negligible */ function _decPow(uint256 _base, uint256 _minutes) internal pure returns (uint256) { if (_minutes > 525600000) { _minutes = 525600000; } // cap to avoid overflow if (_minutes == 0) { return DECIMAL_PRECISION; } uint256 y = DECIMAL_PRECISION; uint256 x = _base; uint256 n = _minutes; // Exponentiation-by-squaring while (n > 1) { if (n % 2 == 0) { x = decMul(x, x); n = n / 2; } else { // if (n % 2 != 0) 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; } // Return the maximal value for uint256 if the Trove has a debt of 0. Represents "infinite" CR. else { // if (_debt == 0) 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; } // Return the maximal value for uint256 if the Trove has a debt of 0. Represents "infinite" CR. else { // if (_debt == 0) return 2 ** 256 - 1; } } function _computeCR(uint256 _coll, uint256 _debt) internal pure returns (uint256) { if (_debt > 0) { uint256 newCollRatio = (_coll) / _debt; return newCollRatio; } // Return the maximal value for uint256 if the Trove has a debt of 0. Represents "infinite" CR. else { // if (_debt == 0) return 2 ** 256 - 1; } } }
// SPDX-License-Identifier: MIT 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); }
// SPDX-License-Identifier: MIT 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); }
{ "evmVersion": "paris", "optimizer": { "enabled": true, "runs": 200 }, "libraries": { "StabilityPool.sol": {} }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"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":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"uint256[]","name":"_assignedIds","type":"uint256[]"}],"name":"notifyRegisteredId","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","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"}]
Contract Creation Code
610140604052670de0b6b3a7640000600a553480156200001e57600080fd5b50604051620038d6380380620038d683398101604081905262000041916200012a565b6001600160a01b0385166080819052604080516378e9792560e01b815290518792916378e979259160048083019260209291908290030181865afa1580156200008e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b49190620001aa565b60a052506001600160a01b0380851660c05283811660e05282811661010052811661012052620000e6600142620001c4565b600160146101000a81548163ffffffff021916908363ffffffff1602179055505050505050620001ec565b6001600160a01b03811681146200012757600080fd5b50565b600080600080600060a086880312156200014357600080fd5b8551620001508162000111565b6020870151909550620001638162000111565b6040870151909450620001768162000111565b6060870151909350620001898162000111565b60808701519092506200019c8162000111565b809150509295509295909350565b600060208284031215620001bd57600080fd5b5051919050565b81810381811115620001e657634e487b7160e01b600052601160045260246000fd5b92915050565b60805160a05160c05160e051610100516101205161363f6200029760003960008181610314015261272101526000818161059901526107110152600081816106be0152818161114c0152818161175b01528181611bbf0152611e8601526000818161069701528181610d40015261153f01526000818161168d0152611e2c0152600081816105c0015281816109eb015281816110ba015281816113d901526116c0015261363f6000f3fe608060405234801561001057600080fd5b506004361061025e5760003560e01c8063874d6d8111610146578063d279c191116100c3578063e950342511610087578063e950342514610642578063ebe2b12b14610655578063eeb58d0b1461066c578063f05820381461067f578063f8d8989814610692578063fbfa77cf146106b957600080fd5b8063d279c191146105ed578063d5f195fe14610600578063d7936b7e14610613578063db03fdaa1461061c578063e66667331461062f57600080fd5b8063a7528a031161010a578063a7528a031461055e578063c046371114610568578063c45a015514610594578063cc9641a8146105bb578063ce4b5bbe146105e257600080fd5b8063874d6d81146105235780638b8fbd921461052b5780638da5cb5b14610534578063a20baee61461053c578063a4e59ac81461054b57600080fd5b806347636371116101df57806378c77a24116101a357806378c77a24146104025780637b0a47ee1461041557806381bafb311461042857806382e0a57414610432578063835dada01461045d57806386da0824146104b157600080fd5b806347636371146103715780635383dfcb1461037a5780635bbe8aad1461039a5780635e3078ec146103bd57806376671808146103d057600080fd5b806319f27b3b1161022657806319f27b3b146102fc5780631ef3a04c1461030f5780632e54bf9514610336578063307d361214610349578063452a93201461036957600080fd5b806309e2acb0146102635780630d9a6b351461028957806311be0de5146102915780631500d2c3146102a6578063172c48c7146102d1575b600080fd5b61027661027136600461317a565b6106e0565b6040519081526020015b60405180910390f35b600454610276565b6102a461029f3660046131a6565b610706565b005b6102b96102b436600461317a565b61097c565b6040516001600160501b039091168152602001610280565b6102e46102df3660046131c3565b6109bf565b6040516001600160a01b039091168152602001610280565b6102a461030a3660046131a6565b6109e9565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b6102a46103443660046131c3565b610c00565b61035c6103573660046131a6565b610e44565b60405161028091906131dc565b6102e46110b6565b61027660005481565b6102766103883660046131a6565b60026020526000908152604090205481565b6103ad6103a836600461326c565b61113f565b6040519015158152602001610280565b6102a46103cb3660046132ae565b611228565b600b546103ea90600160801b90046001600160801b031681565b6040516001600160801b039091168152602001610280565b6102a46104103660046131c3565b6113d7565b6001546103ea906001600160801b031681565b61027661010f5481565b61027661044036600461331f565b600d60209081526000928352604080842090915290825290205481565b61049161046b3660046131a6565b6005602052600090815260409020546001600160801b0380821691600160801b90041682565b604080516001600160801b03938416815292909116602083015201610280565b6104f46104bf3660046131a6565b6006602052600090815260409020805460018201546002909201549091906001600160801b0380821691600160801b90041684565b6040805194855260208501939093526001600160801b0391821692840192909252166060820152608001610280565b610276611682565b610276600a5481565b6102e46116bc565b610276670de0b6b3a764000081565b600b546103ea906001600160801b031681565b6103ea62ed4e0081565b60015461057f90600160801b900463ffffffff1681565b60405163ffffffff9091168152602001610280565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b610276633b9aca0081565b6102766105fb3660046131a6565b61171c565b61027661060e3660046131a6565b61180f565b610276600e5481565b61027661062a366004613352565b6118ab565b6102a461063d36600461338e565b6118de565b6102766106503660046131a6565b6118e9565b60015461057f90600160a01b900463ffffffff1681565b61027661067a3660046131c3565b611b9a565b61027661068d3660046133c3565b611bb2565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b6102e47f000000000000000000000000000000000000000000000000000000000000000081565b60076020528160005260406000208161010081106106fd57600080fd5b01549150829050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146107715760405162461bcd60e51b815260206004820152600b60248201526a4e6f7420666163746f727960a81b60448201526064015b60405180910390fd5b6003546000805b828110156107d257836001600160a01b03166003828154811061079d5761079d6133fc565b6000918252602090912001546001600160a01b0316036107c057600191506107d2565b806107ca81613428565b915050610778565b508061091257604080518082019091526101115461ffff80821680845262010000909204166020830181905211156108b257805161ffff16600090815261011060209081526040918290208251808401909352546001600160801b038082168452600160801b909104169082018190524211156108b05761011180546101109160009161ffff16908261086483613441565b82546101009290920a61ffff818102199093169183160217909155168152602081019190915260400160009081205580516108a99086906001600160801b0316611bf9565b5050505050565b505b50600380546001810182557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b038616908117909155905460009182526002602052604090912055505050565b6001600160a01b0383166000908152600260205260409020546109775760405162461bcd60e51b815260206004820152601860248201527f436f6c6c61746572616c2069732073756e73657474696e6700000000000000006044820152606401610768565b505050565b600860205281600052604060002081610100811061099957600080fd5b60039182820401919006600a02915091509054906101000a90046001600160501b031681565b600381815481106109cf57600080fd5b6000918252602090912001546001600160a01b0316905081565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6b9190613462565b6001600160a01b0316336001600160a01b031614610ab85760405162461bcd60e51b815260206004820152600a60248201526927b7363c9037bbb732b960b11b6044820152606401610768565b6001600160a01b038116600090815260026020526040902054610b1d5760405162461bcd60e51b815260206004820152601d60248201527f436f6c6c61746572616c20616c72656164792073756e73657474696e670000006044820152606401610768565b6040805180820182526001600160a01b0383166000908152600260205291909120548190610b4d9060019061347f565b6001600160801b03168152602001610b6862ed4e0042613492565b6001600160801b0316905261011180546101109160009162010000900461ffff16906002610b9583613441565b825461ffff9182166101009390930a928302928202191691909117909155168152602080820192909252604090810160009081208451948401516001600160801b03908116600160801b029516949094179093556001600160a01b0390931682526002905290812055565b336000908152600560205260409020546001600160801b0380821691600160801b90041681610c8a5760405162461bcd60e51b815260206004820152603060248201527f53746162696c697479506f6f6c3a2055736572206d757374206861766520612060448201526f1b9bdb8b5e995c9bc819195c1bdcda5d60821b6064820152608401610768565b42816001600160801b031610610ce25760405162461bcd60e51b815260206004820181905260248201527f214465706f73697420616e642077697468647261772073616d6520626c6f636b6044820152606401610768565b610cea611e01565b610cf333611fbd565b506000610cff3361180f565b90506000610d0d85836121d9565b9050610d18336121ef565b8015610dad57604051631062c15f60e11b8152306004820152336024820152604481018290527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906320c582be90606401600060405180830381600087803b158015610d8c57600080fd5b505af1158015610da0573d6000803e3d6000fd5b50505050610dad81612241565b6000610db9828461347f565b6040805180820182526001600160801b03808416825287811660208084019182523360008181526005909252949020925190518216600160801b029116179055909150610e069082612290565b60405181815233907fbce78369dccab09eec1986f4d409ab09ffbb47d65423e5148fcf98411c5111c9906020015b60405180910390a2505050505050565b60035460609067ffffffffffffffff811115610e6257610e626134a5565b604051908082528060200260200182016040528015610e8b578160200160208202803683370190505b506001600160a01b038316600090815260066020526040812054919250819003610eb55750919050565b6001600160a01b0383166000908152600860209081526040808320600583528184205460068452828520600201546001600160801b03600160801b82048116808852600c808852868920938316808a52848952968920828a5297529396921694929392919081610f268560016134bb565b6001600160801b03168152602080820192909252604090810160009081206001600160a01b038d16825260079093529081209192505b89518110156110a85787816101008110610f7857610f786133fc565b60039182820401919006600a029054906101000a90046001600160501b03166001600160501b03168a8281518110610fb257610fb26133fc565b60200260200101818152505083816101008110610fd157610fd16133fc565b01541561109657600082826101008110610fed57610fed6133fc565b015485836101008110611002576110026133fc565b015461100e919061347f565b90506000633b9aca008584610100811061102a5761102a6133fc565b015461103691906134e2565b9050670de0b6b3a76400008b61104c8385613492565b611056908c613504565b61106091906134e2565b61106a91906134e2565b8c848151811061107c5761107c6133fc565b602002602001018181516110909190613492565b90525050505b806110a081613428565b915050610f5c565b505050505050505050919050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015611116573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113a9190613462565b905090565b6000336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461117657600080fd5b600054156111b95760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e48185cdcda59db995960821b6044820152606401610768565b600182146111fe5760405162461bcd60e51b8152602060048201526012602482015271125b98dbdc9c9958dd0812510818dbdd5b9d60721b6044820152606401610768565b82826000818110611211576112116133fc565b602002919091013560005550600190505b92915050565b61123133611fbd565b50600354819060009067ffffffffffffffff811115611252576112526134a5565b60405190808252806020026020018201604052801561127b578160200160208202803683370190505b503360009081526008602052604081209192505b8381101561139d5760008686838181106112ab576112ab6133fc565b9050602002013590506000838261010081106112c9576112c96133fc565b60039182820401919006600a029054906101000a90046001600160501b03166001600160501b031690506000811115611393578085838151811061130f5761130f6133fc565b602002602001018181525050600084836101008110611330576113306133fc565b60039182820401919006600a026101000a8154816001600160501b0302191690836001600160501b03160217905550611393898260038581548110611377576113776133fc565b6000918252602090912001546001600160a01b03169190612484565b505060010161128f565b50336001600160a01b03167faecf5c2e84838a7ed87234d73965fc51f96b87b4c957f03bf22cfeb618c9aae183604051610e3491906131dc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611435573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611459919061351b565b1561149c5760405162461bcd60e51b815260206004820152601360248201527211195c1bdcda5d1cc8185c99481c185d5cd959606a1b6044820152606401610768565b600081116114fb5760405162461bcd60e51b815260206004820152602660248201527f53746162696c697479506f6f6c3a20416d6f756e74206d757374206265206e6f6044820152656e2d7a65726f60d01b6064820152608401610768565b611503611e01565b61150c33611fbd565b5060006115183361180f565b9050611523336121ef565b60405163e75b3ae760e01b8152336004820152602481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063e75b3ae790604401600060405180830381600087803b15801561158b57600080fd5b505af115801561159f573d6000803e3d6000fd5b505050506000826004546115b39190613492565b60048190556040518181529091507f5c1eb83edfbe7709b9a63e8c7e294df8731e15bc212a85bf6e95cb906600bcbb9060200160405180910390a160006115fa8484613492565b6040805180820182526001600160801b03808416825242811660208084019182523360008181526005909252949020925190518216600160801b0291161790559091506116479082612290565b60405181815233907fbce78369dccab09eec1986f4d409ab09ffbb47d65423e5148fcf98411c5111c99060200160405180910390a250505050565b600062093a806116b27f00000000000000000000000000000000000000000000000000000000000000004261347f565b61113a91906134e2565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611116573d6000803e3d6000fd5b6000611727336124d6565b905080156117ca576040516335e97f1f60e11b81523360048201526001600160a01b038381166024830152604482018390527f00000000000000000000000000000000000000000000000000000000000000001690636bd2fe3e906064016020604051808303816000875af11580156117a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c8919061351b565b505b6040518181526001600160a01b0383169033907f0aa4d283470c904c551d18bb894d37e17674920f3261a7f854be501e25f421b79060200160405180910390a3919050565b6001600160a01b0381166000908152600560205260408120546001600160801b03168082036118415750600092915050565b6001600160a01b0383166000908152600660209081526040808320815160808101835281548152600182015493810193909352600201546001600160801b0380821692840192909252600160801b9004166060820152906118a28383612629565b95945050505050565b600c6020528260005260406000206020528160005260406000208161010081106118d457600080fd5b0154925083915050565b610977838383612716565b6004546001600160a01b0382166000908152600560205260408120549091906001600160801b031681158061191c575080155b1561193f575050506001600160a01b031660009081526009602052604090205490565b6000600e54670de0b6b3a7640000611955612820565b61195f9190613504565b6119699190613492565b9050600061197784836134e2565b90506000600a54826119899190613504565b6001600160a01b0388166000908152600660209081526040808320815160808101835281548152600182015493810193909352600201546001600160801b03808216928401839052600160801b909104811660608401819052600b549596509294929391928291168303611a97576020808601516001600160801b038087166000908152600d84526040808220928816825291909352909120548791611a2e9161347f565b611a389190613492565b6001600160801b0385166000908152600d60205260408120919350633b9aca009190611a658660016134bb565b6001600160801b03166001600160801b0316815260200190815260200160002054611a9091906134e2565b9050611b33565b6020808601516001600160801b038087166000908152600d8452604080822092881682529190935290912054611acd919061347f565b6001600160801b0385166000908152600d60205260408120919350633b9aca00918891611afb8760016134bb565b6001600160801b03166001600160801b0316815260200190815260200160002054611b269190613492565b611b3091906134e2565b90505b8451670de0b6b3a764000090611b498385613492565b611b53908c613504565b611b5d91906134e2565b611b6791906134e2565b6001600160a01b038d16600090815260096020526040902054611b8a9190613492565b9c9b505050505050505050505050565b600f816101008110611bab57600080fd5b0154905081565b6000336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611be957600080fd5b611bf2836124d6565b9392505050565b6001600160a01b03821660009081526002602052604090205415611c5f5760405162461bcd60e51b815260206004820152601960248201527f436f6c6c61746572616c206d7573742062652073756e736574000000000000006044820152606401610768565b600354808210611ca35760405162461bcd60e51b815260206004820152600f60248201526e496e64657820746f6f206c6172676560881b6044820152606401610768565b600b546001600160801b03600160801b82048116911660005b82816001600160801b031611611d2b5760005b82816001600160801b031611611d22576001600160801b038083166000908152600c602090815260408083209385168352929052908120876101008110611d1857611d186133fc565b0155600101611ccf565b50600101611cbc565b50611d37846001613492565b6001600160a01b038616600090815260026020526040902055600380547f9e147d339c63698deb55c3d0d44ed3eba29bac2a068a88c4bc5bde17d6331e19919086908110611d8757611d876133fc565b60009182526020918290200154604080516001600160a01b039283168152918916928201929092520160405180910390a18460038581548110611dcc57611dcc6133fc565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050505050565b611e11611e0c612820565b61288b565b600154600160a01b900463ffffffff16600062093a80611e517f00000000000000000000000000000000000000000000000000000000000000008461347f565b611e5b91906134e2565b905080611e66611682565b10611f9b576000805460405163378cbf7560e01b815260048101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063378cbf75906024016020604051808303816000875af1158015611ed7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611efb919061353d565b90508015611f995782421015611f3e576000611f17428561347f565b600154909150611f30906001600160801b031682613504565b611f3a9083613492565b9150505b611f4b62093a80826134e2565b600180546001600160801b0319166001600160801b0392909216919091179055611f7862093a8042613492565b600160146101000a81548163ffffffff021916908363ffffffff1602179055505b505b50506001805463ffffffff60801b1916600160801b4263ffffffff1602179055565b6001600160a01b03811660009081526008602090815260408083206003546005909352908320549091906001600160801b0316808403611fff57505050919050565b6001600160a01b0385166000908152600660209081526040808320600281015490546001600160801b03600160801b83048116808752600c808752858820929094168088528287529487208188529390955293949293909290816120648660016134bb565b6001600160801b03168152602080820192909252604090810160009081206001600160a01b038e16825260079093529081209192505b888110156121ca57838161010081106120b5576120b56133fc565b0154156121b85760019a506000828261010081106120d5576120d56133fc565b0154858361010081106120ea576120ea6133fc565b01546120f6919061347f565b90506000633b9aca0085846101008110612112576121126133fc565b015461211e91906134e2565b9050670de0b6b3a7640000876121348385613492565b61213e908d613504565b61214891906134e2565b61215291906134e2565b8c846101008110612165576121656133fc565b60039182820401919006600a028282829054906101000a90046001600160501b03166121919190613556565b92506101000a8154816001600160501b0302191690836001600160501b0316021790555050505b806121c281613428565b91505061209a565b50505050505050505050919050565b60008183106121e85781611bf2565b5090919050565b60006121fa82612987565b6001600160a01b038316600090815260096020526040902054909150612221908290613492565b6001600160a01b0390921660009081526009602052604090209190915550565b600081600454612251919061347f565b60048190556040518181529091507f5c1eb83edfbe7709b9a63e8c7e294df8731e15bc212a85bf6e95cb906600bcbb9060200160405180910390a15050565b60008160000361235857506001600160a01b038216600090815260066020526040812081815560018101829055600201819055600354905b8181101561230e576001600160a01b03841660009081526007602052604081208261010081106122fa576122fa6133fc565b01558061230681613428565b9150506122c8565b5060408051600080825260208201526001600160a01b038516917fc48943df4095f4f20d171fd2872eafdc0eed4d9014ac3672f3bde7fd425449d5910160405180910390a2505050565b50600b54600a546001600160801b03600160801b80840482166000818152600c6020908152604080832095909716808352948152868220838352600d82528783208684528252878320546001600160a01b038b168452600690925296822086815560018101829055938302851760029094019390935560035495939491939192905b8681101561243557828161010081106123f5576123f56133fc565b01546001600160a01b038a166000908152600760205260409020826101008110612421576124216133fc565b01558061242d81613428565b9150506123da565b5060408051848152602081018390526001600160a01b038a16917fc48943df4095f4f20d171fd2872eafdc0eed4d9014ac3672f3bde7fd425449d5910160405180910390a25050505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610977908490612a24565b6001600160a01b0381166000908152600560205260408120546001600160801b031680156125dd576001600160a01b038316600090815260056020526040902054600160801b90046001600160801b031661252f611e01565b600061253a85611fbd565b905060006125478661180f565b90506000612555828661347f565b905061256087612987565b9550600081118061256e5750825b806125795750600086115b156125d8576040805180820182526001600160801b03808516825286811660208084019182526001600160a01b038c166000908152600590915293909320915192518116600160801b029216919091179055816125d68882612290565b505b505050505b6001600160a01b0383166000908152600960205260409020548015612622576126068184613492565b6001600160a01b03851660009081526009602052604081205592505b5050919050565b805160408201516060830151600b546000939291906001600160801b03600160801b909104811690821610156126655760009350505050611222565b600b5460009081906126819085906001600160801b0316613576565b9050806001600160801b03166000036126b45784600a54896126a39190613504565b6126ad91906134e2565b91506126e8565b806001600160801b03166001036126e357633b9aca0085600a548a6126d99190613504565b6126a391906134e2565b600091505b6126f6633b9aca00896134e2565b82101561270b57600095505050505050611222565b509695505050505050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146127a75760405162461bcd60e51b815260206004820152603060248201527f53746162696c697479506f6f6c3a2043616c6c6572206973206e6f74204c697160448201526f3ab4b230ba34b7b71026b0b730b3b2b960811b6064820152608401610768565b6001600160a01b0383166000908152600260205260409020546127cb60018261347f565b6004549091508015806127dc575083155b156127e8575050505050565b6127f0611e01565b6000806127ff85878587612af9565b9150915061280e828286612be6565b61281786612241565b50505050505050565b600154600090600160a01b900463ffffffff164281111561283e5750425b600154600160801b900463ffffffff1681811061285e5760009250505090565b600061286a828461347f565b600154909150612883906001600160801b031682613504565b935050505090565b600454801580612899575081155b156128a2575050565b60006128ae8383612f08565b600b54600a549192506001600160801b03600160801b82048116929116906000906128d99085613504565b6001600160801b038085166000908152600d6020908152604080832093871683529290529081205491925090612910908390613492565b6001600160801b038581166000818152600d60209081526040808320948916808452948252918290208590558151858152908101929092528101919091529091507f2d6127771b164a9cc8827d24b5955db2a77e7a81dac389107ebb8bce9fb649689060600160405180910390a150505050505050565b6001600160a01b0381166000908152600560205260408120546001600160801b03168082036129b95750600092915050565b6001600160a01b038316600090815260066020908152604091829020825160808101845281548152600182015492810192909252600201546001600160801b0380821693830193909352600160801b90049091166060820152612a1c8282612f5b565b949350505050565b6000612a79826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661303f9092919063ffffffff16565b9050805160001480612a9a575080806020019051810190612a9a919061351b565b6109775760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610768565b6000806000600f846101008110612b1257612b126133fc565b0154612b26670de0b6b3a764000089613504565b612b309190613492565b9050848603612b4f57600061010f55670de0b6b3a76400009150612ba6565b61010f54600090612b68670de0b6b3a764000089613504565b612b72919061347f565b9050612b7e86826134e2565b612b89906001613492565b925080612b968785613504565b612ba0919061347f565b61010f55505b612bb085826134e2565b9250612bbc8584613504565b612bc6908261347f565b600f856101008110612bda57612bda6133fc565b01555094509492505050565b600a54600080612bfe85670de0b6b3a764000061347f565b600b546001600160801b03600160801b820481166000818152600c60209081526040808320949095168083529390529283209394509092909190876101008110612c4a57612c4a6133fc565b015490506000612c5a878b613504565b90506000612c688284613492565b6001600160801b038086166000908152600c60209081526040808320938a1683529290522090915081908a6101008110612ca457612ca46133fc565b0155604080518a8152602081018390526001600160801b03868116828401528716606082015290517fe150473acddd94d1c6add794bd840c8d3e297dc3e50d863b56c0fba04d0d02479181900360800190a185600003612db257612d098460016134bb565b600b80546001600160801b03908116600160801b93821684021791829055604051929091041681527fb50f0f59e7cb5b421dc77581c3a9919e3806e076e5fa78a874c3f120cb7d874d9060200160405180910390a1600b80546001600160801b0319169055604051600081527f1f9dfc70cd666adb18a39d60a797518f7b4febf4b6e24ef37d44f6e1e7219fbe9060200160405180910390a1670de0b6b3a76400009650612e8a565b633b9aca00670de0b6b3a7640000612dca888b613504565b612dd491906134e2565b1015612e6a57670de0b6b3a7640000633b9aca00612df2888b613504565b612dfc9190613504565b612e0691906134e2565b9650612e138560016134bb565b600b80546001600160801b0319166001600160801b039290921691821790556040519081527f1f9dfc70cd666adb18a39d60a797518f7b4febf4b6e24ef37d44f6e1e7219fbe9060200160405180910390a1612e8a565b670de0b6b3a7640000612e7d878a613504565b612e8791906134e2565b96505b60008711612ec35760405162461bcd60e51b81526004016107689060208082526004908201526304e6577560e41b604082015260600190565b600a8790556040518781527fc1a9618cb59ebca77cbdbc2949f126823c407ff13edb285fd0262519a9c18e8c9060200160405180910390a15050505050505050505050565b600080600e54670de0b6b3a764000085612f229190613504565b612f2c9190613492565b90506000612f3a84836134e2565b9050612f468482613504565b612f50908361347f565b600e55949350505050565b606081015160408083015160208085015185516001600160801b038087166000908152600d8552868120918616815293529382205491949390918590612fa290849061347f565b6001600160801b0386166000908152600d6020526040812091925090633b9aca009082612fd08860016134bb565b6001600160801b03166001600160801b0316815260200190815260200160002054612ffb91906134e2565b90506000670de0b6b3a7640000846130138486613492565b61301d908d613504565b61302791906134e2565b61303191906134e2565b9a9950505050505050505050565b6060612a1c848460008585600080866001600160a01b0316858760405161306691906135ba565b60006040518083038185875af1925050503d80600081146130a3576040519150601f19603f3d011682016040523d82523d6000602084013e6130a8565b606091505b50915091506130b9878383876130c4565b979650505050505050565b6060831561313357825160000361312c576001600160a01b0385163b61312c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610768565b5081612a1c565b612a1c83838151156131485781518083602001fd5b8060405162461bcd60e51b815260040161076891906135d6565b6001600160a01b038116811461317757600080fd5b50565b6000806040838503121561318d57600080fd5b823561319881613162565b946020939093013593505050565b6000602082840312156131b857600080fd5b8135611bf281613162565b6000602082840312156131d557600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b81811015613214578351835292840192918401916001016131f8565b50909695505050505050565b60008083601f84011261323257600080fd5b50813567ffffffffffffffff81111561324a57600080fd5b6020830191508360208260051b850101111561326557600080fd5b9250929050565b6000806020838503121561327f57600080fd5b823567ffffffffffffffff81111561329657600080fd5b6132a285828601613220565b90969095509350505050565b6000806000604084860312156132c357600080fd5b83356132ce81613162565b9250602084013567ffffffffffffffff8111156132ea57600080fd5b6132f686828701613220565b9497909650939450505050565b80356001600160801b038116811461331a57600080fd5b919050565b6000806040838503121561333257600080fd5b61333b83613303565b915061334960208401613303565b90509250929050565b60008060006060848603121561336757600080fd5b61337084613303565b925061337e60208501613303565b9150604084013590509250925092565b6000806000606084860312156133a357600080fd5b83356133ae81613162565b95602085013595506040909401359392505050565b600080604083850312156133d657600080fd5b82356133e181613162565b915060208301356133f181613162565b809150509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161343a5761343a613412565b5060010190565b600061ffff80831681810361345857613458613412565b6001019392505050565b60006020828403121561347457600080fd5b8151611bf281613162565b8181038181111561122257611222613412565b8082018082111561122257611222613412565b634e487b7160e01b600052604160045260246000fd5b6001600160801b038181168382160190808211156134db576134db613412565b5092915050565b6000826134ff57634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761122257611222613412565b60006020828403121561352d57600080fd5b81518015158114611bf257600080fd5b60006020828403121561354f57600080fd5b5051919050565b6001600160501b038181168382160190808211156134db576134db613412565b6001600160801b038281168282160390808211156134db576134db613412565b60005b838110156135b1578181015183820152602001613599565b50506000910152565b600082516135cc818460208701613596565b9190910192915050565b60208152600082518060208401526135f5816040850160208701613596565b601f01601f1916919091016040019291505056fea26469706673582212201fce4f14110a933356b45e98603f97693638cb7d57066e07078652596e9e105e64736f6c634300081300330000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf800000000000000000000000035282d87011f87508d457f08252bc5bfa52e10a000000000000000000000000006bdf212c290473dcacea9793890c5024c7eb02c000000000000000000000000db2222735e926f3a18d7d1d0cfeef095a66aea2a000000000000000000000000fe847efbe56bc528b901f1cae6b44d1c77a06db9
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061025e5760003560e01c8063874d6d8111610146578063d279c191116100c3578063e950342511610087578063e950342514610642578063ebe2b12b14610655578063eeb58d0b1461066c578063f05820381461067f578063f8d8989814610692578063fbfa77cf146106b957600080fd5b8063d279c191146105ed578063d5f195fe14610600578063d7936b7e14610613578063db03fdaa1461061c578063e66667331461062f57600080fd5b8063a7528a031161010a578063a7528a031461055e578063c046371114610568578063c45a015514610594578063cc9641a8146105bb578063ce4b5bbe146105e257600080fd5b8063874d6d81146105235780638b8fbd921461052b5780638da5cb5b14610534578063a20baee61461053c578063a4e59ac81461054b57600080fd5b806347636371116101df57806378c77a24116101a357806378c77a24146104025780637b0a47ee1461041557806381bafb311461042857806382e0a57414610432578063835dada01461045d57806386da0824146104b157600080fd5b806347636371146103715780635383dfcb1461037a5780635bbe8aad1461039a5780635e3078ec146103bd57806376671808146103d057600080fd5b806319f27b3b1161022657806319f27b3b146102fc5780631ef3a04c1461030f5780632e54bf9514610336578063307d361214610349578063452a93201461036957600080fd5b806309e2acb0146102635780630d9a6b351461028957806311be0de5146102915780631500d2c3146102a6578063172c48c7146102d1575b600080fd5b61027661027136600461317a565b6106e0565b6040519081526020015b60405180910390f35b600454610276565b6102a461029f3660046131a6565b610706565b005b6102b96102b436600461317a565b61097c565b6040516001600160501b039091168152602001610280565b6102e46102df3660046131c3565b6109bf565b6040516001600160a01b039091168152602001610280565b6102a461030a3660046131a6565b6109e9565b6102e47f000000000000000000000000fe847efbe56bc528b901f1cae6b44d1c77a06db981565b6102a46103443660046131c3565b610c00565b61035c6103573660046131a6565b610e44565b60405161028091906131dc565b6102e46110b6565b61027660005481565b6102766103883660046131a6565b60026020526000908152604090205481565b6103ad6103a836600461326c565b61113f565b6040519015158152602001610280565b6102a46103cb3660046132ae565b611228565b600b546103ea90600160801b90046001600160801b031681565b6040516001600160801b039091168152602001610280565b6102a46104103660046131c3565b6113d7565b6001546103ea906001600160801b031681565b61027661010f5481565b61027661044036600461331f565b600d60209081526000928352604080842090915290825290205481565b61049161046b3660046131a6565b6005602052600090815260409020546001600160801b0380821691600160801b90041682565b604080516001600160801b03938416815292909116602083015201610280565b6104f46104bf3660046131a6565b6006602052600090815260409020805460018201546002909201549091906001600160801b0380821691600160801b90041684565b6040805194855260208501939093526001600160801b0391821692840192909252166060820152608001610280565b610276611682565b610276600a5481565b6102e46116bc565b610276670de0b6b3a764000081565b600b546103ea906001600160801b031681565b6103ea62ed4e0081565b60015461057f90600160801b900463ffffffff1681565b60405163ffffffff9091168152602001610280565b6102e47f000000000000000000000000db2222735e926f3a18d7d1d0cfeef095a66aea2a81565b6102e47f0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf881565b610276633b9aca0081565b6102766105fb3660046131a6565b61171c565b61027661060e3660046131a6565b61180f565b610276600e5481565b61027661062a366004613352565b6118ab565b6102a461063d36600461338e565b6118de565b6102766106503660046131a6565b6118e9565b60015461057f90600160a01b900463ffffffff1681565b61027661067a3660046131c3565b611b9a565b61027661068d3660046133c3565b611bb2565b6102e47f00000000000000000000000035282d87011f87508d457f08252bc5bfa52e10a081565b6102e47f00000000000000000000000006bdf212c290473dcacea9793890c5024c7eb02c81565b60076020528160005260406000208161010081106106fd57600080fd5b01549150829050565b336001600160a01b037f000000000000000000000000db2222735e926f3a18d7d1d0cfeef095a66aea2a16146107715760405162461bcd60e51b815260206004820152600b60248201526a4e6f7420666163746f727960a81b60448201526064015b60405180910390fd5b6003546000805b828110156107d257836001600160a01b03166003828154811061079d5761079d6133fc565b6000918252602090912001546001600160a01b0316036107c057600191506107d2565b806107ca81613428565b915050610778565b508061091257604080518082019091526101115461ffff80821680845262010000909204166020830181905211156108b257805161ffff16600090815261011060209081526040918290208251808401909352546001600160801b038082168452600160801b909104169082018190524211156108b05761011180546101109160009161ffff16908261086483613441565b82546101009290920a61ffff818102199093169183160217909155168152602081019190915260400160009081205580516108a99086906001600160801b0316611bf9565b5050505050565b505b50600380546001810182557fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b0319166001600160a01b038616908117909155905460009182526002602052604090912055505050565b6001600160a01b0383166000908152600260205260409020546109775760405162461bcd60e51b815260206004820152601860248201527f436f6c6c61746572616c2069732073756e73657474696e6700000000000000006044820152606401610768565b505050565b600860205281600052604060002081610100811061099957600080fd5b60039182820401919006600a02915091509054906101000a90046001600160501b031681565b600381815481106109cf57600080fd5b6000918252602090912001546001600160a01b0316905081565b7f0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf86001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610a47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a6b9190613462565b6001600160a01b0316336001600160a01b031614610ab85760405162461bcd60e51b815260206004820152600a60248201526927b7363c9037bbb732b960b11b6044820152606401610768565b6001600160a01b038116600090815260026020526040902054610b1d5760405162461bcd60e51b815260206004820152601d60248201527f436f6c6c61746572616c20616c72656164792073756e73657474696e670000006044820152606401610768565b6040805180820182526001600160a01b0383166000908152600260205291909120548190610b4d9060019061347f565b6001600160801b03168152602001610b6862ed4e0042613492565b6001600160801b0316905261011180546101109160009162010000900461ffff16906002610b9583613441565b825461ffff9182166101009390930a928302928202191691909117909155168152602080820192909252604090810160009081208451948401516001600160801b03908116600160801b029516949094179093556001600160a01b0390931682526002905290812055565b336000908152600560205260409020546001600160801b0380821691600160801b90041681610c8a5760405162461bcd60e51b815260206004820152603060248201527f53746162696c697479506f6f6c3a2055736572206d757374206861766520612060448201526f1b9bdb8b5e995c9bc819195c1bdcda5d60821b6064820152608401610768565b42816001600160801b031610610ce25760405162461bcd60e51b815260206004820181905260248201527f214465706f73697420616e642077697468647261772073616d6520626c6f636b6044820152606401610768565b610cea611e01565b610cf333611fbd565b506000610cff3361180f565b90506000610d0d85836121d9565b9050610d18336121ef565b8015610dad57604051631062c15f60e11b8152306004820152336024820152604481018290527f00000000000000000000000035282d87011f87508d457f08252bc5bfa52e10a06001600160a01b0316906320c582be90606401600060405180830381600087803b158015610d8c57600080fd5b505af1158015610da0573d6000803e3d6000fd5b50505050610dad81612241565b6000610db9828461347f565b6040805180820182526001600160801b03808416825287811660208084019182523360008181526005909252949020925190518216600160801b029116179055909150610e069082612290565b60405181815233907fbce78369dccab09eec1986f4d409ab09ffbb47d65423e5148fcf98411c5111c9906020015b60405180910390a2505050505050565b60035460609067ffffffffffffffff811115610e6257610e626134a5565b604051908082528060200260200182016040528015610e8b578160200160208202803683370190505b506001600160a01b038316600090815260066020526040812054919250819003610eb55750919050565b6001600160a01b0383166000908152600860209081526040808320600583528184205460068452828520600201546001600160801b03600160801b82048116808852600c808852868920938316808a52848952968920828a5297529396921694929392919081610f268560016134bb565b6001600160801b03168152602080820192909252604090810160009081206001600160a01b038d16825260079093529081209192505b89518110156110a85787816101008110610f7857610f786133fc565b60039182820401919006600a029054906101000a90046001600160501b03166001600160501b03168a8281518110610fb257610fb26133fc565b60200260200101818152505083816101008110610fd157610fd16133fc565b01541561109657600082826101008110610fed57610fed6133fc565b015485836101008110611002576110026133fc565b015461100e919061347f565b90506000633b9aca008584610100811061102a5761102a6133fc565b015461103691906134e2565b9050670de0b6b3a76400008b61104c8385613492565b611056908c613504565b61106091906134e2565b61106a91906134e2565b8c848151811061107c5761107c6133fc565b602002602001018181516110909190613492565b90525050505b806110a081613428565b915050610f5c565b505050505050505050919050565b60007f0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf86001600160a01b031663452a93206040518163ffffffff1660e01b8152600401602060405180830381865afa158015611116573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061113a9190613462565b905090565b6000336001600160a01b037f00000000000000000000000006bdf212c290473dcacea9793890c5024c7eb02c161461117657600080fd5b600054156111b95760405162461bcd60e51b815260206004820152601060248201526f105b1c9958591e48185cdcda59db995960821b6044820152606401610768565b600182146111fe5760405162461bcd60e51b8152602060048201526012602482015271125b98dbdc9c9958dd0812510818dbdd5b9d60721b6044820152606401610768565b82826000818110611211576112116133fc565b602002919091013560005550600190505b92915050565b61123133611fbd565b50600354819060009067ffffffffffffffff811115611252576112526134a5565b60405190808252806020026020018201604052801561127b578160200160208202803683370190505b503360009081526008602052604081209192505b8381101561139d5760008686838181106112ab576112ab6133fc565b9050602002013590506000838261010081106112c9576112c96133fc565b60039182820401919006600a029054906101000a90046001600160501b03166001600160501b031690506000811115611393578085838151811061130f5761130f6133fc565b602002602001018181525050600084836101008110611330576113306133fc565b60039182820401919006600a026101000a8154816001600160501b0302191690836001600160501b03160217905550611393898260038581548110611377576113776133fc565b6000918252602090912001546001600160a01b03169190612484565b505060010161128f565b50336001600160a01b03167faecf5c2e84838a7ed87234d73965fc51f96b87b4c957f03bf22cfeb618c9aae183604051610e3491906131dc565b7f0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf86001600160a01b0316635c975abb6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611435573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611459919061351b565b1561149c5760405162461bcd60e51b815260206004820152601360248201527211195c1bdcda5d1cc8185c99481c185d5cd959606a1b6044820152606401610768565b600081116114fb5760405162461bcd60e51b815260206004820152602660248201527f53746162696c697479506f6f6c3a20416d6f756e74206d757374206265206e6f6044820152656e2d7a65726f60d01b6064820152608401610768565b611503611e01565b61150c33611fbd565b5060006115183361180f565b9050611523336121ef565b60405163e75b3ae760e01b8152336004820152602481018390527f00000000000000000000000035282d87011f87508d457f08252bc5bfa52e10a06001600160a01b03169063e75b3ae790604401600060405180830381600087803b15801561158b57600080fd5b505af115801561159f573d6000803e3d6000fd5b505050506000826004546115b39190613492565b60048190556040518181529091507f5c1eb83edfbe7709b9a63e8c7e294df8731e15bc212a85bf6e95cb906600bcbb9060200160405180910390a160006115fa8484613492565b6040805180820182526001600160801b03808416825242811660208084019182523360008181526005909252949020925190518216600160801b0291161790559091506116479082612290565b60405181815233907fbce78369dccab09eec1986f4d409ab09ffbb47d65423e5148fcf98411c5111c99060200160405180910390a250505050565b600062093a806116b27f0000000000000000000000000000000000000000000000000000000064d428804261347f565b61113a91906134e2565b60007f0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf86001600160a01b0316638da5cb5b6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611116573d6000803e3d6000fd5b6000611727336124d6565b905080156117ca576040516335e97f1f60e11b81523360048201526001600160a01b038381166024830152604482018390527f00000000000000000000000006bdf212c290473dcacea9793890c5024c7eb02c1690636bd2fe3e906064016020604051808303816000875af11580156117a4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c8919061351b565b505b6040518181526001600160a01b0383169033907f0aa4d283470c904c551d18bb894d37e17674920f3261a7f854be501e25f421b79060200160405180910390a3919050565b6001600160a01b0381166000908152600560205260408120546001600160801b03168082036118415750600092915050565b6001600160a01b0383166000908152600660209081526040808320815160808101835281548152600182015493810193909352600201546001600160801b0380821692840192909252600160801b9004166060820152906118a28383612629565b95945050505050565b600c6020528260005260406000206020528160005260406000208161010081106118d457600080fd5b0154925083915050565b610977838383612716565b6004546001600160a01b0382166000908152600560205260408120549091906001600160801b031681158061191c575080155b1561193f575050506001600160a01b031660009081526009602052604090205490565b6000600e54670de0b6b3a7640000611955612820565b61195f9190613504565b6119699190613492565b9050600061197784836134e2565b90506000600a54826119899190613504565b6001600160a01b0388166000908152600660209081526040808320815160808101835281548152600182015493810193909352600201546001600160801b03808216928401839052600160801b909104811660608401819052600b549596509294929391928291168303611a97576020808601516001600160801b038087166000908152600d84526040808220928816825291909352909120548791611a2e9161347f565b611a389190613492565b6001600160801b0385166000908152600d60205260408120919350633b9aca009190611a658660016134bb565b6001600160801b03166001600160801b0316815260200190815260200160002054611a9091906134e2565b9050611b33565b6020808601516001600160801b038087166000908152600d8452604080822092881682529190935290912054611acd919061347f565b6001600160801b0385166000908152600d60205260408120919350633b9aca00918891611afb8760016134bb565b6001600160801b03166001600160801b0316815260200190815260200160002054611b269190613492565b611b3091906134e2565b90505b8451670de0b6b3a764000090611b498385613492565b611b53908c613504565b611b5d91906134e2565b611b6791906134e2565b6001600160a01b038d16600090815260096020526040902054611b8a9190613492565b9c9b505050505050505050505050565b600f816101008110611bab57600080fd5b0154905081565b6000336001600160a01b037f00000000000000000000000006bdf212c290473dcacea9793890c5024c7eb02c1614611be957600080fd5b611bf2836124d6565b9392505050565b6001600160a01b03821660009081526002602052604090205415611c5f5760405162461bcd60e51b815260206004820152601960248201527f436f6c6c61746572616c206d7573742062652073756e736574000000000000006044820152606401610768565b600354808210611ca35760405162461bcd60e51b815260206004820152600f60248201526e496e64657820746f6f206c6172676560881b6044820152606401610768565b600b546001600160801b03600160801b82048116911660005b82816001600160801b031611611d2b5760005b82816001600160801b031611611d22576001600160801b038083166000908152600c602090815260408083209385168352929052908120876101008110611d1857611d186133fc565b0155600101611ccf565b50600101611cbc565b50611d37846001613492565b6001600160a01b038616600090815260026020526040902055600380547f9e147d339c63698deb55c3d0d44ed3eba29bac2a068a88c4bc5bde17d6331e19919086908110611d8757611d876133fc565b60009182526020918290200154604080516001600160a01b039283168152918916928201929092520160405180910390a18460038581548110611dcc57611dcc6133fc565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055505050505050565b611e11611e0c612820565b61288b565b600154600160a01b900463ffffffff16600062093a80611e517f0000000000000000000000000000000000000000000000000000000064d428808461347f565b611e5b91906134e2565b905080611e66611682565b10611f9b576000805460405163378cbf7560e01b815260048101919091527f00000000000000000000000006bdf212c290473dcacea9793890c5024c7eb02c6001600160a01b03169063378cbf75906024016020604051808303816000875af1158015611ed7573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611efb919061353d565b90508015611f995782421015611f3e576000611f17428561347f565b600154909150611f30906001600160801b031682613504565b611f3a9083613492565b9150505b611f4b62093a80826134e2565b600180546001600160801b0319166001600160801b0392909216919091179055611f7862093a8042613492565b600160146101000a81548163ffffffff021916908363ffffffff1602179055505b505b50506001805463ffffffff60801b1916600160801b4263ffffffff1602179055565b6001600160a01b03811660009081526008602090815260408083206003546005909352908320549091906001600160801b0316808403611fff57505050919050565b6001600160a01b0385166000908152600660209081526040808320600281015490546001600160801b03600160801b83048116808752600c808752858820929094168088528287529487208188529390955293949293909290816120648660016134bb565b6001600160801b03168152602080820192909252604090810160009081206001600160a01b038e16825260079093529081209192505b888110156121ca57838161010081106120b5576120b56133fc565b0154156121b85760019a506000828261010081106120d5576120d56133fc565b0154858361010081106120ea576120ea6133fc565b01546120f6919061347f565b90506000633b9aca0085846101008110612112576121126133fc565b015461211e91906134e2565b9050670de0b6b3a7640000876121348385613492565b61213e908d613504565b61214891906134e2565b61215291906134e2565b8c846101008110612165576121656133fc565b60039182820401919006600a028282829054906101000a90046001600160501b03166121919190613556565b92506101000a8154816001600160501b0302191690836001600160501b0316021790555050505b806121c281613428565b91505061209a565b50505050505050505050919050565b60008183106121e85781611bf2565b5090919050565b60006121fa82612987565b6001600160a01b038316600090815260096020526040902054909150612221908290613492565b6001600160a01b0390921660009081526009602052604090209190915550565b600081600454612251919061347f565b60048190556040518181529091507f5c1eb83edfbe7709b9a63e8c7e294df8731e15bc212a85bf6e95cb906600bcbb9060200160405180910390a15050565b60008160000361235857506001600160a01b038216600090815260066020526040812081815560018101829055600201819055600354905b8181101561230e576001600160a01b03841660009081526007602052604081208261010081106122fa576122fa6133fc565b01558061230681613428565b9150506122c8565b5060408051600080825260208201526001600160a01b038516917fc48943df4095f4f20d171fd2872eafdc0eed4d9014ac3672f3bde7fd425449d5910160405180910390a2505050565b50600b54600a546001600160801b03600160801b80840482166000818152600c6020908152604080832095909716808352948152868220838352600d82528783208684528252878320546001600160a01b038b168452600690925296822086815560018101829055938302851760029094019390935560035495939491939192905b8681101561243557828161010081106123f5576123f56133fc565b01546001600160a01b038a166000908152600760205260409020826101008110612421576124216133fc565b01558061242d81613428565b9150506123da565b5060408051848152602081018390526001600160a01b038a16917fc48943df4095f4f20d171fd2872eafdc0eed4d9014ac3672f3bde7fd425449d5910160405180910390a25050505050505050565b604080516001600160a01b038416602482015260448082018490528251808303909101815260649091019091526020810180516001600160e01b031663a9059cbb60e01b179052610977908490612a24565b6001600160a01b0381166000908152600560205260408120546001600160801b031680156125dd576001600160a01b038316600090815260056020526040902054600160801b90046001600160801b031661252f611e01565b600061253a85611fbd565b905060006125478661180f565b90506000612555828661347f565b905061256087612987565b9550600081118061256e5750825b806125795750600086115b156125d8576040805180820182526001600160801b03808516825286811660208084019182526001600160a01b038c166000908152600590915293909320915192518116600160801b029216919091179055816125d68882612290565b505b505050505b6001600160a01b0383166000908152600960205260409020548015612622576126068184613492565b6001600160a01b03851660009081526009602052604081205592505b5050919050565b805160408201516060830151600b546000939291906001600160801b03600160801b909104811690821610156126655760009350505050611222565b600b5460009081906126819085906001600160801b0316613576565b9050806001600160801b03166000036126b45784600a54896126a39190613504565b6126ad91906134e2565b91506126e8565b806001600160801b03166001036126e357633b9aca0085600a548a6126d99190613504565b6126a391906134e2565b600091505b6126f6633b9aca00896134e2565b82101561270b57600095505050505050611222565b509695505050505050565b336001600160a01b037f000000000000000000000000fe847efbe56bc528b901f1cae6b44d1c77a06db916146127a75760405162461bcd60e51b815260206004820152603060248201527f53746162696c697479506f6f6c3a2043616c6c6572206973206e6f74204c697160448201526f3ab4b230ba34b7b71026b0b730b3b2b960811b6064820152608401610768565b6001600160a01b0383166000908152600260205260409020546127cb60018261347f565b6004549091508015806127dc575083155b156127e8575050505050565b6127f0611e01565b6000806127ff85878587612af9565b9150915061280e828286612be6565b61281786612241565b50505050505050565b600154600090600160a01b900463ffffffff164281111561283e5750425b600154600160801b900463ffffffff1681811061285e5760009250505090565b600061286a828461347f565b600154909150612883906001600160801b031682613504565b935050505090565b600454801580612899575081155b156128a2575050565b60006128ae8383612f08565b600b54600a549192506001600160801b03600160801b82048116929116906000906128d99085613504565b6001600160801b038085166000908152600d6020908152604080832093871683529290529081205491925090612910908390613492565b6001600160801b038581166000818152600d60209081526040808320948916808452948252918290208590558151858152908101929092528101919091529091507f2d6127771b164a9cc8827d24b5955db2a77e7a81dac389107ebb8bce9fb649689060600160405180910390a150505050505050565b6001600160a01b0381166000908152600560205260408120546001600160801b03168082036129b95750600092915050565b6001600160a01b038316600090815260066020908152604091829020825160808101845281548152600182015492810192909252600201546001600160801b0380821693830193909352600160801b90049091166060820152612a1c8282612f5b565b949350505050565b6000612a79826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b031661303f9092919063ffffffff16565b9050805160001480612a9a575080806020019051810190612a9a919061351b565b6109775760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610768565b6000806000600f846101008110612b1257612b126133fc565b0154612b26670de0b6b3a764000089613504565b612b309190613492565b9050848603612b4f57600061010f55670de0b6b3a76400009150612ba6565b61010f54600090612b68670de0b6b3a764000089613504565b612b72919061347f565b9050612b7e86826134e2565b612b89906001613492565b925080612b968785613504565b612ba0919061347f565b61010f55505b612bb085826134e2565b9250612bbc8584613504565b612bc6908261347f565b600f856101008110612bda57612bda6133fc565b01555094509492505050565b600a54600080612bfe85670de0b6b3a764000061347f565b600b546001600160801b03600160801b820481166000818152600c60209081526040808320949095168083529390529283209394509092909190876101008110612c4a57612c4a6133fc565b015490506000612c5a878b613504565b90506000612c688284613492565b6001600160801b038086166000908152600c60209081526040808320938a1683529290522090915081908a6101008110612ca457612ca46133fc565b0155604080518a8152602081018390526001600160801b03868116828401528716606082015290517fe150473acddd94d1c6add794bd840c8d3e297dc3e50d863b56c0fba04d0d02479181900360800190a185600003612db257612d098460016134bb565b600b80546001600160801b03908116600160801b93821684021791829055604051929091041681527fb50f0f59e7cb5b421dc77581c3a9919e3806e076e5fa78a874c3f120cb7d874d9060200160405180910390a1600b80546001600160801b0319169055604051600081527f1f9dfc70cd666adb18a39d60a797518f7b4febf4b6e24ef37d44f6e1e7219fbe9060200160405180910390a1670de0b6b3a76400009650612e8a565b633b9aca00670de0b6b3a7640000612dca888b613504565b612dd491906134e2565b1015612e6a57670de0b6b3a7640000633b9aca00612df2888b613504565b612dfc9190613504565b612e0691906134e2565b9650612e138560016134bb565b600b80546001600160801b0319166001600160801b039290921691821790556040519081527f1f9dfc70cd666adb18a39d60a797518f7b4febf4b6e24ef37d44f6e1e7219fbe9060200160405180910390a1612e8a565b670de0b6b3a7640000612e7d878a613504565b612e8791906134e2565b96505b60008711612ec35760405162461bcd60e51b81526004016107689060208082526004908201526304e6577560e41b604082015260600190565b600a8790556040518781527fc1a9618cb59ebca77cbdbc2949f126823c407ff13edb285fd0262519a9c18e8c9060200160405180910390a15050505050505050505050565b600080600e54670de0b6b3a764000085612f229190613504565b612f2c9190613492565b90506000612f3a84836134e2565b9050612f468482613504565b612f50908361347f565b600e55949350505050565b606081015160408083015160208085015185516001600160801b038087166000908152600d8552868120918616815293529382205491949390918590612fa290849061347f565b6001600160801b0386166000908152600d6020526040812091925090633b9aca009082612fd08860016134bb565b6001600160801b03166001600160801b0316815260200190815260200160002054612ffb91906134e2565b90506000670de0b6b3a7640000846130138486613492565b61301d908d613504565b61302791906134e2565b61303191906134e2565b9a9950505050505050505050565b6060612a1c848460008585600080866001600160a01b0316858760405161306691906135ba565b60006040518083038185875af1925050503d80600081146130a3576040519150601f19603f3d011682016040523d82523d6000602084013e6130a8565b606091505b50915091506130b9878383876130c4565b979650505050505050565b6060831561313357825160000361312c576001600160a01b0385163b61312c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610768565b5081612a1c565b612a1c83838151156131485781518083602001fd5b8060405162461bcd60e51b815260040161076891906135d6565b6001600160a01b038116811461317757600080fd5b50565b6000806040838503121561318d57600080fd5b823561319881613162565b946020939093013593505050565b6000602082840312156131b857600080fd5b8135611bf281613162565b6000602082840312156131d557600080fd5b5035919050565b6020808252825182820181905260009190848201906040850190845b81811015613214578351835292840192918401916001016131f8565b50909695505050505050565b60008083601f84011261323257600080fd5b50813567ffffffffffffffff81111561324a57600080fd5b6020830191508360208260051b850101111561326557600080fd5b9250929050565b6000806020838503121561327f57600080fd5b823567ffffffffffffffff81111561329657600080fd5b6132a285828601613220565b90969095509350505050565b6000806000604084860312156132c357600080fd5b83356132ce81613162565b9250602084013567ffffffffffffffff8111156132ea57600080fd5b6132f686828701613220565b9497909650939450505050565b80356001600160801b038116811461331a57600080fd5b919050565b6000806040838503121561333257600080fd5b61333b83613303565b915061334960208401613303565b90509250929050565b60008060006060848603121561336757600080fd5b61337084613303565b925061337e60208501613303565b9150604084013590509250925092565b6000806000606084860312156133a357600080fd5b83356133ae81613162565b95602085013595506040909401359392505050565b600080604083850312156133d657600080fd5b82356133e181613162565b915060208301356133f181613162565b809150509250929050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161343a5761343a613412565b5060010190565b600061ffff80831681810361345857613458613412565b6001019392505050565b60006020828403121561347457600080fd5b8151611bf281613162565b8181038181111561122257611222613412565b8082018082111561122257611222613412565b634e487b7160e01b600052604160045260246000fd5b6001600160801b038181168382160190808211156134db576134db613412565b5092915050565b6000826134ff57634e487b7160e01b600052601260045260246000fd5b500490565b808202811582820484141761122257611222613412565b60006020828403121561352d57600080fd5b81518015158114611bf257600080fd5b60006020828403121561354f57600080fd5b5051919050565b6001600160501b038181168382160190808211156134db576134db613412565b6001600160801b038281168282160390808211156134db576134db613412565b60005b838110156135b1578181015183820152602001613599565b50506000910152565b600082516135cc818460208701613596565b9190910192915050565b60208152600082518060208401526135f5816040850160208701613596565b601f01601f1916919091016040019291505056fea26469706673582212201fce4f14110a933356b45e98603f97693638cb7d57066e07078652596e9e105e64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf800000000000000000000000035282d87011f87508d457f08252bc5bfa52e10a000000000000000000000000006bdf212c290473dcacea9793890c5024c7eb02c000000000000000000000000db2222735e926f3a18d7d1d0cfeef095a66aea2a000000000000000000000000fe847efbe56bc528b901f1cae6b44d1c77a06db9
-----Decoded View---------------
Arg [0] : _prismaCore (address): 0x5d17eA085F2FF5da3e6979D5d26F1dBaB664ccf8
Arg [1] : _debtTokenAddress (address): 0x35282d87011f87508D457F08252Bc5bFa52E10A0
Arg [2] : _vault (address): 0x06bDF212C290473dCACea9793890C5024c7Eb02c
Arg [3] : _factory (address): 0xDb2222735e926f3a18D7d1D0CFeEf095A66Aea2A
Arg [4] : _liquidationManager (address): 0xfE847eFBe56bC528b901F1CAe6B44D1c77a06DB9
-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000005d17ea085f2ff5da3e6979d5d26f1dbab664ccf8
Arg [1] : 00000000000000000000000035282d87011f87508d457f08252bc5bfa52e10a0
Arg [2] : 00000000000000000000000006bdf212c290473dcacea9793890c5024c7eb02c
Arg [3] : 000000000000000000000000db2222735e926f3a18d7d1d0cfeef095a66aea2a
Arg [4] : 000000000000000000000000fe847efbe56bc528b901f1cae6b44d1c77a06db9
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.