Source Code
Overview
S Balance
0 S
More Info
ContractCreator
Loading...
Loading
Contract Source Code Verified (Exact Match)
Contract Name:
CollateralRegistry
Compiler Version
v0.8.24+commit.e11b9ed9
Optimization Enabled:
Yes with 200 runs
Other Settings:
cancun EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; import "openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "./Interfaces/ITroveManager.sol"; import "./Interfaces/IBoldToken.sol"; import "./Dependencies/Constants.sol"; import "./Dependencies/LiquityMath.sol"; import "./Interfaces/ICollateralRegistry.sol"; contract CollateralRegistry is ICollateralRegistry { // See: https://github.com/ethereum/solidity/issues/12587 uint256 public immutable totalCollaterals; IERC20Metadata internal immutable token0; IERC20Metadata internal immutable token1; IERC20Metadata internal immutable token2; IERC20Metadata internal immutable token3; IERC20Metadata internal immutable token4; IERC20Metadata internal immutable token5; IERC20Metadata internal immutable token6; IERC20Metadata internal immutable token7; IERC20Metadata internal immutable token8; IERC20Metadata internal immutable token9; ITroveManager internal immutable troveManager0; ITroveManager internal immutable troveManager1; ITroveManager internal immutable troveManager2; ITroveManager internal immutable troveManager3; ITroveManager internal immutable troveManager4; ITroveManager internal immutable troveManager5; ITroveManager internal immutable troveManager6; ITroveManager internal immutable troveManager7; ITroveManager internal immutable troveManager8; ITroveManager internal immutable troveManager9; IBoldToken public immutable boldToken; uint256 public baseRate; // The timestamp of the latest fee operation (redemption or new Bold issuance) uint256 public lastFeeOperationTime = block.timestamp; event BaseRateUpdated(uint256 _baseRate); event LastFeeOpTimeUpdated(uint256 _lastFeeOpTime); constructor(IBoldToken _boldToken, IERC20Metadata[] memory _tokens, ITroveManager[] memory _troveManagers) { uint256 numTokens = _tokens.length; require(numTokens > 0, "Collateral list cannot be empty"); require(numTokens <= 10, "Collateral list too long"); totalCollaterals = numTokens; boldToken = _boldToken; token0 = _tokens[0]; token1 = numTokens > 1 ? _tokens[1] : IERC20Metadata(address(0)); token2 = numTokens > 2 ? _tokens[2] : IERC20Metadata(address(0)); token3 = numTokens > 3 ? _tokens[3] : IERC20Metadata(address(0)); token4 = numTokens > 4 ? _tokens[4] : IERC20Metadata(address(0)); token5 = numTokens > 5 ? _tokens[5] : IERC20Metadata(address(0)); token6 = numTokens > 6 ? _tokens[6] : IERC20Metadata(address(0)); token7 = numTokens > 7 ? _tokens[7] : IERC20Metadata(address(0)); token8 = numTokens > 8 ? _tokens[8] : IERC20Metadata(address(0)); token9 = numTokens > 9 ? _tokens[9] : IERC20Metadata(address(0)); troveManager0 = _troveManagers[0]; troveManager1 = numTokens > 1 ? _troveManagers[1] : ITroveManager(address(0)); troveManager2 = numTokens > 2 ? _troveManagers[2] : ITroveManager(address(0)); troveManager3 = numTokens > 3 ? _troveManagers[3] : ITroveManager(address(0)); troveManager4 = numTokens > 4 ? _troveManagers[4] : ITroveManager(address(0)); troveManager5 = numTokens > 5 ? _troveManagers[5] : ITroveManager(address(0)); troveManager6 = numTokens > 6 ? _troveManagers[6] : ITroveManager(address(0)); troveManager7 = numTokens > 7 ? _troveManagers[7] : ITroveManager(address(0)); troveManager8 = numTokens > 8 ? _troveManagers[8] : ITroveManager(address(0)); troveManager9 = numTokens > 9 ? _troveManagers[9] : ITroveManager(address(0)); // Initialize the baseRate state variable baseRate = INITIAL_BASE_RATE; emit BaseRateUpdated(INITIAL_BASE_RATE); } struct RedemptionTotals { uint256 numCollaterals; uint256 boldSupplyAtStart; uint256 unbacked; uint256 redeemedAmount; } function redeemCollateral(uint256 _boldAmount, uint256 _maxIterationsPerCollateral, uint256 _maxFeePercentage) external { _requireValidMaxFeePercentage(_maxFeePercentage); _requireAmountGreaterThanZero(_boldAmount); RedemptionTotals memory totals; totals.numCollaterals = totalCollaterals; uint256[] memory unbackedPortions = new uint256[](totals.numCollaterals); uint256[] memory prices = new uint256[](totals.numCollaterals); totals.boldSupplyAtStart = boldToken.totalSupply(); // Decay the baseRate due to time passed, and then increase it according to the size of this redemption. // Use the saved total Bold supply value, from before it was reduced by the redemption. // We only compute it here, and update it at the end, // because the final redeemed amount may be less than the requested amount // Redeemers should take this into account in order to request the optimal amount to not overpay uint256 redemptionRate = _calcRedemptionRate(_getUpdatedBaseRateFromRedemption(_boldAmount, totals.boldSupplyAtStart)); require(redemptionRate <= _maxFeePercentage, "CR: Fee exceeded provided maximum"); // Implicit by the above and the _requireValidMaxFeePercentage checks //require(newBaseRate < DECIMAL_PRECISION, "CR: Fee would eat up all collateral"); // Gather and accumulate unbacked portions for (uint256 index = 0; index < totals.numCollaterals; index++) { ITroveManager troveManager = getTroveManager(index); (uint256 unbackedPortion, uint256 price, bool redeemable) = troveManager.getUnbackedPortionPriceAndRedeemability(); prices[index] = price; if (redeemable) { totals.unbacked += unbackedPortion; unbackedPortions[index] = unbackedPortion; } } // There’s an unlikely scenario where all the normally redeemable branches (i.e. having TCR > SCR) have 0 unbacked // In that case, we redeem proportinally to branch size if (totals.unbacked == 0) { unbackedPortions = new uint256[](totals.numCollaterals); for (uint256 index = 0; index < totals.numCollaterals; index++) { ITroveManager troveManager = getTroveManager(index); (,, bool redeemable) = troveManager.getUnbackedPortionPriceAndRedeemability(); if (redeemable) { uint256 unbackedPortion = troveManager.getEntireSystemDebt(); totals.unbacked += unbackedPortion; unbackedPortions[index] = unbackedPortion; } } } // Compute redemption amount for each collateral and redeem against the corresponding TroveManager for (uint256 index = 0; index < totals.numCollaterals; index++) { //uint256 unbackedPortion = unbackedPortions[index]; if (unbackedPortions[index] > 0) { uint256 redeemAmount = _boldAmount * unbackedPortions[index] / totals.unbacked; if (redeemAmount > 0) { ITroveManager troveManager = getTroveManager(index); uint256 redeemedAmount = troveManager.redeemCollateral( msg.sender, redeemAmount, prices[index], redemptionRate, _maxIterationsPerCollateral ); totals.redeemedAmount += redeemedAmount; } } } _updateBaseRateAndGetRedemptionRate(totals.redeemedAmount, totals.boldSupplyAtStart); // Burn the total Bold that is cancelled with debt if (totals.redeemedAmount > 0) { boldToken.burn(msg.sender, totals.redeemedAmount); } } // --- Internal fee functions --- // Update the last fee operation time only if time passed >= decay interval. This prevents base rate griefing. function _updateLastFeeOpTime() internal { uint256 timePassed = block.timestamp - lastFeeOperationTime; if (timePassed >= ONE_MINUTE) { lastFeeOperationTime = block.timestamp; emit LastFeeOpTimeUpdated(block.timestamp); } } function _minutesPassedSinceLastFeeOp() internal view returns (uint256) { return (block.timestamp - lastFeeOperationTime) / ONE_MINUTE; } // Updates the `baseRate` state with math from `_getUpdatedBaseRateFromRedemption` function _updateBaseRateAndGetRedemptionRate(uint256 _boldAmount, uint256 _totalBoldSupplyAtStart) internal { uint256 newBaseRate = _getUpdatedBaseRateFromRedemption(_boldAmount, _totalBoldSupplyAtStart); //assert(newBaseRate <= DECIMAL_PRECISION); // This is already enforced in `_getUpdatedBaseRateFromRedemption` // Update the baseRate state variable baseRate = newBaseRate; emit BaseRateUpdated(newBaseRate); _updateLastFeeOpTime(); } /* * This function calculates the new baseRate in the following way: * 1) decays the baseRate based on time passed since last redemption or Bold borrowing operation. * then, * 2) increases the baseRate based on the amount redeemed, as a proportion of total supply */ function _getUpdatedBaseRateFromRedemption(uint256 _redeemAmount, uint256 _totalBoldSupply) internal view returns (uint256) { // decay the base rate uint256 decayedBaseRate = _calcDecayedBaseRate(); // get the fraction of total supply that was redeemed uint256 redeemedBoldFraction = _redeemAmount * DECIMAL_PRECISION / _totalBoldSupply; uint256 newBaseRate = decayedBaseRate + redeemedBoldFraction / REDEMPTION_BETA; newBaseRate = LiquityMath._min(newBaseRate, DECIMAL_PRECISION); // cap baseRate at a maximum of 100% return newBaseRate; } function _calcDecayedBaseRate() internal view returns (uint256) { uint256 minutesPassed = _minutesPassedSinceLastFeeOp(); uint256 decayFactor = LiquityMath._decPow(REDEMPTION_MINUTE_DECAY_FACTOR, minutesPassed); return baseRate * decayFactor / DECIMAL_PRECISION; } function _calcRedemptionRate(uint256 _baseRate) internal pure returns (uint256) { return LiquityMath._min( REDEMPTION_FEE_FLOOR + _baseRate, DECIMAL_PRECISION // cap at a maximum of 100% ); } function _calcRedemptionFee(uint256 _redemptionRate, uint256 _amount) internal pure returns (uint256) { uint256 redemptionFee = _redemptionRate * _amount / DECIMAL_PRECISION; return redemptionFee; } // external redemption rate/fee getters function getRedemptionRate() external view override returns (uint256) { return _calcRedemptionRate(baseRate); } function getRedemptionRateWithDecay() public view override returns (uint256) { return _calcRedemptionRate(_calcDecayedBaseRate()); } function getRedemptionRateForRedeemedAmount(uint256 _redeemAmount) external view returns (uint256) { uint256 totalBoldSupply = boldToken.totalSupply(); uint256 newBaseRate = _getUpdatedBaseRateFromRedemption(_redeemAmount, totalBoldSupply); return _calcRedemptionRate(newBaseRate); } function getRedemptionFeeWithDecay(uint256 _ETHDrawn) external view override returns (uint256) { return _calcRedemptionFee(getRedemptionRateWithDecay(), _ETHDrawn); } function getEffectiveRedemptionFeeInBold(uint256 _redeemAmount) external view override returns (uint256) { uint256 totalBoldSupply = boldToken.totalSupply(); uint256 newBaseRate = _getUpdatedBaseRateFromRedemption(_redeemAmount, totalBoldSupply); return _calcRedemptionFee(_calcRedemptionRate(newBaseRate), _redeemAmount); } // getters function getToken(uint256 _index) external view returns (IERC20Metadata) { if (_index == 0) return token0; else if (_index == 1) return token1; else if (_index == 2) return token2; else if (_index == 3) return token3; else if (_index == 4) return token4; else if (_index == 5) return token5; else if (_index == 6) return token6; else if (_index == 7) return token7; else if (_index == 8) return token8; else if (_index == 9) return token9; else revert("Invalid index"); } function getTroveManager(uint256 _index) public view returns (ITroveManager) { if (_index == 0) return troveManager0; else if (_index == 1) return troveManager1; else if (_index == 2) return troveManager2; else if (_index == 3) return troveManager3; else if (_index == 4) return troveManager4; else if (_index == 5) return troveManager5; else if (_index == 6) return troveManager6; else if (_index == 7) return troveManager7; else if (_index == 8) return troveManager8; else if (_index == 9) return troveManager9; else revert("Invalid index"); } // require functions function _requireValidMaxFeePercentage(uint256 _maxFeePercentage) internal pure { require( _maxFeePercentage >= REDEMPTION_FEE_FLOOR && _maxFeePercentage <= DECIMAL_PRECISION, "Max fee percentage must be between 0.5% and 100%" ); } function _requireAmountGreaterThanZero(uint256 _amount) internal pure { require(_amount > 0, "CollateralRegistry: Amount must be greater than zero"); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC-20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ILiquityBase.sol"; import "./ITroveNFT.sol"; import "./IBorrowerOperations.sol"; import "./IStabilityPool.sol"; import "./IBoldToken.sol"; import "./ISortedTroves.sol"; import "../Types/LatestTroveData.sol"; import "../Types/LatestBatchData.sol"; // Common interface for the Trove Manager. interface ITroveManager is ILiquityBase { enum Status { nonExistent, active, closedByOwner, closedByLiquidation, zombie } function shutdownTime() external view returns (uint256); function troveNFT() external view returns (ITroveNFT); function stabilityPool() external view returns (IStabilityPool); //function boldToken() external view returns (IBoldToken); function sortedTroves() external view returns (ISortedTroves); function borrowerOperations() external view returns (IBorrowerOperations); function Troves(uint256 _id) external view returns ( uint256 debt, uint256 coll, uint256 stake, Status status, uint64 arrayIndex, uint64 lastDebtUpdateTime, uint64 lastInterestRateAdjTime, uint256 annualInterestRate, address interestBatchManager, uint256 batchDebtShares ); function rewardSnapshots(uint256 _id) external view returns (uint256 coll, uint256 boldDebt); function getTroveIdsCount() external view returns (uint256); function getTroveFromTroveIdsArray(uint256 _index) external view returns (uint256); function getCurrentICR(uint256 _troveId, uint256 _price) external view returns (uint256); function lastZombieTroveId() external view returns (uint256); function batchLiquidateTroves(uint256[] calldata _troveArray) external; function redeemCollateral( address _sender, uint256 _boldAmount, uint256 _price, uint256 _redemptionRate, uint256 _maxIterations ) external returns (uint256 _redemeedAmount); function shutdown() external; function urgentRedemption(uint256 _boldAmount, uint256[] calldata _troveIds, uint256 _minCollateral) external; function getUnbackedPortionPriceAndRedeemability() external returns (uint256, uint256, bool); function getLatestTroveData(uint256 _troveId) external view returns (LatestTroveData memory); function getTroveAnnualInterestRate(uint256 _troveId) external view returns (uint256); function getTroveStatus(uint256 _troveId) external view returns (Status); function getLatestBatchData(address _batchAddress) external view returns (LatestBatchData memory); // -- permissioned functions called by BorrowerOperations function onOpenTrove(address _owner, uint256 _troveId, TroveChange memory _troveChange, uint256 _annualInterestRate) external; function onOpenTroveAndJoinBatch( address _owner, uint256 _troveId, TroveChange memory _troveChange, address _batchAddress, uint256 _batchColl, uint256 _batchDebt ) external; // Called from `adjustZombieTrove()` function setTroveStatusToActive(uint256 _troveId) external; function onAdjustTroveInterestRate( uint256 _troveId, uint256 _newColl, uint256 _newDebt, uint256 _newAnnualInterestRate, TroveChange calldata _troveChange ) external; function onAdjustTrove(uint256 _troveId, uint256 _newColl, uint256 _newDebt, TroveChange calldata _troveChange) external; function onAdjustTroveInsideBatch( uint256 _troveId, uint256 _newTroveColl, uint256 _newTroveDebt, TroveChange memory _troveChange, address _batchAddress, uint256 _newBatchColl, uint256 _newBatchDebt ) external; function onApplyTroveInterest( uint256 _troveId, uint256 _newTroveColl, uint256 _newTroveDebt, address _batchAddress, uint256 _newBatchColl, uint256 _newBatchDebt, TroveChange calldata _troveChange ) external; function onCloseTrove( uint256 _troveId, TroveChange memory _troveChange, // decrease vars: entire, with interest, batch fee and redistribution address _batchAddress, uint256 _newBatchColl, uint256 _newBatchDebt // entire, with interest and batch fee ) external; // -- batches -- function onRegisterBatchManager(address _batchAddress, uint256 _annualInterestRate, uint256 _annualFee) external; function onLowerBatchManagerAnnualFee( address _batchAddress, uint256 _newColl, uint256 _newDebt, uint256 _newAnnualManagementFee ) external; function onSetBatchManagerAnnualInterestRate( address _batchAddress, uint256 _newColl, uint256 _newDebt, uint256 _newAnnualInterestRate, uint256 _upfrontFee // needed by BatchUpdated event ) external; struct OnSetInterestBatchManagerParams { uint256 troveId; uint256 troveColl; // entire, with redistribution uint256 troveDebt; // entire, with interest, batch fee and redistribution TroveChange troveChange; address newBatchAddress; uint256 newBatchColl; // updated collateral for new batch manager uint256 newBatchDebt; // updated debt for new batch manager } function onSetInterestBatchManager(OnSetInterestBatchManagerParams calldata _params) external; function onRemoveFromBatch( uint256 _troveId, uint256 _newTroveColl, // entire, with redistribution uint256 _newTroveDebt, // entire, with interest, batch fee and redistribution TroveChange memory _troveChange, address _batchAddress, uint256 _newBatchColl, uint256 _newBatchDebt, // entire, with interest and batch fee uint256 _newAnnualInterestRate ) external; // -- end of permissioned functions -- }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IERC20Metadata} from "openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {IERC5267} from "openzeppelin-contracts/contracts/interfaces/IERC5267.sol"; interface IBoldToken is IERC20Metadata, IERC5267 { function setBranchAddresses( address _troveManagerAddress, address _stabilityPoolAddress, address _borrowerOperationsAddress, address _activePoolAddress ) external; function setCollateralRegistry(address _collateralRegistryAddress) external; function mint(address _account, uint256 _amount) external; function burn(address _account, uint256 _amount) external; function sendToPool(address _sender, address poolAddress, uint256 _amount) external; function returnFromPool(address poolAddress, address user, uint256 _amount) external; }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.24; address constant ZERO_ADDRESS = address(0); uint256 constant MAX_UINT256 = type(uint256).max; uint256 constant DECIMAL_PRECISION = 1e18; uint256 constant _100pct = DECIMAL_PRECISION; uint256 constant _1pct = DECIMAL_PRECISION / 100; // Amount of ETH to be locked in gas pool on opening troves uint256 constant ETH_GAS_COMPENSATION = 0.0375 ether; // Fraction of collateral awarded to liquidator uint256 constant COLL_GAS_COMPENSATION_DIVISOR = 200; // dividing by 200 yields 0.5% uint256 constant COLL_GAS_COMPENSATION_CAP = 2 ether; // Max coll gas compensation capped at 2 ETH // Minimum amount of net Bold debt a trove must have uint256 constant MIN_DEBT = 2000e18; uint256 constant MIN_ANNUAL_INTEREST_RATE = _1pct / 2; // 0.5% uint256 constant MAX_ANNUAL_INTEREST_RATE = _100pct; // Batch management params uint128 constant MAX_ANNUAL_BATCH_MANAGEMENT_FEE = uint128(_100pct); uint128 constant MIN_INTEREST_RATE_CHANGE_PERIOD = 1 seconds; // prevents more than one adjustment per block uint256 constant REDEMPTION_FEE_FLOOR = _1pct / 2; // 0.5% // For the debt / shares ratio to increase by a factor 1e9 // at a average annual debt increase (compounded interest + fees) of 10%, it would take more than 217 years (log(1e9)/log(1.1)) // at a average annual debt increase (compounded interest + fees) of 50%, it would take more than 51 years (log(1e9)/log(1.5)) // The increase pace could be forced to be higher through an inflation attack, // but precisely the fact that we have this max value now prevents the attack uint256 constant MAX_BATCH_SHARES_RATIO = 1e9; // Half-life of 12h. 12h = 720 min // (1/2) = d^720 => d = (1/2)^(1/720) uint256 constant REDEMPTION_MINUTE_DECAY_FACTOR = 999037758833783000; // BETA: 18 digit decimal. Parameter by which to divide the redeemed fraction, in order to calc the new base rate from a redemption. // Corresponds to (1 / ALPHA) in the white paper. uint256 constant REDEMPTION_BETA = 2; // To prevent redemptions unless Bold depegs below 0.95 and allow the system to take off uint256 constant INITIAL_BASE_RATE = 5 * _1pct - REDEMPTION_FEE_FLOOR; // 5% initial redemption rate // Discount to be used once the shutdown thas been triggered uint256 constant URGENT_REDEMPTION_BONUS = 1e16; // 1% uint256 constant ONE_MINUTE = 1 minutes; uint256 constant ONE_YEAR = 365 days; uint256 constant UPFRONT_INTEREST_PERIOD = 7 days; uint256 constant INTEREST_RATE_ADJ_COOLDOWN = 3 days; uint256 constant SP_YIELD_SPLIT = 72 * _1pct; // 72% // Dummy contract that lets legacy Hardhat tests query some of the constants contract Constants { uint256 public constant _ETH_GAS_COMPENSATION = ETH_GAS_COMPENSATION; uint256 public constant _MIN_DEBT = MIN_DEBT; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; import {DECIMAL_PRECISION} from "./Constants.sol"; library LiquityMath { function _min(uint256 _a, uint256 _b) internal pure returns (uint256) { return (_a < _b) ? _a : _b; } function _max(uint256 _a, uint256 _b) internal pure returns (uint256) { return (_a >= _b) ? _a : _b; } function _sub_min_0(uint256 _a, uint256 _b) internal pure returns (uint256) { return (_a > _b) ? _a - _b : 0; } /* * 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 function CollateralRegistry._calcDecayedBaseRate, that represent time in units of minutes * * 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 _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 debt is 0. Represents "infinite" CR. else { // if (_debt == 0) return 2 ** 256 - 1; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import "./IBoldToken.sol"; import "./ITroveManager.sol"; interface ICollateralRegistry { function baseRate() external view returns (uint256); function lastFeeOperationTime() external view returns (uint256); function redeemCollateral(uint256 _boldamount, uint256 _maxIterations, uint256 _maxFeePercentage) external; // getters function totalCollaterals() external view returns (uint256); function getToken(uint256 _index) external view returns (IERC20Metadata); function getTroveManager(uint256 _index) external view returns (ITroveManager); function boldToken() external view returns (IBoldToken); function getRedemptionRate() external view returns (uint256); function getRedemptionRateWithDecay() external view returns (uint256); function getRedemptionRateForRedeemedAmount(uint256 _redeemAmount) external view returns (uint256); function getRedemptionFeeWithDecay(uint256 _ETHDrawn) external view returns (uint256); function getEffectiveRedemptionFeeInBold(uint256 _redeemAmount) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-20 standard as defined in the ERC. */ 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 value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` 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 value) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IActivePool.sol"; import "./IDefaultPool.sol"; import "./IPriceFeed.sol"; interface ILiquityBase { function activePool() external view returns (IActivePool); function getEntireSystemDebt() external view returns (uint256); function getEntireSystemColl() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "openzeppelin-contracts/contracts/token/ERC721/extensions/IERC721Metadata.sol"; import "./ITroveManager.sol"; interface ITroveNFT is IERC721Metadata { function mint(address _owner, uint256 _troveId) external; function burn(uint256 _troveId) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ILiquityBase.sol"; import "./IAddRemoveManagers.sol"; import "./IBoldToken.sol"; import "./IPriceFeed.sol"; import "./ISortedTroves.sol"; import "./ITroveManager.sol"; import "./IWETH.sol"; // Common interface for the Borrower Operations. interface IBorrowerOperations is ILiquityBase, IAddRemoveManagers { function CCR() external view returns (uint256); function MCR() external view returns (uint256); function SCR() external view returns (uint256); function openTrove( address _owner, uint256 _ownerIndex, uint256 _ETHAmount, uint256 _boldAmount, uint256 _upperHint, uint256 _lowerHint, uint256 _annualInterestRate, uint256 _maxUpfrontFee, address _addManager, address _removeManager, address _receiver ) external returns (uint256); struct OpenTroveAndJoinInterestBatchManagerParams { address owner; uint256 ownerIndex; uint256 collAmount; uint256 boldAmount; uint256 upperHint; uint256 lowerHint; address interestBatchManager; uint256 maxUpfrontFee; address addManager; address removeManager; address receiver; } function openTroveAndJoinInterestBatchManager(OpenTroveAndJoinInterestBatchManagerParams calldata _params) external returns (uint256); function addColl(uint256 _troveId, uint256 _ETHAmount) external; function withdrawColl(uint256 _troveId, uint256 _amount) external; function withdrawBold(uint256 _troveId, uint256 _amount, uint256 _maxUpfrontFee) external; function repayBold(uint256 _troveId, uint256 _amount) external; function closeTrove(uint256 _troveId) external; function adjustTrove( uint256 _troveId, uint256 _collChange, bool _isCollIncrease, uint256 _debtChange, bool isDebtIncrease, uint256 _maxUpfrontFee ) external; function adjustZombieTrove( uint256 _troveId, uint256 _collChange, bool _isCollIncrease, uint256 _boldChange, bool _isDebtIncrease, uint256 _upperHint, uint256 _lowerHint, uint256 _maxUpfrontFee ) external; function adjustTroveInterestRate( uint256 _troveId, uint256 _newAnnualInterestRate, uint256 _upperHint, uint256 _lowerHint, uint256 _maxUpfrontFee ) external; function applyPendingDebt(uint256 _troveId, uint256 _lowerHint, uint256 _upperHint) external; function onLiquidateTrove(uint256 _troveId) external; function claimCollateral() external; function hasBeenShutDown() external view returns (bool); function shutdown() external; function shutdownFromOracleFailure() external; function checkBatchManagerExists(address _batchMananger) external view returns (bool); // -- individual delegation -- struct InterestIndividualDelegate { address account; uint128 minInterestRate; uint128 maxInterestRate; uint256 minInterestRateChangePeriod; } function getInterestIndividualDelegateOf(uint256 _troveId) external view returns (InterestIndividualDelegate memory); function setInterestIndividualDelegate( uint256 _troveId, address _delegate, uint128 _minInterestRate, uint128 _maxInterestRate, // only needed if trove was previously in a batch: uint256 _newAnnualInterestRate, uint256 _upperHint, uint256 _lowerHint, uint256 _maxUpfrontFee, uint256 _minInterestRateChangePeriod ) external; function removeInterestIndividualDelegate(uint256 _troveId) external; // -- batches -- struct InterestBatchManager { uint128 minInterestRate; uint128 maxInterestRate; uint256 minInterestRateChangePeriod; } function registerBatchManager( uint128 minInterestRate, uint128 maxInterestRate, uint128 currentInterestRate, uint128 fee, uint128 minInterestRateChangePeriod ) external; function lowerBatchManagementFee(uint256 _newAnnualFee) external; function setBatchManagerAnnualInterestRate( uint128 _newAnnualInterestRate, uint256 _upperHint, uint256 _lowerHint, uint256 _maxUpfrontFee ) external; function interestBatchManagerOf(uint256 _troveId) external view returns (address); function getInterestBatchManager(address _account) external view returns (InterestBatchManager memory); function setInterestBatchManager( uint256 _troveId, address _newBatchManager, uint256 _upperHint, uint256 _lowerHint, uint256 _maxUpfrontFee ) external; function removeFromBatch( uint256 _troveId, uint256 _newAnnualInterestRate, uint256 _upperHint, uint256 _lowerHint, uint256 _maxUpfrontFee ) external; function switchBatchManager( uint256 _troveId, uint256 _removeUpperHint, uint256 _removeLowerHint, address _newBatchManager, uint256 _addUpperHint, uint256 _addLowerHint, uint256 _maxUpfrontFee ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IActivePool.sol"; import "./ILiquityBase.sol"; import "./IBoldToken.sol"; import "./ITroveManager.sol"; import "./IBoldRewardsReceiver.sol"; /* * The Stability Pool holds Bold tokens deposited by Stability Pool depositors. * * When a trove is liquidated, then depending on system conditions, some of its Bold debt gets offset with * Bold in the Stability Pool: that is, the offset debt evaporates, and an equal amount of Bold tokens in the Stability Pool is burned. * * Thus, a liquidation causes each depositor to receive a Bold loss, in proportion to their deposit as a share of total deposits. * They also receive an Coll gain, as the collateral of the liquidated trove is distributed among Stability depositors, * in the same proportion. * * When a liquidation occurs, it depletes every deposit by the same fraction: for example, a liquidation that depletes 40% * of the total Bold in the Stability Pool, depletes 40% of each deposit. * * A deposit that has experienced a series of liquidations is termed a "compounded deposit": each liquidation depletes the deposit, * multiplying it by some factor in range ]0,1[ * * Please see the implementation spec in the proof document, which closely follows on from the compounded deposit / Coll gain derivations: * https://github.com/liquity/liquity/blob/master/papers/Scalable_Reward_Distribution_with_Compounding_Stakes.pdf * */ interface IStabilityPool is ILiquityBase, IBoldRewardsReceiver { function boldToken() external view returns (IBoldToken); function troveManager() external view returns (ITroveManager); /* provideToSP(): * - Calculates depositor's Coll gain * - Calculates the compounded deposit * - Increases deposit, and takes new snapshots of accumulators P and S * - Sends depositor's accumulated Coll gains to depositor */ function provideToSP(uint256 _amount, bool _doClaim) external; /* withdrawFromSP(): * - Calculates depositor's Coll gain * - Calculates the compounded deposit * - Sends the requested BOLD withdrawal to depositor * - (If _amount > userDeposit, the user withdraws all of their compounded deposit) * - Decreases deposit by withdrawn amount and takes new snapshots of accumulators P and S */ function withdrawFromSP(uint256 _amount, bool doClaim) external; function claimAllCollGains() external; /* * Initial checks: * - Caller is TroveManager * --- * Cancels out the specified debt against the Bold contained in the Stability Pool (as far as possible) * and transfers the Trove's collateral from ActivePool to StabilityPool. * Only called by liquidation functions in the TroveManager. */ function offset(uint256 _debt, uint256 _coll) external; function deposits(address _depositor) external view returns (uint256 initialValue); function stashedColl(address _depositor) external view returns (uint256); /* * Returns the total amount of Coll held by the pool, accounted in an internal variable instead of `balance`, * to exclude edge cases like Coll received from a self-destruct. */ function getCollBalance() external view returns (uint256); /* * Returns Bold held in the pool. Changes when users deposit/withdraw, and when Trove debt is offset. */ function getTotalBoldDeposits() external view returns (uint256); function getYieldGainsOwed() external view returns (uint256); function getYieldGainsPending() external view returns (uint256); /* * Calculates the Coll gain earned by the deposit since its last snapshots were taken. */ function getDepositorCollGain(address _depositor) external view returns (uint256); /* * Calculates the BOLD yield gain earned by the deposit since its last snapshots were taken. */ function getDepositorYieldGain(address _depositor) external view returns (uint256); /* * Calculates what `getDepositorYieldGain` will be if interest is minted now. */ function getDepositorYieldGainWithPending(address _depositor) external view returns (uint256); /* * Return the user's compounded deposit. */ function getCompoundedBoldDeposit(address _depositor) external view returns (uint256); function epochToScaleToS(uint128 _epoch, uint128 _scale) external view returns (uint256); function epochToScaleToB(uint128 _epoch, uint128 _scale) external view returns (uint256); function P() external view returns (uint256); function currentScale() external view returns (uint128); function currentEpoch() external view returns (uint128); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./ITroveManager.sol"; import {BatchId, BATCH_ID_ZERO} from "../Types/BatchId.sol"; interface ISortedTroves { // -- Mutating functions (permissioned) -- function insert(uint256 _id, uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) external; function insertIntoBatch( uint256 _troveId, BatchId _batchId, uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId ) external; function remove(uint256 _id) external; function removeFromBatch(uint256 _id) external; function reInsert(uint256 _id, uint256 _newAnnualInterestRate, uint256 _prevId, uint256 _nextId) external; function reInsertBatch(BatchId _id, uint256 _newAnnualInterestRate, uint256 _prevId, uint256 _nextId) external; // -- View functions -- function contains(uint256 _id) external view returns (bool); function isBatchedNode(uint256 _id) external view returns (bool); function isEmptyBatch(BatchId _id) external view returns (bool); function isEmpty() external view returns (bool); function getSize() external view returns (uint256); function getFirst() external view returns (uint256); function getLast() external view returns (uint256); function getNext(uint256 _id) external view returns (uint256); function getPrev(uint256 _id) external view returns (uint256); function validInsertPosition(uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) external view returns (bool); function findInsertPosition(uint256 _annualInterestRate, uint256 _prevId, uint256 _nextId) external view returns (uint256, uint256); // Public state variable getters function borrowerOperationsAddress() external view returns (address); function troveManager() external view returns (ITroveManager); function size() external view returns (uint256); function nodes(uint256 _id) external view returns (uint256 nextId, uint256 prevId, BatchId batchId, bool exists); function batches(BatchId _id) external view returns (uint256 head, uint256 tail); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; struct LatestTroveData { uint256 entireDebt; uint256 entireColl; uint256 redistBoldDebtGain; uint256 redistCollGain; uint256 accruedInterest; uint256 recordedDebt; uint256 annualInterestRate; uint256 weightedRecordedDebt; uint256 accruedBatchManagementFee; uint256 lastInterestRateAdjTime; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; struct LatestBatchData { uint256 entireDebtWithoutRedistribution; uint256 entireCollWithoutRedistribution; uint256 accruedInterest; uint256 recordedDebt; uint256 annualInterestRate; uint256 weightedRecordedDebt; uint256 annualManagementFee; uint256 accruedManagementFee; uint256 weightedRecordedBatchManagementFee; uint256 lastDebtUpdateTime; uint256 lastInterestRateAdjTime; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol) pragma solidity ^0.8.20; interface IERC5267 { /** * @dev MAY be emitted to signal that the domain could have changed. */ event EIP712DomainChanged(); /** * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712 * signature. */ function eip712Domain() external view returns ( bytes1 fields, string memory name, string memory version, uint256 chainId, address verifyingContract, bytes32 salt, uint256[] memory extensions ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IInterestRouter.sol"; import "./IBoldRewardsReceiver.sol"; import "../Types/TroveChange.sol"; interface IActivePool { function defaultPoolAddress() external view returns (address); function borrowerOperationsAddress() external view returns (address); function troveManagerAddress() external view returns (address); function interestRouter() external view returns (IInterestRouter); // We avoid IStabilityPool here in order to prevent creating a dependency cycle that would break flattening function stabilityPool() external view returns (IBoldRewardsReceiver); function getCollBalance() external view returns (uint256); function getBoldDebt() external view returns (uint256); function lastAggUpdateTime() external view returns (uint256); function aggRecordedDebt() external view returns (uint256); function aggWeightedDebtSum() external view returns (uint256); function aggBatchManagementFees() external view returns (uint256); function aggWeightedBatchManagementFeeSum() external view returns (uint256); function calcPendingAggInterest() external view returns (uint256); function calcPendingSPYield() external view returns (uint256); function calcPendingAggBatchManagementFee() external view returns (uint256); function getNewApproxAvgInterestRateFromTroveChange(TroveChange calldata _troveChange) external view returns (uint256); function mintAggInterest() external; function mintAggInterestAndAccountForTroveChange(TroveChange calldata _troveChange, address _batchManager) external; function mintBatchManagementFeeAndAccountForChange(TroveChange calldata _troveChange, address _batchAddress) external; function setShutdownFlag() external; function hasBeenShutDown() external view returns (bool); function shutdownTime() external view returns (uint256); function sendColl(address _account, uint256 _amount) external; function sendCollToDefaultPool(uint256 _amount) external; function receiveColl(uint256 _amount) external; function accountForReceivedColl(uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IDefaultPool { function troveManagerAddress() external view returns (address); function activePoolAddress() external view returns (address); // --- Functions --- function getCollBalance() external view returns (uint256); function getBoldDebt() external view returns (uint256); function sendCollToActivePool(uint256 _amount) external; function receiveColl(uint256 _amount) external; function increaseBoldDebt(uint256 _amount) external; function decreaseBoldDebt(uint256 _amount) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IPriceFeed { function fetchPrice() external returns (uint256, bool); function fetchRedemptionPrice() external returns (uint256, bool); function lastGoodPrice() external view returns (uint256); function setAddresses(address _borrowerOperationsAddress) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol) pragma solidity ^0.8.20; import {IERC721} from "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IAddRemoveManagers { function setAddManager(uint256 _troveId, address _manager) external; function setRemoveManager(uint256 _troveId, address _manager) external; function setRemoveManagerWithReceiver(uint256 _troveId, address _manager, address _receiver) external; function addManagerOf(uint256 _troveId) external view returns (address); function removeManagerReceiverOf(uint256 _troveId) external view returns (address, address); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol"; interface IWETH is IERC20Metadata { function deposit() external payable; function withdraw(uint256 wad) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IBoldRewardsReceiver { function triggerBoldRewards(uint256 _boldYield) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; type BatchId is address; using {equals as ==, notEquals as !=, isZero, isNotZero} for BatchId global; function equals(BatchId a, BatchId b) pure returns (bool) { return BatchId.unwrap(a) == BatchId.unwrap(b); } function notEquals(BatchId a, BatchId b) pure returns (bool) { return !(a == b); } function isZero(BatchId x) pure returns (bool) { return x == BATCH_ID_ZERO; } function isNotZero(BatchId x) pure returns (bool) { return !x.isZero(); } BatchId constant BATCH_ID_ZERO = BatchId.wrap(address(0));
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IInterestRouter { // Currently the Interest Router doesn’t need any specific function }
// SPDX-License-Identifier: MIT pragma solidity 0.8.24; struct TroveChange { uint256 appliedRedistBoldDebtGain; uint256 appliedRedistCollGain; uint256 collIncrease; uint256 collDecrease; uint256 debtIncrease; uint256 debtDecrease; uint256 newWeightedRecordedDebt; uint256 oldWeightedRecordedDebt; uint256 upfrontFee; uint256 batchAccruedManagementFee; uint256 newWeightedRecordedBatchManagementFee; uint256 oldWeightedRecordedBatchManagementFee; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (token/ERC721/IERC721.sol) pragma solidity ^0.8.20; import {IERC165} from "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC-721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId, bytes calldata data) external; /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC-721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or * {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon * a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom(address from, address to, uint256 tokenId) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC-721 * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must * understand this adds an external call which potentially creates a reentrancy vulnerability. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 tokenId) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the address zero. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool approved) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/IERC165.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC-165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[ERC]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
{ "remappings": [ "@chimera/=lib/V2-gov/lib/chimera/src/", "@ensdomains/=lib/V2-gov/lib/v4-core/node_modules/@ensdomains/", "@openzeppelin/=lib/V2-gov/lib/v4-core/lib/openzeppelin-contracts/", "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "Solady/=lib/Solady/src/", "V2-gov/=lib/V2-gov/", "chimera/=lib/V2-gov/lib/chimera/src/", "ds-test/=lib/openzeppelin-contracts/lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-gas-snapshot/=lib/V2-gov/lib/v4-core/lib/forge-gas-snapshot/src/", "forge-std/=lib/forge-std/src/", "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/", "hardhat/=lib/V2-gov/lib/v4-core/node_modules/hardhat/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "openzeppelin/=lib/V2-gov/lib/openzeppelin-contracts/", "solmate/=lib/V2-gov/lib/v4-core/lib/solmate/src/", "v4-core/=lib/V2-gov/lib/v4-core/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "cancun", "viaIR": false, "libraries": {} }
[{"inputs":[{"internalType":"contract IBoldToken","name":"_boldToken","type":"address"},{"internalType":"contract IERC20Metadata[]","name":"_tokens","type":"address[]"},{"internalType":"contract ITroveManager[]","name":"_troveManagers","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_baseRate","type":"uint256"}],"name":"BaseRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_lastFeeOpTime","type":"uint256"}],"name":"LastFeeOpTimeUpdated","type":"event"},{"inputs":[],"name":"baseRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"boldToken","outputs":[{"internalType":"contract IBoldToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_redeemAmount","type":"uint256"}],"name":"getEffectiveRedemptionFeeInBold","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_ETHDrawn","type":"uint256"}],"name":"getRedemptionFeeWithDecay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRedemptionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_redeemAmount","type":"uint256"}],"name":"getRedemptionRateForRedeemedAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRedemptionRateWithDecay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getToken","outputs":[{"internalType":"contract IERC20Metadata","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_index","type":"uint256"}],"name":"getTroveManager","outputs":[{"internalType":"contract ITroveManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastFeeOperationTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_boldAmount","type":"uint256"},{"internalType":"uint256","name":"_maxIterationsPerCollateral","type":"uint256"},{"internalType":"uint256","name":"_maxFeePercentage","type":"uint256"}],"name":"redeemCollateral","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalCollaterals","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
6103406040524260015534801562000015575f80fd5b5060405162001c6638038062001c66833981016040819052620000389162000765565b8151806200008d5760405162461bcd60e51b815260206004820152601f60248201527f436f6c6c61746572616c206c6973742063616e6e6f7420626520656d7074790060448201526064015b60405180910390fd5b600a811115620000e05760405162461bcd60e51b815260206004820152601860248201527f436f6c6c61746572616c206c69737420746f6f206c6f6e670000000000000000604482015260640162000084565b60808190526001600160a01b03841661032052825183905f9062000108576200010862000846565b60209081029190910101516001600160a01b031660a052600181116200012f575f6200014e565b8260018151811062000145576200014562000846565b60200260200101515b6001600160a01b031660c052600281116200016a575f62000189565b8260028151811062000180576200018062000846565b60200260200101515b6001600160a01b031660e05260038111620001a5575f620001c4565b82600381518110620001bb57620001bb62000846565b60200260200101515b6001600160a01b03166101005260048111620001e1575f62000200565b82600481518110620001f757620001f762000846565b60200260200101515b6001600160a01b031661012052600581116200021d575f6200023c565b8260058151811062000233576200023362000846565b60200260200101515b6001600160a01b0316610140526006811162000259575f62000278565b826006815181106200026f576200026f62000846565b60200260200101515b6001600160a01b0316610160526007811162000295575f620002b4565b82600781518110620002ab57620002ab62000846565b60200260200101515b6001600160a01b03166101805260088111620002d1575f620002f0565b82600881518110620002e757620002e762000846565b60200260200101515b6001600160a01b03166101a052600981116200030d575f6200032c565b8260098151811062000323576200032362000846565b60200260200101515b6001600160a01b03166101c052815182905f906200034e576200034e62000846565b60209081029190910101516001600160a01b03166101e0526001811162000376575f62000395565b816001815181106200038c576200038c62000846565b60200260200101515b6001600160a01b03166102005260028111620003b2575f620003d1565b81600281518110620003c857620003c862000846565b60200260200101515b6001600160a01b03166102205260038111620003ee575f6200040d565b8160038151811062000404576200040462000846565b60200260200101515b6001600160a01b031661024052600481116200042a575f62000449565b8160048151811062000440576200044062000846565b60200260200101515b6001600160a01b0316610260526005811162000466575f62000485565b816005815181106200047c576200047c62000846565b60200260200101515b6001600160a01b03166102805260068111620004a2575f620004c1565b81600681518110620004b857620004b862000846565b60200260200101515b6001600160a01b03166102a05260078111620004de575f620004fd565b81600781518110620004f457620004f462000846565b60200260200101515b6001600160a01b03166102c052600881116200051a575f62000539565b8160088151811062000530576200053062000846565b60200260200101515b6001600160a01b03166102e0526009811162000556575f62000575565b816009815181106200056c576200056c62000846565b60200260200101515b6001600160a01b0316610300526002620005996064670de0b6b3a76400006200086e565b620005a591906200086e565b620005ba6064670de0b6b3a76400006200086e565b620005c79060056200088e565b620005d39190620008ae565b5f557fc454ee9b76c52f782a256af821b857ca6e125d1e3333bcede402fec2bed9600c60026200060d6064670de0b6b3a76400006200086e565b6200061991906200086e565b6200062e6064670de0b6b3a76400006200086e565b6200063b9060056200088e565b620006479190620008ae565b60405190815260200160405180910390a150505050620008c4565b6001600160a01b038116811462000677575f80fd5b50565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b0381118282101715620006b957620006b96200067a565b604052919050565b5f6001600160401b03821115620006dc57620006dc6200067a565b5060051b60200190565b5f82601f830112620006f6575f80fd5b815160206200070f6200070983620006c1565b6200068e565b8083825260208201915060208460051b87010193508684111562000731575f80fd5b602086015b848110156200075a5780516200074c8162000662565b835291830191830162000736565b509695505050505050565b5f805f6060848603121562000778575f80fd5b8351620007858162000662565b602085810151919450906001600160401b0380821115620007a4575f80fd5b818701915087601f830112620007b8575f80fd5b8151620007c96200070982620006c1565b81815260059190911b8301840190848101908a831115620007e8575f80fd5b938501935b8285101562000813578451620008038162000662565b82529385019390850190620007ed565b60408a015190975094505050808311156200082c575f80fd5b50506200083c86828701620006e6565b9150509250925092565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b5f826200088957634e487b7160e01b5f52601260045260245ffd5b500490565b8082028115828204841417620008a857620008a86200085a565b92915050565b81810381811115620008a857620008a86200085a565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161026051610280516102a0516102c0516102e0516103005161032051611297620009cf5f395f818161012f015281816103ea0152818161057601528181610a610152610ace01525f61037501525f61034601525f61031701525f6102e801525f6102b901525f61028a01525f61025b01525f61022c01525f6101fd01525f6101ce01525f610d4301525f610d1401525f610ce501525f610cb601525f610c8701525f610c5801525f610c2901525f610bfa01525f610bcb01525f610b9c01525f818161010801526104c301526112975ff3fe608060405234801561000f575f80fd5b50600436106100b1575f3560e01c8063ab6d53bd1161006e578063ab6d53bd14610164578063c3bfd84214610179578063c52861f21461018c578063d380a37c14610194578063d5b356351461019d578063e4b50cb8146101b0575f80fd5b80630bc17feb146100b55780631f68f20a146100e55780632b11551a146100fb57806330504b6f14610103578063630afce51461012a57806363f1134e14610151575b5f80fd5b6100c86100c336600461111d565b6101c3565b6040516001600160a01b0390911681526020015b60405180910390f35b6100ed5f5481565b6040519081526020016100dc565b6100ed6103d6565b6100ed7f000000000000000000000000000000000000000000000000000000000000000081565b6100c87f000000000000000000000000000000000000000000000000000000000000000081565b6100ed61015f36600461111d565b6103e6565b610177610172366004611134565b610488565b005b6100ed61018736600461111d565b610aca565b6100ed610b6d565b6100ed60015481565b6100ed6101ab36600461111d565b610b79565b6100c86101be36600461111d565b610b91565b5f815f036101f257507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160010361022157507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160020361025057507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160030361027f57507f0000000000000000000000000000000000000000000000000000000000000000919050565b816004036102ae57507f0000000000000000000000000000000000000000000000000000000000000000919050565b816005036102dd57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160060361030c57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160070361033b57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160080361036a57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160090361039957507f0000000000000000000000000000000000000000000000000000000000000000919050565b60405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b60448201526064015b60405180910390fd5b5f6103e15f54610d67565b905090565b5f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610444573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610468919061115d565b90505f6104758483610da3565b905061048081610d67565b949350505050565b61049181610e03565b61049a83610ea1565b6104c160405180608001604052805f81526020015f81526020015f81526020015f81525090565b7f00000000000000000000000000000000000000000000000000000000000000008082525f9067ffffffffffffffff8111156104ff576104ff611174565b604051908082528060200260200182016040528015610528578160200160208202803683370190505b5090505f825f015167ffffffffffffffff81111561054857610548611174565b604051908082528060200260200182016040528015610571578160200160208202803683370190505b5090507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105f4919061115d565b602084018190525f906106119061060c908990610da3565b610d67565b90508481111561066d5760405162461bcd60e51b815260206004820152602160248201527f43523a204665652065786365656465642070726f7669646564206d6178696d756044820152606d60f81b60648201526084016103cd565b5f5b845181101561075b575f610682826101c3565b90505f805f836001600160a01b0316634ea15f376040518163ffffffff1660e01b81526004016060604051808303815f875af11580156106c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106e89190611188565b92509250925081878681518110610701576107016111c2565b602002602001018181525050801561074b57828960400181815161072591906111ea565b9052508751839089908790811061073e5761073e6111c2565b6020026020010181815250505b50506001909201915061066f9050565b5083604001515f036108d857835167ffffffffffffffff81111561078157610781611174565b6040519080825280602002602001820160405280156107aa578160200160208202803683370190505b5092505f5b84518110156108d6575f6107c2826101c3565b90505f816001600160a01b0316634ea15f376040518163ffffffff1660e01b81526004016060604051808303815f875af1158015610802573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108269190611188565b9250505080156108cc575f826001600160a01b031663795d26c36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561086d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610891919061115d565b905080886040018181516108a591906111ea565b905250865181908890869081106108be576108be6111c2565b602002602001018181525050505b50506001016107af565b505b5f5b8451811015610a22575f8482815181106108f6576108f66111c2565b60200260200101511115610a1a575f856040015185838151811061091c5761091c6111c2565b60200260200101518a61092f91906111fd565b6109399190611228565b90508015610a18575f61094b836101c3565b90505f816001600160a01b031663f8a239e83385898881518110610971576109716111c2565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260648101889052608481018d905260a4016020604051808303815f875af11580156109da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109fe919061115d565b90508088606001818151610a1291906111ea565b90525050505b505b6001016108da565b50610a3584606001518560200151610f0d565b606084015115610ac1576060840151604051632770a7eb60e21b815233600482015260248101919091527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690639dc29fac906044015f604051808303815f87803b158015610aaa575f80fd5b505af1158015610abc573d5f803e3d5ffd5b505050505b50505050505050565b5f807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b28573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b4c919061115d565b90505f610b598483610da3565b9050610480610b6782610d67565b85610f5f565b5f6103e161060c610f7e565b5f610b8b610b85610b6d565b83610f5f565b92915050565b5f815f03610bc057507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600103610bef57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600203610c1e57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600303610c4d57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600403610c7c57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600503610cab57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600603610cda57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600703610d0957507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600803610d3857507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160090361039957507f0000000000000000000000000000000000000000000000000000000000000000919050565b5f610b8b826002610d816064670de0b6b3a7640000611228565b610d8b9190611228565b610d9591906111ea565b670de0b6b3a7640000610fc6565b5f80610dad610f7e565b90505f83610dc3670de0b6b3a7640000876111fd565b610dcd9190611228565b90505f610ddb600283611228565b610de590846111ea565b9050610df981670de0b6b3a7640000610fc6565b9695505050505050565b6002610e186064670de0b6b3a7640000611228565b610e229190611228565b8110158015610e395750670de0b6b3a76400008111155b610e9e5760405162461bcd60e51b815260206004820152603060248201527f4d6178206665652070657263656e74616765206d75737420626520626574776560448201526f656e20302e352520616e64203130302560801b60648201526084016103cd565b50565b5f8111610e9e5760405162461bcd60e51b815260206004820152603460248201527f436f6c6c61746572616c52656769737472793a20416d6f756e74206d7573742060448201527362652067726561746572207468616e207a65726f60601b60648201526084016103cd565b5f610f188383610da3565b5f8190556040518181529091507fc454ee9b76c52f782a256af821b857ca6e125d1e3333bcede402fec2bed9600c9060200160405180910390a1610f5a610fdd565b505050565b5f80670de0b6b3a7640000610f7484866111fd565b6104809190611228565b5f80610f88611032565b90505f610f9d670ddd4b8c6c7d70d88361104d565b9050670de0b6b3a7640000815f54610fb591906111fd565b610fbf9190611228565b9250505090565b5f818310610fd45781610fd6565b825b9392505050565b5f60015442610fec919061123b565b9050603c8110610e9e574260018190556040519081527f860f8d2f0c74dd487e89e2883e3b25b8159ce1e1b3433a291cba7b82c508f3bc9060200160405180910390a150565b5f603c60015442611043919061123b565b6103e19190611228565b5f631f54050082111561106257631f54050091505b815f036110785750670de0b6b3a7640000610b8b565b670de0b6b3a764000083835b60018111156110eb5761109860028261124e565b5f036110bc576110a882836110f1565b91506110b5600282611228565b9050611084565b6110c682846110f1565b92506110d282836110f1565b915060026110e160018361123b565b6110b59190611228565b610df982845b5f806110fd83856111fd565b9050670de0b6b3a7640000611113600282611228565b610f7490836111ea565b5f6020828403121561112d575f80fd5b5035919050565b5f805f60608486031215611146575f80fd5b505081359360208301359350604090920135919050565b5f6020828403121561116d575f80fd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b5f805f6060848603121561119a575f80fd5b8351925060208401519150604084015180151581146111b7575f80fd5b809150509250925092565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b80820180821115610b8b57610b8b6111d6565b8082028115828204841417610b8b57610b8b6111d6565b634e487b7160e01b5f52601260045260245ffd5b5f8261123657611236611214565b500490565b81810381811115610b8b57610b8b6111d6565b5f8261125c5761125c611214565b50069056fea2646970667358221220a0fab2dfc5e0e20b4d699db955021604c2f419b5e62caf2f3c656038a078412964736f6c63430008180033000000000000000000000000862e98428c173b11d730d65b896bafb08c702e95000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000004223f8af31e07815f1a7437336f093f37c065efe000000000000000000000000000000000000000000000000000000000000000100000000000000000000000076bd25aabf9f6ce46fe44b0140bced0bc831847b
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106100b1575f3560e01c8063ab6d53bd1161006e578063ab6d53bd14610164578063c3bfd84214610179578063c52861f21461018c578063d380a37c14610194578063d5b356351461019d578063e4b50cb8146101b0575f80fd5b80630bc17feb146100b55780631f68f20a146100e55780632b11551a146100fb57806330504b6f14610103578063630afce51461012a57806363f1134e14610151575b5f80fd5b6100c86100c336600461111d565b6101c3565b6040516001600160a01b0390911681526020015b60405180910390f35b6100ed5f5481565b6040519081526020016100dc565b6100ed6103d6565b6100ed7f000000000000000000000000000000000000000000000000000000000000000181565b6100c87f000000000000000000000000862e98428c173b11d730d65b896bafb08c702e9581565b6100ed61015f36600461111d565b6103e6565b610177610172366004611134565b610488565b005b6100ed61018736600461111d565b610aca565b6100ed610b6d565b6100ed60015481565b6100ed6101ab36600461111d565b610b79565b6100c86101be36600461111d565b610b91565b5f815f036101f257507f00000000000000000000000076bd25aabf9f6ce46fe44b0140bced0bc831847b919050565b8160010361022157507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160020361025057507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160030361027f57507f0000000000000000000000000000000000000000000000000000000000000000919050565b816004036102ae57507f0000000000000000000000000000000000000000000000000000000000000000919050565b816005036102dd57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160060361030c57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160070361033b57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160080361036a57507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160090361039957507f0000000000000000000000000000000000000000000000000000000000000000919050565b60405162461bcd60e51b815260206004820152600d60248201526c092dcecc2d8d2c840d2dcc8caf609b1b60448201526064015b60405180910390fd5b5f6103e15f54610d67565b905090565b5f807f000000000000000000000000862e98428c173b11d730d65b896bafb08c702e956001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610444573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610468919061115d565b90505f6104758483610da3565b905061048081610d67565b949350505050565b61049181610e03565b61049a83610ea1565b6104c160405180608001604052805f81526020015f81526020015f81526020015f81525090565b7f00000000000000000000000000000000000000000000000000000000000000018082525f9067ffffffffffffffff8111156104ff576104ff611174565b604051908082528060200260200182016040528015610528578160200160208202803683370190505b5090505f825f015167ffffffffffffffff81111561054857610548611174565b604051908082528060200260200182016040528015610571578160200160208202803683370190505b5090507f000000000000000000000000862e98428c173b11d730d65b896bafb08c702e956001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156105d0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906105f4919061115d565b602084018190525f906106119061060c908990610da3565b610d67565b90508481111561066d5760405162461bcd60e51b815260206004820152602160248201527f43523a204665652065786365656465642070726f7669646564206d6178696d756044820152606d60f81b60648201526084016103cd565b5f5b845181101561075b575f610682826101c3565b90505f805f836001600160a01b0316634ea15f376040518163ffffffff1660e01b81526004016060604051808303815f875af11580156106c4573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906106e89190611188565b92509250925081878681518110610701576107016111c2565b602002602001018181525050801561074b57828960400181815161072591906111ea565b9052508751839089908790811061073e5761073e6111c2565b6020026020010181815250505b50506001909201915061066f9050565b5083604001515f036108d857835167ffffffffffffffff81111561078157610781611174565b6040519080825280602002602001820160405280156107aa578160200160208202803683370190505b5092505f5b84518110156108d6575f6107c2826101c3565b90505f816001600160a01b0316634ea15f376040518163ffffffff1660e01b81526004016060604051808303815f875af1158015610802573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108269190611188565b9250505080156108cc575f826001600160a01b031663795d26c36040518163ffffffff1660e01b8152600401602060405180830381865afa15801561086d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610891919061115d565b905080886040018181516108a591906111ea565b905250865181908890869081106108be576108be6111c2565b602002602001018181525050505b50506001016107af565b505b5f5b8451811015610a22575f8482815181106108f6576108f66111c2565b60200260200101511115610a1a575f856040015185838151811061091c5761091c6111c2565b60200260200101518a61092f91906111fd565b6109399190611228565b90508015610a18575f61094b836101c3565b90505f816001600160a01b031663f8a239e83385898881518110610971576109716111c2565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0390931660048401526024830191909152604482015260648101889052608481018d905260a4016020604051808303815f875af11580156109da573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906109fe919061115d565b90508088606001818151610a1291906111ea565b90525050505b505b6001016108da565b50610a3584606001518560200151610f0d565b606084015115610ac1576060840151604051632770a7eb60e21b815233600482015260248101919091527f000000000000000000000000862e98428c173b11d730d65b896bafb08c702e956001600160a01b031690639dc29fac906044015f604051808303815f87803b158015610aaa575f80fd5b505af1158015610abc573d5f803e3d5ffd5b505050505b50505050505050565b5f807f000000000000000000000000862e98428c173b11d730d65b896bafb08c702e956001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b28573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b4c919061115d565b90505f610b598483610da3565b9050610480610b6782610d67565b85610f5f565b5f6103e161060c610f7e565b5f610b8b610b85610b6d565b83610f5f565b92915050565b5f815f03610bc057507f0000000000000000000000004223f8af31e07815f1a7437336f093f37c065efe919050565b81600103610bef57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600203610c1e57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600303610c4d57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600403610c7c57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600503610cab57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600603610cda57507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600703610d0957507f0000000000000000000000000000000000000000000000000000000000000000919050565b81600803610d3857507f0000000000000000000000000000000000000000000000000000000000000000919050565b8160090361039957507f0000000000000000000000000000000000000000000000000000000000000000919050565b5f610b8b826002610d816064670de0b6b3a7640000611228565b610d8b9190611228565b610d9591906111ea565b670de0b6b3a7640000610fc6565b5f80610dad610f7e565b90505f83610dc3670de0b6b3a7640000876111fd565b610dcd9190611228565b90505f610ddb600283611228565b610de590846111ea565b9050610df981670de0b6b3a7640000610fc6565b9695505050505050565b6002610e186064670de0b6b3a7640000611228565b610e229190611228565b8110158015610e395750670de0b6b3a76400008111155b610e9e5760405162461bcd60e51b815260206004820152603060248201527f4d6178206665652070657263656e74616765206d75737420626520626574776560448201526f656e20302e352520616e64203130302560801b60648201526084016103cd565b50565b5f8111610e9e5760405162461bcd60e51b815260206004820152603460248201527f436f6c6c61746572616c52656769737472793a20416d6f756e74206d7573742060448201527362652067726561746572207468616e207a65726f60601b60648201526084016103cd565b5f610f188383610da3565b5f8190556040518181529091507fc454ee9b76c52f782a256af821b857ca6e125d1e3333bcede402fec2bed9600c9060200160405180910390a1610f5a610fdd565b505050565b5f80670de0b6b3a7640000610f7484866111fd565b6104809190611228565b5f80610f88611032565b90505f610f9d670ddd4b8c6c7d70d88361104d565b9050670de0b6b3a7640000815f54610fb591906111fd565b610fbf9190611228565b9250505090565b5f818310610fd45781610fd6565b825b9392505050565b5f60015442610fec919061123b565b9050603c8110610e9e574260018190556040519081527f860f8d2f0c74dd487e89e2883e3b25b8159ce1e1b3433a291cba7b82c508f3bc9060200160405180910390a150565b5f603c60015442611043919061123b565b6103e19190611228565b5f631f54050082111561106257631f54050091505b815f036110785750670de0b6b3a7640000610b8b565b670de0b6b3a764000083835b60018111156110eb5761109860028261124e565b5f036110bc576110a882836110f1565b91506110b5600282611228565b9050611084565b6110c682846110f1565b92506110d282836110f1565b915060026110e160018361123b565b6110b59190611228565b610df982845b5f806110fd83856111fd565b9050670de0b6b3a7640000611113600282611228565b610f7490836111ea565b5f6020828403121561112d575f80fd5b5035919050565b5f805f60608486031215611146575f80fd5b505081359360208301359350604090920135919050565b5f6020828403121561116d575f80fd5b5051919050565b634e487b7160e01b5f52604160045260245ffd5b5f805f6060848603121561119a575f80fd5b8351925060208401519150604084015180151581146111b7575f80fd5b809150509250925092565b634e487b7160e01b5f52603260045260245ffd5b634e487b7160e01b5f52601160045260245ffd5b80820180821115610b8b57610b8b6111d6565b8082028115828204841417610b8b57610b8b6111d6565b634e487b7160e01b5f52601260045260245ffd5b5f8261123657611236611214565b500490565b81810381811115610b8b57610b8b6111d6565b5f8261125c5761125c611214565b50069056fea2646970667358221220a0fab2dfc5e0e20b4d699db955021604c2f419b5e62caf2f3c656038a078412964736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000862e98428c173b11d730d65b896bafb08c702e95000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a000000000000000000000000000000000000000000000000000000000000000010000000000000000000000004223f8af31e07815f1a7437336f093f37c065efe000000000000000000000000000000000000000000000000000000000000000100000000000000000000000076bd25aabf9f6ce46fe44b0140bced0bc831847b
-----Decoded View---------------
Arg [0] : _boldToken (address): 0x862E98428c173B11D730D65B896Bafb08c702E95
Arg [1] : _tokens (address[]): 0x4223F8aF31E07815f1A7437336f093F37C065EfE
Arg [2] : _troveManagers (address[]): 0x76bD25aABF9F6Ce46fE44B0140BcEd0bc831847B
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000862e98428c173b11d730d65b896bafb08c702e95
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [2] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [4] : 0000000000000000000000004223f8af31e07815f1a7437336f093f37c065efe
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [6] : 00000000000000000000000076bd25aabf9f6ce46fe44b0140bced0bc831847b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.