Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
NFTValueProvider
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 800 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.4; import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/security/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import "../interfaces/IAggregatorV3Interface.sol"; import "../interfaces/IUniswapV2Oracle.sol"; import "../interfaces/IJPEGOraclesAggregator.sol"; import "../interfaces/IJPEGCardsCigStaking.sol"; contract NFTValueProvider is ReentrancyGuardUpgradeable, OwnableUpgradeable { using SafeERC20Upgradeable for IERC20Upgradeable; error InvalidNFTType(bytes32 nftType); error InvalidRate(Rate rate); error InvalidUnlockTime(uint256 unlockTime); error ExistingLock(uint256 index); error InvalidAmount(uint256 amount); error InvalidOracleResults(); error Unauthorized(); error ZeroAddress(); error InvalidLength(); event DaoFloorChanged(uint256 newFloor); event JPEGLocked( address indexed owner, uint256 indexed index, uint256 amount, uint256 unlockTime, bool isTraitBoost ); event JPEGUnlocked( address indexed owner, uint256 indexed index, uint256 amount, bool isTraitBoost ); struct Rate { uint128 numerator; uint128 denominator; } struct JPEGLock { address owner; uint256 unlockAt; uint256 lockedValue; } /// @notice The JPEG floor oracles aggregator IJPEGOraclesAggregator public aggregator; /// @notice If true, the floor price won't be fetched using the Chainlink oracle but /// a value set by the DAO will be used instead bool public daoFloorOverride; /// @notice Value of floor set by the DAO. Only used if `daoFloorOverride` is true uint256 private overriddenFloorValueETH; /// @notice The JPEG token IERC20Upgradeable public jpeg; /// @notice Value of the JPEG to lock for trait boost based on the NFT value increase /// @custom:oz-renamed-from valueIncreaseLockRate Rate public traitBoostLockRate; /// @notice Minimum amount of JPEG to lock for trait boost uint256 public minJPEGToLock; mapping(uint256 => bytes32) public nftTypes; mapping(bytes32 => Rate) public nftTypeValueMultiplier; /// @custom:oz-renamed-from lockPositions mapping(uint256 => JPEGLock) public traitBoostPositions; mapping(uint256 => JPEGLock) public ltvBoostPositions; Rate public baseCreditLimitRate; Rate public baseLiquidationLimitRate; Rate public cigStakedRateIncrease; Rate public jpegLockedRateIncrease; /// @notice Value of the JPEG to lock for ltv boost based on the NFT ltv increase Rate public ltvBoostLockRate; /// @notice JPEGCardsCigStaking, cig stakers get an higher credit limit rate and liquidation limit rate. /// Immediately reverts to normal rates if the cig is unstaked. IJPEGCardsCigStaking public cigStaking; /// @notice This function is only called once during deployment of the proxy contract. It's not called after upgrades. /// @param _jpeg The JPEG token /// @param _aggregator The JPEG floor oracles aggregator /// @param _cigStaking The cig staking address /// @param _baseCreditLimitRate The base credit limit rate /// @param _baseLiquidationLimitRate The base liquidation limit rate /// @param _cigStakedRateIncrease The liquidation and credit limit rate increases for users staking a cig in the cigStaking contract /// @param _jpegLockedRateIncrease The liquidation and credit limit rate increases for users that locked JPEG for LTV boost /// @param _traitBoostLockRate The rate used to calculate the amount of JPEG to lock for trait boost based on the NFT's value increase /// @param _ltvBoostLockRate The rate used to calculate the amount of JPEG to lock for LTV boost based on the NFT's credit limit increase /// @param _minJPEGToLock Minimum amount of JPEG to lock to apply the trait boost function initialize( IERC20Upgradeable _jpeg, IJPEGOraclesAggregator _aggregator, IJPEGCardsCigStaking _cigStaking, Rate calldata _baseCreditLimitRate, Rate calldata _baseLiquidationLimitRate, Rate calldata _cigStakedRateIncrease, Rate calldata _jpegLockedRateIncrease, Rate calldata _traitBoostLockRate, Rate calldata _ltvBoostLockRate, uint256 _minJPEGToLock ) external initializer { __Ownable_init(); __ReentrancyGuard_init(); if (address(_jpeg) == address(0)) revert ZeroAddress(); if (address(_aggregator) == address(0)) revert ZeroAddress(); if (address(_cigStaking) == address(0)) revert ZeroAddress(); _validateRateBelowOne(_baseCreditLimitRate); _validateRateBelowOne(_baseLiquidationLimitRate); _validateRateBelowOne(_cigStakedRateIncrease); _validateRateBelowOne(_jpegLockedRateIncrease); _validateRateBelowOne(_traitBoostLockRate); _validateRateBelowOne(_ltvBoostLockRate); if (!_greaterThan(_baseLiquidationLimitRate, _baseCreditLimitRate)) revert InvalidRate(_baseLiquidationLimitRate); _validateRateBelowOne( _rateSum( _rateSum(_baseLiquidationLimitRate, _cigStakedRateIncrease), _jpegLockedRateIncrease ) ); jpeg = _jpeg; aggregator = _aggregator; cigStaking = _cigStaking; baseCreditLimitRate = _baseCreditLimitRate; baseLiquidationLimitRate = _baseLiquidationLimitRate; cigStakedRateIncrease = _cigStakedRateIncrease; jpegLockedRateIncrease = _jpegLockedRateIncrease; traitBoostLockRate = _traitBoostLockRate; ltvBoostLockRate = _ltvBoostLockRate; minJPEGToLock = _minJPEGToLock; } /// @notice This function is only called once during the upgrade process by the {ProxyAdmin} contract. function finalizeUpgrade( IJPEGCardsCigStaking _cigStaking, Rate calldata _baseCreditLimitRate, Rate calldata _baseLiquidationLimitRate, Rate calldata _cigStakedRateIncrease, Rate calldata _jpegLockedRateIncrease, Rate calldata _ltvBoostLockRate ) external { if (address(cigStaking) != address(0)) revert Unauthorized(); if (address(_cigStaking) == address(0)) revert ZeroAddress(); _validateRateBelowOne(_baseCreditLimitRate); _validateRateBelowOne(_baseLiquidationLimitRate); _validateRateBelowOne(_cigStakedRateIncrease); _validateRateBelowOne(_jpegLockedRateIncrease); _validateRateBelowOne(_ltvBoostLockRate); if (!_greaterThan(_baseLiquidationLimitRate, _baseCreditLimitRate)) revert InvalidRate(_baseLiquidationLimitRate); _validateRateBelowOne( _rateSum( _rateSum(_baseLiquidationLimitRate, _cigStakedRateIncrease), _jpegLockedRateIncrease ) ); cigStaking = _cigStaking; baseCreditLimitRate = _baseCreditLimitRate; baseLiquidationLimitRate = _baseLiquidationLimitRate; cigStakedRateIncrease = _cigStakedRateIncrease; jpegLockedRateIncrease = _jpegLockedRateIncrease; ltvBoostLockRate = _ltvBoostLockRate; } /// @param _owner The owner of the NFT at index `_nftIndex` (or the owner of the associated position in the vault) /// @param _nftIndex The index of the NFT to return the credit limit rate for /// @return The credit limit rate for the NFT with index `_nftIndex` function getCreditLimitRate(address _owner, uint256 _nftIndex) public view returns (Rate memory) { return _rateAfterBoosts(baseCreditLimitRate, _owner, _nftIndex); } /// @param _owner The owner of the NFT at index `_nftIndex` (or the owner of the associated position in the vault) /// @param _nftIndex The index of the NFT to return the liquidation limit rate for /// @return The liquidation limit rate for the NFT with index `_nftIndex` function getLiquidationLimitRate(address _owner, uint256 _nftIndex) public view returns (Rate memory) { return _rateAfterBoosts(baseLiquidationLimitRate, _owner, _nftIndex); } /// @param _owner The owner of the NFT at index `_nftIndex` (or the owner of the associated position in the vault) /// @param _nftIndex The index of the NFT to return the credit limit for /// @return The credit limit for the NFT with index `_nftIndex`, in ETH function getCreditLimitETH(address _owner, uint256 _nftIndex) external view returns (uint256) { Rate memory creditLimitRate = getCreditLimitRate(_owner, _nftIndex); return (getNFTValueETH(_nftIndex) * creditLimitRate.numerator) / creditLimitRate.denominator; } /// @param _owner The owner of the NFT at index `_nftIndex` (or the owner of the associated position in the vault) /// @param _nftIndex The index of the NFT to return the liquidation limit for /// @return The liquidation limit for the NFT with index `_nftIndex`, in ETH function getLiquidationLimitETH(address _owner, uint256 _nftIndex) external view returns (uint256) { Rate memory liquidationLimitRate = getLiquidationLimitRate( _owner, _nftIndex ); return (getNFTValueETH(_nftIndex) * liquidationLimitRate.numerator) / liquidationLimitRate.denominator; } /// @param _nftType The NFT type to calculate the JPEG lock amount for /// @param _jpegPrice The JPEG price in ETH (18 decimals) /// @return The JPEG to lock for the specified `_nftType` function calculateTraitBoostLock(bytes32 _nftType, uint256 _jpegPrice) public view returns (uint256) { return _calculateTraitBoostLock( traitBoostLockRate, _nftType, getFloorETH(), _jpegPrice ); } /// @param _nftIndex The index of the NFT to calculate the JPEG lock amount for /// @param _jpegPrice The JPEG price in ETH (18 decimals) /// @return The JPEG to lock for the specified `_nftIndex` function calculateLTVBoostLock(uint256 _nftIndex, uint256 _jpegPrice) external view returns (uint256) { uint256 nftValue = getNFTValueETH(_nftIndex); Rate memory creditLimitRate = baseCreditLimitRate; return _calculateLTVBoostLock( creditLimitRate, _rateSum(creditLimitRate, jpegLockedRateIncrease), ltvBoostLockRate, nftValue, _jpegPrice ); } /// @return The floor value for the collection, in ETH. function getFloorETH() public view returns (uint256) { if (daoFloorOverride) return overriddenFloorValueETH; else return aggregator.getFloorETH(); } /// @param _nftIndex The NFT to return the value of /// @return The value in ETH of the NFT at index `_nftIndex`, with 18 decimals. function getNFTValueETH(uint256 _nftIndex) public view returns (uint256) { uint256 floor = getFloorETH(); bytes32 nftType = nftTypes[_nftIndex]; if ( nftType != bytes32(0) && traitBoostPositions[_nftIndex].unlockAt > block.timestamp ) { Rate memory multiplier = nftTypeValueMultiplier[nftType]; return (floor * multiplier.numerator) / multiplier.denominator; } else return floor; } /// @notice Allows users to lock JPEG tokens to unlock the trait boost for a single non floor NFT. /// The trait boost is a multiplicative value increase relative to the collection's floor. /// The value increase depends on the NFT's traits and it's set by the DAO. /// The ETH value of the JPEG to lock is calculated by applying the `traitBoostLockRate` rate to the NFT's new credit limit. /// The unlock time is set by the user and has to be greater than `block.timestamp` and the previous unlock time. /// After the lock expires, the boost is revoked and the NFT's value goes back to floor. /// If a boosted position is closed or liquidated, the JPEG remains locked and the boost will still be applied in case the NFT /// is deposited again, even in case of a different owner. The locked JPEG will only be claimable by the original lock creator /// once the lock expires. If the lock is renewed by the new owner, the JPEG from the previous lock will be sent back to the original /// lock creator. /// @dev emits multiple {JPEGLocked} events /// @param _nftIndexes The indexes of the non floor NFTs to boost /// @param _unlocks The locks expiration times function applyTraitBoost( uint256[] calldata _nftIndexes, uint256[] calldata _unlocks ) external nonReentrant { _lockJPEG(_nftIndexes, _unlocks, true); } /// @notice Allows users to lock JPEG tokens to unlock the LTV boost for a single NFT. /// The LTV boost is an increase of an NFT's credit and liquidation limit rates. /// The ETH value of the JPEG to lock is calculated by applying the `ltvBoostLockRate` rate to the difference between the new and the old credit limits. /// See {applyTraitBoost} for details on the locking and unlocking mechanism. /// @dev emits multiple {JPEGLocked} events /// @param _nftIndexes The indexes of the NFTs to boost /// @param _unlocks The locks expiration times function applyLTVBoost( uint256[] calldata _nftIndexes, uint256[] calldata _unlocks ) external nonReentrant { _lockJPEG(_nftIndexes, _unlocks, false); } /// @notice Allows trait boost lock creators to unlock the JPEG associated to the NFT at index `_nftIndex`, provided the lock expired. /// @dev emits a {JPEGUnlocked} event /// @param _nftIndexes The indexes of the NFTs holding the locks. function withdrawTraitBoost(uint256[] calldata _nftIndexes) external nonReentrant { _unlockJPEG(traitBoostPositions, _nftIndexes, true); } /// @notice Allows ltv boost lock creators to unlock the JPEG associated to the NFT at index `_nftIndex`, provided the lock expired. /// @dev emits a {JPEGUnlocked} event /// @param _nftIndexes The indexes of the NFTs holding the locks. function withdrawLTVBoost(uint256[] calldata _nftIndexes) external nonReentrant { _unlockJPEG(ltvBoostPositions, _nftIndexes, false); } function addLocks( uint256[] calldata _nftIndexes, JPEGLock[] calldata _locks ) external onlyOwner { if (_nftIndexes.length != _locks.length || _nftIndexes.length == 0) revert InvalidLength(); for (uint256 i; i < _nftIndexes.length; ++i) { if (traitBoostPositions[_nftIndexes[i]].owner != address(0)) revert ExistingLock(_nftIndexes[i]); traitBoostPositions[_nftIndexes[i]] = _locks[i]; } } /// @notice Allows the DAO to bypass the floor oracle and override the NFT floor value /// @param _newFloor The new floor function overrideFloor(uint256 _newFloor) external onlyOwner { if (_newFloor == 0) revert InvalidAmount(_newFloor); overriddenFloorValueETH = _newFloor; daoFloorOverride = true; emit DaoFloorChanged(_newFloor); } /// @notice Allows the DAO to stop overriding floor function disableFloorOverride() external onlyOwner { daoFloorOverride = false; } /// @notice Allows the DAO to change the multiplier of an NFT category /// @param _type The category hash /// @param _multiplier The new multiplier function setNFTTypeMultiplier(bytes32 _type, Rate calldata _multiplier) external onlyOwner { if (_type == bytes32(0)) revert InvalidNFTType(_type); _validateRateAboveOne(_multiplier); nftTypeValueMultiplier[_type] = _multiplier; } /// @notice Allows the DAO to add an NFT to a specific price category /// @param _nftIndexes The indexes to add to the category /// @param _type The category hash function setNFTType(uint256[] calldata _nftIndexes, bytes32 _type) external onlyOwner { if (_type != bytes32(0) && nftTypeValueMultiplier[_type].numerator == 0) revert InvalidNFTType(_type); for (uint256 i; i < _nftIndexes.length; ++i) { nftTypes[_nftIndexes[i]] = _type; } } function setBaseCreditLimitRate(Rate memory _baseCreditLimitRate) external onlyOwner { _validateRateBelowOne(_baseCreditLimitRate); if (!_greaterThan(baseLiquidationLimitRate, _baseCreditLimitRate)) revert InvalidRate(_baseCreditLimitRate); baseCreditLimitRate = _baseCreditLimitRate; } function setBaseLiquidationLimitRate(Rate memory _liquidationLimitRate) external onlyOwner { _validateRateBelowOne(_liquidationLimitRate); if (!_greaterThan(_liquidationLimitRate, baseCreditLimitRate)) revert InvalidRate(_liquidationLimitRate); _validateRateBelowOne( _rateSum( _rateSum(_liquidationLimitRate, cigStakedRateIncrease), jpegLockedRateIncrease ) ); baseLiquidationLimitRate = _liquidationLimitRate; } function setCigStakedRateIncrease(Rate memory _cigStakedRateIncrease) external onlyOwner { _validateRateBelowOne(_cigStakedRateIncrease); _validateRateBelowOne( _rateSum( _rateSum(baseLiquidationLimitRate, _cigStakedRateIncrease), jpegLockedRateIncrease ) ); cigStakedRateIncrease = _cigStakedRateIncrease; } function setJPEGLockedRateIncrease(Rate memory _jpegLockedRateIncrease) external onlyOwner { _validateRateBelowOne(_jpegLockedRateIncrease); _validateRateBelowOne( _rateSum( _rateSum(baseLiquidationLimitRate, cigStakedRateIncrease), _jpegLockedRateIncrease ) ); jpegLockedRateIncrease = _jpegLockedRateIncrease; } function setTraitBoostLockRate(Rate memory _traitBoostLockRate) external onlyOwner { _validateRateBelowOne(_traitBoostLockRate); traitBoostLockRate = _traitBoostLockRate; } function setLTVBoostLockRate(Rate memory _ltvBoostLockRate) external onlyOwner { _validateRateBelowOne(_ltvBoostLockRate); ltvBoostLockRate = _ltvBoostLockRate; } /// @dev see {applyTraitBoost} and {applyLTVBoost} function _lockJPEG( uint256[] memory _nftIndexes, uint256[] memory _unlocks, bool _isTraitBoost ) internal { if (_nftIndexes.length != _unlocks.length) revert InvalidLength(); Rate memory creditLimitRate; Rate memory boostedCreditLimitRate; Rate memory lockRate; if (_isTraitBoost) { lockRate = traitBoostLockRate; } else { creditLimitRate = baseCreditLimitRate; boostedCreditLimitRate = _rateSum( creditLimitRate, jpegLockedRateIncrease ); lockRate = ltvBoostLockRate; } IERC20Upgradeable _jpeg = jpeg; uint256 floor = getFloorETH(); uint256 minJPEG = minJPEGToLock; uint256 jpegPrice = _jpegPriceETH(); uint256 requiredJpeg; uint256 jpegToRefund; for (uint256 i; i < _nftIndexes.length; ++i) { uint256 index = _nftIndexes[i]; uint256 unlockAt = _unlocks[i]; uint256 jpegToLock; JPEGLock storage jpegLock; if (_isTraitBoost) { jpegLock = traitBoostPositions[index]; bytes32 nftType = nftTypes[index]; if (nftType == bytes32(0)) revert InvalidNFTType(nftType); jpegToLock = _calculateTraitBoostLock( lockRate, nftType, floor, jpegPrice ); if (minJPEG > jpegToLock) revert InvalidNFTType(nftType); //dirty workaround to prevent stack too deep errors _emitJPEGLockedTraitBoost(index, jpegToLock, unlockAt); } else { jpegLock = ltvBoostPositions[index]; jpegToLock = _calculateLTVBoostLock( creditLimitRate, boostedCreditLimitRate, lockRate, floor, jpegPrice ); if (minJPEG > jpegToLock) jpegToLock = minJPEG; //dirty workaround to prevent stack too deep errors _emitJPEGLockedLTVBoost(index, jpegToLock, unlockAt); } if (block.timestamp >= unlockAt || jpegLock.unlockAt >= unlockAt) revert InvalidUnlockTime(unlockAt); uint256 previousLockValue = jpegLock.lockedValue; address previousOwner = jpegLock.owner; jpegLock.lockedValue = jpegToLock; jpegLock.unlockAt = unlockAt; jpegLock.owner = msg.sender; requiredJpeg += jpegToLock; if (previousOwner == msg.sender) jpegToRefund += previousLockValue; else if (previousLockValue > 0) _jpeg.safeTransfer(previousOwner, previousLockValue); } if (requiredJpeg > jpegToRefund) _jpeg.safeTransferFrom( msg.sender, address(this), requiredJpeg - jpegToRefund ); else if (requiredJpeg < jpegToRefund) _jpeg.safeTransfer(msg.sender, jpegToRefund - requiredJpeg); } /// @dev This function is used in {_lockJPEG} to prevent stack too deep errors function _emitJPEGLockedTraitBoost( uint256 _nftIndex, uint256 _jpegToLock, uint256 _unlockAt ) internal { emit JPEGLocked(msg.sender, _nftIndex, _jpegToLock, _unlockAt, true); } /// @dev This function is used in {_lockJPEG} to prevent stack too deep errors function _emitJPEGLockedLTVBoost( uint256 _nftIndex, uint256 _jpegToLock, uint256 _unlockAt ) internal { emit JPEGLocked(msg.sender, _nftIndex, _jpegToLock, _unlockAt, false); } /// @dev See {withdrawTraitBoost} and {withdrawLTVBoost} function _unlockJPEG( mapping(uint256 => JPEGLock) storage _locks, uint256[] calldata _nftIndexes, bool _isTraitBoost ) internal { uint256 length = _nftIndexes.length; if (length == 0) revert InvalidLength(); uint256 jpegToSend; for (uint256 i; i < length; ++i) { uint256 index = _nftIndexes[i]; JPEGLock memory jpegLock = _locks[index]; if (jpegLock.owner != msg.sender) revert Unauthorized(); if (block.timestamp < jpegLock.unlockAt) revert Unauthorized(); jpegToSend += jpegLock.lockedValue; delete _locks[index]; emit JPEGUnlocked( msg.sender, index, jpegLock.lockedValue, _isTraitBoost ); } jpeg.safeTransfer(msg.sender, jpegToSend); } function _calculateTraitBoostLock( Rate memory _lockRate, bytes32 _nftType, uint256 _floor, uint256 _jpegPrice ) internal view returns (uint256) { Rate memory multiplier = nftTypeValueMultiplier[_nftType]; if (multiplier.numerator == 0 || multiplier.denominator == 0) return 0; return (((_floor * multiplier.numerator) / multiplier.denominator - _floor) * 1 ether * _lockRate.numerator) / _lockRate.denominator / _jpegPrice; } function _calculateLTVBoostLock( Rate memory _creditLimitRate, Rate memory _boostedCreditLimitRate, Rate memory _lockRate, uint256 _floor, uint256 _jpegPrice ) internal pure returns (uint256) { uint256 baseCreditLimit = (_floor * _creditLimitRate.numerator) / _creditLimitRate.denominator; uint256 boostedCreditLimit = (_floor * _boostedCreditLimitRate.numerator) / _boostedCreditLimitRate.denominator; return ((((boostedCreditLimit - baseCreditLimit) * _lockRate.numerator) / _lockRate.denominator) * 1 ether) / _jpegPrice; } function _rateAfterBoosts( Rate memory _baseRate, address _owner, uint256 _nftIndex ) internal view returns (Rate memory) { if (cigStaking.isUserStaking(_owner)) { _baseRate = _rateSum(_baseRate, cigStakedRateIncrease); } if (ltvBoostPositions[_nftIndex].unlockAt > block.timestamp) { _baseRate = _rateSum(_baseRate, jpegLockedRateIncrease); } return _baseRate; } /// @dev Returns the current JPEG price in ETH /// @return result The current JPEG price, 18 decimals function _jpegPriceETH() internal returns (uint256) { return aggregator.consultJPEGPriceETH(address(jpeg)); } /// @dev Validates a rate. The denominator must be greater than zero and less than or equal to the numerator. /// @param _rate The rate to validate function _validateRateAboveOne(Rate memory _rate) internal pure { if (_rate.denominator == 0 || _rate.numerator < _rate.denominator) revert InvalidRate(_rate); } /// @dev Validates a rate. The denominator must be greater than zero and greater than or equal to the numerator. /// @param _rate The rate to validate function _validateRateBelowOne(Rate memory _rate) internal pure { if (_rate.denominator == 0 || _rate.denominator < _rate.numerator) revert InvalidRate(_rate); } /// @dev Checks if `r1` is greater than `r2`. function _greaterThan(Rate memory _r1, Rate memory _r2) internal pure returns (bool) { return _r1.numerator * _r2.denominator > _r2.numerator * _r1.denominator; } function _rateSum(Rate memory _r1, Rate memory _r2) internal pure returns (Rate memory) { return Rate({ numerator: _r1.numerator * _r2.denominator + _r1.denominator * _r2.numerator, denominator: _r1.denominator * _r2.denominator }); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/ContextUpgradeable.sol"; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ function __Ownable_init() internal onlyInitializing { __Ownable_init_unchained(); } function __Ownable_init_unchained() internal onlyInitializing { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuardUpgradeable is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal onlyInitializing { __ReentrancyGuard_init_unchained(); } function __ReentrancyGuard_init_unchained() internal onlyInitializing { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[49] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; import "../../../utils/AddressUpgradeable.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 SafeERC20Upgradeable { using AddressUpgradeable for address; function safeTransfer( IERC20Upgradeable token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20Upgradeable 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( IERC20Upgradeable 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)); } function safeIncreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20Upgradeable token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @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(IERC20Upgradeable 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"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.4; interface IAggregatorV3Interface { function decimals() external view returns (uint8); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.4; interface IUniswapV2Oracle { function consultAndUpdateIfNecessary(address token, uint256 amountIn) external returns (uint256); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.4; interface IJPEGOraclesAggregator { function getFloorETH() external view returns (uint256); function consultJPEGPriceETH(address _token) external returns (uint256 result); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.4; interface IJPEGCardsCigStaking { function isUserStaking(address _user) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal onlyInitializing { } function __Context_init_unchained() internal onlyInitializing { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } /** * @dev This empty reserved space is put in place to allow future versions to add new * variables without shifting down storage in the inheritance chain. * See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps */ uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [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://diligence.consensys.net/posts/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.5.11/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 functionCall(target, data, "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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(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) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason 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 { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20Upgradeable { /** * @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); /** * @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); }
{ "optimizer": { "enabled": true, "runs": 800 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"ExistingLock","type":"error"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"InvalidAmount","type":"error"},{"inputs":[],"name":"InvalidLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"nftType","type":"bytes32"}],"name":"InvalidNFTType","type":"error"},{"inputs":[],"name":"InvalidOracleResults","type":"error"},{"inputs":[{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"rate","type":"tuple"}],"name":"InvalidRate","type":"error"},{"inputs":[{"internalType":"uint256","name":"unlockTime","type":"uint256"}],"name":"InvalidUnlockTime","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newFloor","type":"uint256"}],"name":"DaoFloorChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"unlockTime","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isTraitBoost","type":"bool"}],"name":"JPEGLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"index","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isTraitBoost","type":"bool"}],"name":"JPEGUnlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"inputs":[{"internalType":"uint256[]","name":"_nftIndexes","type":"uint256[]"},{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"unlockAt","type":"uint256"},{"internalType":"uint256","name":"lockedValue","type":"uint256"}],"internalType":"struct NFTValueProvider.JPEGLock[]","name":"_locks","type":"tuple[]"}],"name":"addLocks","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"aggregator","outputs":[{"internalType":"contract IJPEGOraclesAggregator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_nftIndexes","type":"uint256[]"},{"internalType":"uint256[]","name":"_unlocks","type":"uint256[]"}],"name":"applyLTVBoost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_nftIndexes","type":"uint256[]"},{"internalType":"uint256[]","name":"_unlocks","type":"uint256[]"}],"name":"applyTraitBoost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"baseCreditLimitRate","outputs":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseLiquidationLimitRate","outputs":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftIndex","type":"uint256"},{"internalType":"uint256","name":"_jpegPrice","type":"uint256"}],"name":"calculateLTVBoostLock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_nftType","type":"bytes32"},{"internalType":"uint256","name":"_jpegPrice","type":"uint256"}],"name":"calculateTraitBoostLock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cigStakedRateIncrease","outputs":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cigStaking","outputs":[{"internalType":"contract IJPEGCardsCigStaking","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"daoFloorOverride","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"disableFloorOverride","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IJPEGCardsCigStaking","name":"_cigStaking","type":"address"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_baseCreditLimitRate","type":"tuple"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_baseLiquidationLimitRate","type":"tuple"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_cigStakedRateIncrease","type":"tuple"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_jpegLockedRateIncrease","type":"tuple"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_ltvBoostLockRate","type":"tuple"}],"name":"finalizeUpgrade","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_nftIndex","type":"uint256"}],"name":"getCreditLimitETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_nftIndex","type":"uint256"}],"name":"getCreditLimitRate","outputs":[{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFloorETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_nftIndex","type":"uint256"}],"name":"getLiquidationLimitETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"uint256","name":"_nftIndex","type":"uint256"}],"name":"getLiquidationLimitRate","outputs":[{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_nftIndex","type":"uint256"}],"name":"getNFTValueETH","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"_jpeg","type":"address"},{"internalType":"contract IJPEGOraclesAggregator","name":"_aggregator","type":"address"},{"internalType":"contract IJPEGCardsCigStaking","name":"_cigStaking","type":"address"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_baseCreditLimitRate","type":"tuple"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_baseLiquidationLimitRate","type":"tuple"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_cigStakedRateIncrease","type":"tuple"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_jpegLockedRateIncrease","type":"tuple"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_traitBoostLockRate","type":"tuple"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_ltvBoostLockRate","type":"tuple"},{"internalType":"uint256","name":"_minJPEGToLock","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"jpeg","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"jpegLockedRateIncrease","outputs":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ltvBoostLockRate","outputs":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"ltvBoostPositions","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"unlockAt","type":"uint256"},{"internalType":"uint256","name":"lockedValue","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minJPEGToLock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"nftTypeValueMultiplier","outputs":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nftTypes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newFloor","type":"uint256"}],"name":"overrideFloor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_baseCreditLimitRate","type":"tuple"}],"name":"setBaseCreditLimitRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_liquidationLimitRate","type":"tuple"}],"name":"setBaseLiquidationLimitRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_cigStakedRateIncrease","type":"tuple"}],"name":"setCigStakedRateIncrease","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_jpegLockedRateIncrease","type":"tuple"}],"name":"setJPEGLockedRateIncrease","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_ltvBoostLockRate","type":"tuple"}],"name":"setLTVBoostLockRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_nftIndexes","type":"uint256[]"},{"internalType":"bytes32","name":"_type","type":"bytes32"}],"name":"setNFTType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_type","type":"bytes32"},{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_multiplier","type":"tuple"}],"name":"setNFTTypeMultiplier","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"internalType":"struct NFTValueProvider.Rate","name":"_traitBoostLockRate","type":"tuple"}],"name":"setTraitBoostLockRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"traitBoostLockRate","outputs":[{"internalType":"uint128","name":"numerator","type":"uint128"},{"internalType":"uint128","name":"denominator","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"traitBoostPositions","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"unlockAt","type":"uint256"},{"internalType":"uint256","name":"lockedValue","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_nftIndexes","type":"uint256[]"}],"name":"withdrawLTVBoost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_nftIndexes","type":"uint256[]"}],"name":"withdrawTraitBoost","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b50613197806100206000396000f3fe608060405234801561001057600080fd5b50600436106102e95760003560e01c8063822be78711610191578063df7412c0116100e3578063ee42a12611610097578063f960254d11610071578063f960254d146106ee578063fdb0480d14610701578063ffd833411461073a57600080fd5b8063ee42a126146106b5578063f2fde38b146106c8578063f6ea706f146106db57600080fd5b8063e9bdd3ef116100c8578063e9bdd3ef1461067c578063e9e3f36e1461068f578063eb88d91a146106a257600080fd5b8063df7412c014610661578063e38e56101461066957600080fd5b8063a222f99311610145578063b8ad10751161011f578063b8ad10751461061d578063c87ef91b14610630578063cd3149211461064e57600080fd5b8063a222f993146105ef578063a82f44cf14610602578063b82b11cf1461061557600080fd5b806389a0b6a01161017657806389a0b6a01461056d5780638da5cb5b146105cb5780639e00d0da146105dc57600080fd5b8063822be7871461053c57806384bc5ff51461055a57600080fd5b8063576be9731161024a5780636f47438c116101fe578063761d0ea1116101d8578063761d0ea1146104d557806379b2ab23146104e85780637dde5d8d1461050857600080fd5b80636f47438c14610480578063715018a61461049357806372208c4c1461049b57600080fd5b8063650d17931161022f578063650d17931461042b578063668362dd1461044f57806368f4630c1461046d57600080fd5b8063576be973146104055780635d7d551e1461041857600080fd5b80632be6d51b116102a15780634d1869be116102865780634d1869be146103d65780634dbaa038146103e95780634e1fd47d146103f257600080fd5b80632be6d51b1461037a578063454d4776146103b857600080fd5b80631ceaac72116102d25780631ceaac7214610316578063245a7bfc1461032957806329e463c91461035957600080fd5b806302a05e05146102ee5780630303dd9f14610303575b600080fd5b6103016102fc366004612e69565b610758565b005b610301610311366004612e69565b610831565b610301610324366004612e69565b6108a3565b60975461033c906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61036c610367366004612af6565b610915565b604051908152602001610350565b60a254610398906001600160801b0380821691600160801b90041682565b604080516001600160801b03938416815292909116602083015201610350565b60a354610398906001600160801b0380821691600160801b90041682565b6103016103e4366004612d2d565b610965565b61036c609b5481565b610301610400366004612b61565b610c49565b610301610413366004612b21565b610ddc565b61036c610426366004612af6565b610e4a565b60975461043f90600160a01b900460ff1681565b6040519015158152602001610350565b60a454610398906001600160801b0380821691600160801b90041682565b61030161047b366004612ded565b610e57565b61036c61048e366004612cc8565b610fe9565b610301611086565b6104ae6104a9366004612af6565b6110da565b6040805182516001600160801b039081168252602093840151169281019290925201610350565b6103016104e3366004612ce0565b611128565b61036c6104f6366004612cc8565b609c6020526000908152604090205481565b610398610516366004612cc8565b609d602052600090815260409020546001600160801b0380821691600160801b90041682565b609a54610398906001600160801b0380821691600160801b90041682565b61036c610568366004612d0c565b6111c8565b6105a661057b366004612cc8565b609e602052600090815260409020805460018201546002909201546001600160a01b03909116919083565b604080516001600160a01b039094168452602084019290925290820152606001610350565b6065546001600160a01b031661033c565b6103016105ea366004612c5e565b61125d565b6103016105fd366004612e69565b611344565b610301610610366004612bf5565b611487565b61036c611556565b61030161062b366004612e69565b6115fd565b60a154610398906001600160801b0380821691600160801b90041682565b61030161065c366004612bf5565b6116a9565b61030161176b565b60a55461033c906001600160a01b031681565b61030161068a366004612cc8565b6117c2565b61030161069d366004612e69565b611880565b60995461033c906001600160a01b031681565b61036c6106c3366004612d0c565b61195a565b6103016106d6366004612ada565b611998565b6104ae6106e9366004612af6565b611a68565b6103016106fc366004612b21565b611aaf565b6105a661070f366004612cc8565b609f602052600090815260409020805460018201546002909201546001600160a01b03909116919083565b60a054610398906001600160801b0380821691600160801b90041682565b6065546001600160a01b031633146107a55760405162461bcd60e51b8152602060048201819052602482015260008051602061314283398151915260448201526064015b60405180910390fd5b6107ae81611b18565b60408051808201825260a1546001600160801b038082168352600160801b918290048116602080850191909152845180860190955260a25480831686529290920416908301526108109161080b9161080591611b82565b83611b82565b611b18565b80516020909101516001600160801b03908116600160801b0291161760a355565b6065546001600160a01b031633146108795760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b61088281611b18565b80516020909101516001600160801b03908116600160801b0291161760a455565b6065546001600160a01b031633146108eb5760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b6108f481611b18565b80516020909101516001600160801b03908116600160801b02911617609a55565b60008061092284846110da565b905080602001516001600160801b031681600001516001600160801b031661094985610fe9565b6109539190613007565b61095d9190612fb8565b949350505050565b600054610100900460ff166109805760005460ff1615610984565b303b155b6109f65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161079c565b600054610100900460ff16158015610a18576000805461ffff19166101011790555b610a20611c04565b610a28611c77565b6001600160a01b038b16610a4f5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038a16610a765760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038916610a9d5760405163d92e233d60e01b815260040160405180910390fd5b610aaf61080b368a90038a018a612e69565b610ac161080b36899003890189612e69565b610ad361080b36889003880188612e69565b610ae561080b36879003870187612e69565b610af761080b36869003860186612e69565b610b0961080b36859003850185612e69565b610b2f610b1b36899003890189612e69565b610b2a368b90038b018b612e69565b611cea565b610b4e5786604051639259c66b60e01b815260040161079c9190612f3a565b610b8961080b610b7a610b66368b90038b018b612e69565b610b75368b90038b018b612e69565b611b82565b610b7536899003890189612e69565b609980546001600160a01b03808e166001600160a01b031992831617909255609780548d841690831617905560a58054928c16929091169190911790558760a0610bd382826130d7565b5087905060a1610be382826130d7565b5086905060a2610bf382826130d7565b5085905060a3610c0382826130d7565b50849050609a610c1382826130d7565b5083905060a4610c2382826130d7565b5050609b8290558015610c3c576000805461ff00191690555b5050505050505050505050565b6065546001600160a01b03163314610c915760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b8281141580610c9e575082155b15610cbc5760405163251f56a160e21b815260040160405180910390fd5b60005b83811015610dd5576000609e81878785818110610cec57634e487b7160e01b600052603260045260246000fd5b60209081029290920135835250810191909152604001600020546001600160a01b031614610d5757848482818110610d3457634e487b7160e01b600052603260045260246000fd5b90506020020135604051633920d20d60e11b815260040161079c91815260200190565b828282818110610d7757634e487b7160e01b600052603260045260246000fd5b905060600201609e6000878785818110610da157634e487b7160e01b600052603260045260246000fd5b9050602002013581526020019081526020016000208181610dc2919061309a565b50610dce905081613069565b9050610cbf565b5050505050565b60026001541415610e2f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161079c565b6002600155610e42609f83836000611d2b565b505060018055565b6000806109228484611a68565b60a5546001600160a01b031615610e80576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038616610ea75760405163d92e233d60e01b815260040160405180910390fd5b610eb961080b36879003870187612e69565b610ecb61080b36869003860186612e69565b610edd61080b36859003850185612e69565b610eef61080b36849003840184612e69565b610f0161080b36839003830183612e69565b610f22610f1336869003860186612e69565b610b2a36889003880188612e69565b610f415783604051639259c66b60e01b815260040161079c9190612f3a565b610f7761080b610f68610f5936889003880188612e69565b610b7536889003880188612e69565b610b7536869003860186612e69565b60a580546001600160a01b0319166001600160a01b0388161790558460a0610f9f82826130d7565b5084905060a1610faf82826130d7565b5083905060a2610fbf82826130d7565b5082905060a3610fcf82826130d7565b5081905060a4610fdf82826130d7565b5050505050505050565b600080610ff4611556565b6000848152609c6020526040902054909150801580159061102557506000848152609e602052604090206001015442105b1561107f576000818152609d60209081526040918290208251808401909352546001600160801b03808216808552600160801b9092041691830182905261106c9085613007565b6110769190612fb8565b95945050505050565b5092915050565b6065546001600160a01b031633146110ce5760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b6110d86000611eb9565b565b60408051808201909152600080825260208201526040805180820190915260a0546001600160801b038082168352600160801b909104166020820152611121908484611f0b565b9392505050565b6065546001600160a01b031633146111705760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b8161119157604051632d3c1ad360e01b81526004810183905260240161079c565b6111a86111a336839003830183612e69565b61202c565b6000828152609d6020526040902081906111c282826130d7565b50505050565b6000806111d484610fe9565b60408051808201825260a0546001600160801b038082168352600160801b918290048116602080850191909152845180860190955260a354808316865292909204169083015291925061107690829061122e908290611b82565b6040805180820190915260a4546001600160801b038082168352600160801b9091041660208201528588612095565b6065546001600160a01b031633146112a55760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b80158015906112c957506000818152609d60205260409020546001600160801b0316155b156112ea57604051632d3c1ad360e01b81526004810182905260240161079c565b60005b828110156111c25781609c600086868581811061131a57634e487b7160e01b600052603260045260246000fd5b905060200201358152602001908152602001600020819055508061133d90613069565b90506112ed565b6065546001600160a01b0316331461138c5760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b61139581611b18565b6040805180820190915260a0546001600160801b038082168352600160801b9091041660208201526113c8908290611cea565b6113fe57604051639259c66b60e01b815281516001600160801b039081166004830152602083015116602482015260440161079c565b6040805180820190915260a2546001600160801b038082168352600160801b9091041660208201526114669061080b90611439908490611b82565b6040805180820190915260a3546001600160801b038082168352600160801b909104166020820152611b82565b80516020909101516001600160801b03908116600160801b0291161760a155565b600260015414156114da5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161079c565b6002600155604080516020808602828101820190935285825261154c928791879182918501908490808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525060019250612165915050565b5050600180555050565b609754600090600160a01b900460ff1615611572575060985490565b609760009054906101000a90046001600160a01b03166001600160a01b031663b82b11cf6040518163ffffffff1660e01b815260040160206040518083038186803b1580156115c057600080fd5b505afa1580156115d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f89190612ed3565b905090565b6065546001600160a01b031633146116455760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b61164e81611b18565b6040805180820190915260a1546001600160801b038082168352600160801b9091041660208201526116889061080b906114399084611b82565b80516020909101516001600160801b03908116600160801b0291161760a255565b600260015414156116fc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161079c565b6002600155604080516020808602828101820190935285825261154c928791879182918501908490808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201829052509250612165915050565b6065546001600160a01b031633146117b35760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b6097805460ff60a01b19169055565b6065546001600160a01b0316331461180a5760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b8061182b57604051633728b83d60e01b81526004810182905260240161079c565b60988190556097805460ff60a01b1916600160a01b1790556040517f4589714a4e091ee1f5546063b789414b026108edc40299d754c7f15bacbadced906118759083815260200190565b60405180910390a150565b6065546001600160a01b031633146118c85760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b6118d181611b18565b6040805180820190915260a1546001600160801b038082168352600160801b9091041660208201526119039082611cea565b61193957604051639259c66b60e01b815281516001600160801b039081166004830152602083015116602482015260440161079c565b80516020909101516001600160801b03908116600160801b0291161760a055565b60408051808201909152609a546001600160801b038082168352600160801b9091041660208201526000906111219084611992611556565b856124e7565b6065546001600160a01b031633146119e05760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b6001600160a01b038116611a5c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161079c565b611a6581611eb9565b50565b60408051808201909152600080825260208201526040805180820190915260a1546001600160801b038082168352600160801b909104166020820152611121908484611f0b565b60026001541415611b025760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161079c565b6002600181905550610e42609e83836001611d2b565b60208101516001600160801b03161580611b4b575080600001516001600160801b031681602001516001600160801b0316105b15611a6557604051639259c66b60e01b815281516001600160801b039081166004830152602083015116602482015260440161079c565b6040805180820190915260008082526020820152604051806040016040528083600001518560200151611bb59190612fd8565b60208501518651611bc69190612fd8565b611bd09190612f75565b6001600160801b0316815260200183602001518560200151611bf29190612fd8565b6001600160801b031690529392505050565b600054610100900460ff16611c6f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161079c565b6110d86125d9565b600054610100900460ff16611ce25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161079c565b6110d861264d565b60208201518151600091611cfd91612fd8565b6001600160801b031682602001518460000151611d1a9190612fd8565b6001600160801b0316119392505050565b8180611d4a5760405163251f56a160e21b815260040160405180910390fd5b6000805b82811015611e99576000868683818110611d7857634e487b7160e01b600052603260045260246000fd5b6020908102929092013560008181528b8452604090819020815160608101835281546001600160a01b0316808252600183015496820196909652600290910154918101919091529093509133149050611de3576040516282b42960e81b815260040160405180910390fd5b8060200151421015611e07576040516282b42960e81b815260040160405180910390fd5b6040810151611e169085612fa0565b600083815260208b8152604080832080546001600160a01b0319168155600181018490556002019290925583820151825190815289151591810191909152919550839133917fc676eee6188651bcfd52e90e7af08b34c939597e6cdf8c6f9e79a2ea8e0222de910160405180910390a3505080611e9290613069565b9050611d4e565b50609954611eb1906001600160a01b031633836126be565b505050505050565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080518082019091526000808252602082015260a55460405162ff815b60e01b81526001600160a01b0385811660048301529091169062ff815b9060240160206040518083038186803b158015611f6257600080fd5b505afa158015611f76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9a9190612ca8565b15611fd5576040805180820190915260a2546001600160801b038082168352600160801b909104166020820152611fd2908590611b82565b93505b6000828152609f6020526040902060010154421015612024576040805180820190915260a3546001600160801b038082168352600160801b909104166020820152612021908590611b82565b93505b509192915050565b60208101516001600160801b03161580611b4b575080602001516001600160801b031681600001516001600160801b03161015611a6557604051639259c66b60e01b815281516001600160801b039081166004830152602083015116602482015260440161079c565b60008086602001516001600160801b031687600001516001600160801b0316856120bf9190613007565b6120c99190612fb8565b9050600086602001516001600160801b031687600001516001600160801b0316866120f49190613007565b6120fe9190612fb8565b90508386602001516001600160801b031687600001516001600160801b031684846121299190613026565b6121339190613007565b61213d9190612fb8565b61214f90670de0b6b3a7640000613007565b6121599190612fb8565b98975050505050505050565b81518351146121875760405163251f56a160e21b815260040160405180910390fd5b60408051808201909152600080825260208201526040805180820190915260008082526020820152604080518082019091526000808252602082015283156121f7575060408051808201909152609a546001600160801b038082168352600160801b909104166020820152612278565b60408051808201825260a0546001600160801b038082168352600160801b918290048116602080850191909152845180860190955260a3548083168652929092041690830152935061224a908490611b82565b6040805180820190915260a4546001600160801b038082168352600160801b90910416602082015290925090505b6099546001600160a01b0316600061228e611556565b609b54909150600061229e612753565b905060008060005b8c518110156124835760008d82815181106122d157634e487b7160e01b600052603260045260246000fd5b6020026020010151905060008d83815181106122fd57634e487b7160e01b600052603260045260246000fd5b602002602001015190506000808e1561238f57506000838152609e60209081526040808320609c909252909120548061234c57604051632d3c1ad360e01b81526004810182905260240161079c565b6123588d828d8c6124e7565b9250828a111561237e57604051632d3c1ad360e01b81526004810182905260240161079c565b6123898584866127b5565b506123c4565b506000838152609f602052604090206123ab8e8e8e8d8c612095565b9150818911156123b9578891505b6123c4848385612803565b82421015806123d7575082816001015410155b156123f85760405163d107e31960e01b81526004810184905260240161079c565b600281018054825491849055600183018590556001600160a01b0319821633178355906001600160a01b031661242e848a612fa0565b98506001600160a01b0381163314156124525761244b8289612fa0565b975061246c565b811561246c5761246c6001600160a01b038e1682846126be565b5050505050508061247c90613069565b90506122a6565b50808211156124b2576124ad333061249b8486613026565b6001600160a01b038a16929190612848565b6124d9565b808210156124d9576124d9336124c88484613026565b6001600160a01b03891691906126be565b505050505050505050505050565b6000838152609d602090815260408083208151808301909252546001600160801b03808216808452600160801b9092041692820192909252901580612537575060208101516001600160801b0316155b1561254657600091505061095d565b8286602001516001600160801b031687600001516001600160801b03168684602001516001600160801b031685600001516001600160801b03168961258b9190613007565b6125959190612fb8565b61259f9190613026565b6125b190670de0b6b3a7640000613007565b6125bb9190613007565b6125c59190612fb8565b6125cf9190612fb8565b9695505050505050565b600054610100900460ff166126445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161079c565b6110d833611eb9565b600054610100900460ff166126b85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161079c565b60018055565b6040516001600160a01b03831660248201526044810182905261274e90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612880565b505050565b6097546099546040516332c4fe1360e01b81526001600160a01b03918216600482015260009291909116906332c4fe1390602401602060405180830381600087803b1580156127a157600080fd5b505af11580156115d4573d6000803e3d6000fd5b6040805183815260208101839052600191810191909152839033907ffd5203a7a82db968d610bb174f84cc6787f9f290f7743959ae3a2a8ed69dc28d906060015b60405180910390a3505050565b6040805183815260208101839052600091810191909152839033907ffd5203a7a82db968d610bb174f84cc6787f9f290f7743959ae3a2a8ed69dc28d906060016127f6565b6040516001600160a01b03808516602483015283166044820152606481018290526111c29085906323b872dd60e01b906084016126ea565b60006128d5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166129659092919063ffffffff16565b80519091501561274e57808060200190518101906128f39190612ca8565b61274e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161079c565b606061095d8484600085856001600160a01b0385163b6129c75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161079c565b600080866001600160a01b031685876040516129e39190612eeb565b60006040518083038185875af1925050503d8060008114612a20576040519150601f19603f3d011682016040523d82523d6000602084013e612a25565b606091505b5091509150612a35828286612a40565b979650505050505050565b60608315612a4f575081611121565b825115612a5f5782518084602001fd5b8160405162461bcd60e51b815260040161079c9190612f07565b60008083601f840112612a8a578182fd5b50813567ffffffffffffffff811115612aa1578182fd5b6020830191508360208260051b8501011115612abc57600080fd5b9250929050565b600060408284031215612ad4578081fd5b50919050565b600060208284031215612aeb578081fd5b813561112181613117565b60008060408385031215612b08578081fd5b8235612b1381613117565b946020939093013593505050565b60008060208385031215612b33578182fd5b823567ffffffffffffffff811115612b49578283fd5b612b5585828601612a79565b90969095509350505050565b60008060008060408587031215612b76578182fd5b843567ffffffffffffffff80821115612b8d578384fd5b612b9988838901612a79565b90965094506020870135915080821115612bb1578384fd5b818701915087601f830112612bc4578384fd5b813581811115612bd2578485fd5b886020606083028501011115612be6578485fd5b95989497505060200194505050565b60008060008060408587031215612c0a578384fd5b843567ffffffffffffffff80821115612c21578586fd5b612c2d88838901612a79565b90965094506020870135915080821115612c45578384fd5b50612c5287828801612a79565b95989497509550505050565b600080600060408486031215612c72578283fd5b833567ffffffffffffffff811115612c88578384fd5b612c9486828701612a79565b909790965060209590950135949350505050565b600060208284031215612cb9578081fd5b81518015158114611121578182fd5b600060208284031215612cd9578081fd5b5035919050565b60008060608385031215612cf2578182fd5b82359150612d038460208501612ac3565b90509250929050565b60008060408385031215612d1e578182fd5b50508035926020909101359150565b6000806000806000806000806000806102008b8d031215612d4c578586fd5b8a35612d5781613117565b995060208b0135612d6781613117565b985060408b0135612d7781613117565b9750612d868c60608d01612ac3565b9650612d958c60a08d01612ac3565b9550612da48c60e08d01612ac3565b9450612db48c6101208d01612ac3565b9350612dc48c6101608d01612ac3565b9250612dd48c6101a08d01612ac3565b91506101e08b013590509295989b9194979a5092959850565b6000806000806000806101608789031215612e06578384fd5b8635612e1181613117565b9550612e208860208901612ac3565b9450612e2f8860608901612ac3565b9350612e3e8860a08901612ac3565b9250612e4d8860e08901612ac3565b9150612e5d886101208901612ac3565b90509295509295509295565b600060408284031215612e7a578081fd5b6040516040810181811067ffffffffffffffff82111715612ea957634e487b7160e01b83526041600452602483fd5b6040528235612eb78161312c565b81526020830135612ec78161312c565b60208201529392505050565b600060208284031215612ee4578081fd5b5051919050565b60008251612efd81846020870161303d565b9190910192915050565b6020815260008251806020840152612f2681604085016020870161303d565b601f01601f19169190910160400192915050565b604081018235612f498161312c565b6001600160801b039081168352602084013590612f658261312c565b8082166020850152505092915050565b60006001600160801b03808316818516808303821115612f9757612f97613084565b01949350505050565b60008219821115612fb357612fb3613084565b500190565b600082612fd357634e487b7160e01b81526012600452602481fd5b500490565b60006001600160801b0380831681851681830481118215151615612ffe57612ffe613084565b02949350505050565b600081600019048311821515161561302157613021613084565b500290565b60008282101561303857613038613084565b500390565b60005b83811015613058578181015183820152602001613040565b838111156111c25750506000910152565b600060001982141561307d5761307d613084565b5060010190565b634e487b7160e01b600052601160045260246000fd5b81356130a581613117565b6001600160a01b0381166001600160a01b03198354161782555060208201356001820155604082013560028201555050565b81356130e28161312c565b6001600160801b03811690506001600160801b03198181845416178355602084013561310d8161312c565b60801b1617905550565b6001600160a01b0381168114611a6557600080fd5b6001600160801b0381168114611a6557600080fdfe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a26469706673582212209a101682e3a1b2f7d59f397819ed6b0f6aa1b87a1aafea97b36331e664ca63c364736f6c63430008040033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102e95760003560e01c8063822be78711610191578063df7412c0116100e3578063ee42a12611610097578063f960254d11610071578063f960254d146106ee578063fdb0480d14610701578063ffd833411461073a57600080fd5b8063ee42a126146106b5578063f2fde38b146106c8578063f6ea706f146106db57600080fd5b8063e9bdd3ef116100c8578063e9bdd3ef1461067c578063e9e3f36e1461068f578063eb88d91a146106a257600080fd5b8063df7412c014610661578063e38e56101461066957600080fd5b8063a222f99311610145578063b8ad10751161011f578063b8ad10751461061d578063c87ef91b14610630578063cd3149211461064e57600080fd5b8063a222f993146105ef578063a82f44cf14610602578063b82b11cf1461061557600080fd5b806389a0b6a01161017657806389a0b6a01461056d5780638da5cb5b146105cb5780639e00d0da146105dc57600080fd5b8063822be7871461053c57806384bc5ff51461055a57600080fd5b8063576be9731161024a5780636f47438c116101fe578063761d0ea1116101d8578063761d0ea1146104d557806379b2ab23146104e85780637dde5d8d1461050857600080fd5b80636f47438c14610480578063715018a61461049357806372208c4c1461049b57600080fd5b8063650d17931161022f578063650d17931461042b578063668362dd1461044f57806368f4630c1461046d57600080fd5b8063576be973146104055780635d7d551e1461041857600080fd5b80632be6d51b116102a15780634d1869be116102865780634d1869be146103d65780634dbaa038146103e95780634e1fd47d146103f257600080fd5b80632be6d51b1461037a578063454d4776146103b857600080fd5b80631ceaac72116102d25780631ceaac7214610316578063245a7bfc1461032957806329e463c91461035957600080fd5b806302a05e05146102ee5780630303dd9f14610303575b600080fd5b6103016102fc366004612e69565b610758565b005b610301610311366004612e69565b610831565b610301610324366004612e69565b6108a3565b60975461033c906001600160a01b031681565b6040516001600160a01b0390911681526020015b60405180910390f35b61036c610367366004612af6565b610915565b604051908152602001610350565b60a254610398906001600160801b0380821691600160801b90041682565b604080516001600160801b03938416815292909116602083015201610350565b60a354610398906001600160801b0380821691600160801b90041682565b6103016103e4366004612d2d565b610965565b61036c609b5481565b610301610400366004612b61565b610c49565b610301610413366004612b21565b610ddc565b61036c610426366004612af6565b610e4a565b60975461043f90600160a01b900460ff1681565b6040519015158152602001610350565b60a454610398906001600160801b0380821691600160801b90041682565b61030161047b366004612ded565b610e57565b61036c61048e366004612cc8565b610fe9565b610301611086565b6104ae6104a9366004612af6565b6110da565b6040805182516001600160801b039081168252602093840151169281019290925201610350565b6103016104e3366004612ce0565b611128565b61036c6104f6366004612cc8565b609c6020526000908152604090205481565b610398610516366004612cc8565b609d602052600090815260409020546001600160801b0380821691600160801b90041682565b609a54610398906001600160801b0380821691600160801b90041682565b61036c610568366004612d0c565b6111c8565b6105a661057b366004612cc8565b609e602052600090815260409020805460018201546002909201546001600160a01b03909116919083565b604080516001600160a01b039094168452602084019290925290820152606001610350565b6065546001600160a01b031661033c565b6103016105ea366004612c5e565b61125d565b6103016105fd366004612e69565b611344565b610301610610366004612bf5565b611487565b61036c611556565b61030161062b366004612e69565b6115fd565b60a154610398906001600160801b0380821691600160801b90041682565b61030161065c366004612bf5565b6116a9565b61030161176b565b60a55461033c906001600160a01b031681565b61030161068a366004612cc8565b6117c2565b61030161069d366004612e69565b611880565b60995461033c906001600160a01b031681565b61036c6106c3366004612d0c565b61195a565b6103016106d6366004612ada565b611998565b6104ae6106e9366004612af6565b611a68565b6103016106fc366004612b21565b611aaf565b6105a661070f366004612cc8565b609f602052600090815260409020805460018201546002909201546001600160a01b03909116919083565b60a054610398906001600160801b0380821691600160801b90041682565b6065546001600160a01b031633146107a55760405162461bcd60e51b8152602060048201819052602482015260008051602061314283398151915260448201526064015b60405180910390fd5b6107ae81611b18565b60408051808201825260a1546001600160801b038082168352600160801b918290048116602080850191909152845180860190955260a25480831686529290920416908301526108109161080b9161080591611b82565b83611b82565b611b18565b80516020909101516001600160801b03908116600160801b0291161760a355565b6065546001600160a01b031633146108795760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b61088281611b18565b80516020909101516001600160801b03908116600160801b0291161760a455565b6065546001600160a01b031633146108eb5760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b6108f481611b18565b80516020909101516001600160801b03908116600160801b02911617609a55565b60008061092284846110da565b905080602001516001600160801b031681600001516001600160801b031661094985610fe9565b6109539190613007565b61095d9190612fb8565b949350505050565b600054610100900460ff166109805760005460ff1615610984565b303b155b6109f65760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161079c565b600054610100900460ff16158015610a18576000805461ffff19166101011790555b610a20611c04565b610a28611c77565b6001600160a01b038b16610a4f5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038a16610a765760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038916610a9d5760405163d92e233d60e01b815260040160405180910390fd5b610aaf61080b368a90038a018a612e69565b610ac161080b36899003890189612e69565b610ad361080b36889003880188612e69565b610ae561080b36879003870187612e69565b610af761080b36869003860186612e69565b610b0961080b36859003850185612e69565b610b2f610b1b36899003890189612e69565b610b2a368b90038b018b612e69565b611cea565b610b4e5786604051639259c66b60e01b815260040161079c9190612f3a565b610b8961080b610b7a610b66368b90038b018b612e69565b610b75368b90038b018b612e69565b611b82565b610b7536899003890189612e69565b609980546001600160a01b03808e166001600160a01b031992831617909255609780548d841690831617905560a58054928c16929091169190911790558760a0610bd382826130d7565b5087905060a1610be382826130d7565b5086905060a2610bf382826130d7565b5085905060a3610c0382826130d7565b50849050609a610c1382826130d7565b5083905060a4610c2382826130d7565b5050609b8290558015610c3c576000805461ff00191690555b5050505050505050505050565b6065546001600160a01b03163314610c915760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b8281141580610c9e575082155b15610cbc5760405163251f56a160e21b815260040160405180910390fd5b60005b83811015610dd5576000609e81878785818110610cec57634e487b7160e01b600052603260045260246000fd5b60209081029290920135835250810191909152604001600020546001600160a01b031614610d5757848482818110610d3457634e487b7160e01b600052603260045260246000fd5b90506020020135604051633920d20d60e11b815260040161079c91815260200190565b828282818110610d7757634e487b7160e01b600052603260045260246000fd5b905060600201609e6000878785818110610da157634e487b7160e01b600052603260045260246000fd5b9050602002013581526020019081526020016000208181610dc2919061309a565b50610dce905081613069565b9050610cbf565b5050505050565b60026001541415610e2f5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161079c565b6002600155610e42609f83836000611d2b565b505060018055565b6000806109228484611a68565b60a5546001600160a01b031615610e80576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038616610ea75760405163d92e233d60e01b815260040160405180910390fd5b610eb961080b36879003870187612e69565b610ecb61080b36869003860186612e69565b610edd61080b36859003850185612e69565b610eef61080b36849003840184612e69565b610f0161080b36839003830183612e69565b610f22610f1336869003860186612e69565b610b2a36889003880188612e69565b610f415783604051639259c66b60e01b815260040161079c9190612f3a565b610f7761080b610f68610f5936889003880188612e69565b610b7536889003880188612e69565b610b7536869003860186612e69565b60a580546001600160a01b0319166001600160a01b0388161790558460a0610f9f82826130d7565b5084905060a1610faf82826130d7565b5083905060a2610fbf82826130d7565b5082905060a3610fcf82826130d7565b5081905060a4610fdf82826130d7565b5050505050505050565b600080610ff4611556565b6000848152609c6020526040902054909150801580159061102557506000848152609e602052604090206001015442105b1561107f576000818152609d60209081526040918290208251808401909352546001600160801b03808216808552600160801b9092041691830182905261106c9085613007565b6110769190612fb8565b95945050505050565b5092915050565b6065546001600160a01b031633146110ce5760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b6110d86000611eb9565b565b60408051808201909152600080825260208201526040805180820190915260a0546001600160801b038082168352600160801b909104166020820152611121908484611f0b565b9392505050565b6065546001600160a01b031633146111705760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b8161119157604051632d3c1ad360e01b81526004810183905260240161079c565b6111a86111a336839003830183612e69565b61202c565b6000828152609d6020526040902081906111c282826130d7565b50505050565b6000806111d484610fe9565b60408051808201825260a0546001600160801b038082168352600160801b918290048116602080850191909152845180860190955260a354808316865292909204169083015291925061107690829061122e908290611b82565b6040805180820190915260a4546001600160801b038082168352600160801b9091041660208201528588612095565b6065546001600160a01b031633146112a55760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b80158015906112c957506000818152609d60205260409020546001600160801b0316155b156112ea57604051632d3c1ad360e01b81526004810182905260240161079c565b60005b828110156111c25781609c600086868581811061131a57634e487b7160e01b600052603260045260246000fd5b905060200201358152602001908152602001600020819055508061133d90613069565b90506112ed565b6065546001600160a01b0316331461138c5760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b61139581611b18565b6040805180820190915260a0546001600160801b038082168352600160801b9091041660208201526113c8908290611cea565b6113fe57604051639259c66b60e01b815281516001600160801b039081166004830152602083015116602482015260440161079c565b6040805180820190915260a2546001600160801b038082168352600160801b9091041660208201526114669061080b90611439908490611b82565b6040805180820190915260a3546001600160801b038082168352600160801b909104166020820152611b82565b80516020909101516001600160801b03908116600160801b0291161760a155565b600260015414156114da5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161079c565b6002600155604080516020808602828101820190935285825261154c928791879182918501908490808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201919091525060019250612165915050565b5050600180555050565b609754600090600160a01b900460ff1615611572575060985490565b609760009054906101000a90046001600160a01b03166001600160a01b031663b82b11cf6040518163ffffffff1660e01b815260040160206040518083038186803b1580156115c057600080fd5b505afa1580156115d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115f89190612ed3565b905090565b6065546001600160a01b031633146116455760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b61164e81611b18565b6040805180820190915260a1546001600160801b038082168352600160801b9091041660208201526116889061080b906114399084611b82565b80516020909101516001600160801b03908116600160801b0291161760a255565b600260015414156116fc5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161079c565b6002600155604080516020808602828101820190935285825261154c928791879182918501908490808284376000920191909152505060408051602080880282810182019093528782529093508792508691829185019084908082843760009201829052509250612165915050565b6065546001600160a01b031633146117b35760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b6097805460ff60a01b19169055565b6065546001600160a01b0316331461180a5760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b8061182b57604051633728b83d60e01b81526004810182905260240161079c565b60988190556097805460ff60a01b1916600160a01b1790556040517f4589714a4e091ee1f5546063b789414b026108edc40299d754c7f15bacbadced906118759083815260200190565b60405180910390a150565b6065546001600160a01b031633146118c85760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b6118d181611b18565b6040805180820190915260a1546001600160801b038082168352600160801b9091041660208201526119039082611cea565b61193957604051639259c66b60e01b815281516001600160801b039081166004830152602083015116602482015260440161079c565b80516020909101516001600160801b03908116600160801b0291161760a055565b60408051808201909152609a546001600160801b038082168352600160801b9091041660208201526000906111219084611992611556565b856124e7565b6065546001600160a01b031633146119e05760405162461bcd60e51b81526020600482018190526024820152600080516020613142833981519152604482015260640161079c565b6001600160a01b038116611a5c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161079c565b611a6581611eb9565b50565b60408051808201909152600080825260208201526040805180820190915260a1546001600160801b038082168352600160801b909104166020820152611121908484611f0b565b60026001541415611b025760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161079c565b6002600181905550610e42609e83836001611d2b565b60208101516001600160801b03161580611b4b575080600001516001600160801b031681602001516001600160801b0316105b15611a6557604051639259c66b60e01b815281516001600160801b039081166004830152602083015116602482015260440161079c565b6040805180820190915260008082526020820152604051806040016040528083600001518560200151611bb59190612fd8565b60208501518651611bc69190612fd8565b611bd09190612f75565b6001600160801b0316815260200183602001518560200151611bf29190612fd8565b6001600160801b031690529392505050565b600054610100900460ff16611c6f5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161079c565b6110d86125d9565b600054610100900460ff16611ce25760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161079c565b6110d861264d565b60208201518151600091611cfd91612fd8565b6001600160801b031682602001518460000151611d1a9190612fd8565b6001600160801b0316119392505050565b8180611d4a5760405163251f56a160e21b815260040160405180910390fd5b6000805b82811015611e99576000868683818110611d7857634e487b7160e01b600052603260045260246000fd5b6020908102929092013560008181528b8452604090819020815160608101835281546001600160a01b0316808252600183015496820196909652600290910154918101919091529093509133149050611de3576040516282b42960e81b815260040160405180910390fd5b8060200151421015611e07576040516282b42960e81b815260040160405180910390fd5b6040810151611e169085612fa0565b600083815260208b8152604080832080546001600160a01b0319168155600181018490556002019290925583820151825190815289151591810191909152919550839133917fc676eee6188651bcfd52e90e7af08b34c939597e6cdf8c6f9e79a2ea8e0222de910160405180910390a3505080611e9290613069565b9050611d4e565b50609954611eb1906001600160a01b031633836126be565b505050505050565b606580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b604080518082019091526000808252602082015260a55460405162ff815b60e01b81526001600160a01b0385811660048301529091169062ff815b9060240160206040518083038186803b158015611f6257600080fd5b505afa158015611f76573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f9a9190612ca8565b15611fd5576040805180820190915260a2546001600160801b038082168352600160801b909104166020820152611fd2908590611b82565b93505b6000828152609f6020526040902060010154421015612024576040805180820190915260a3546001600160801b038082168352600160801b909104166020820152612021908590611b82565b93505b509192915050565b60208101516001600160801b03161580611b4b575080602001516001600160801b031681600001516001600160801b03161015611a6557604051639259c66b60e01b815281516001600160801b039081166004830152602083015116602482015260440161079c565b60008086602001516001600160801b031687600001516001600160801b0316856120bf9190613007565b6120c99190612fb8565b9050600086602001516001600160801b031687600001516001600160801b0316866120f49190613007565b6120fe9190612fb8565b90508386602001516001600160801b031687600001516001600160801b031684846121299190613026565b6121339190613007565b61213d9190612fb8565b61214f90670de0b6b3a7640000613007565b6121599190612fb8565b98975050505050505050565b81518351146121875760405163251f56a160e21b815260040160405180910390fd5b60408051808201909152600080825260208201526040805180820190915260008082526020820152604080518082019091526000808252602082015283156121f7575060408051808201909152609a546001600160801b038082168352600160801b909104166020820152612278565b60408051808201825260a0546001600160801b038082168352600160801b918290048116602080850191909152845180860190955260a3548083168652929092041690830152935061224a908490611b82565b6040805180820190915260a4546001600160801b038082168352600160801b90910416602082015290925090505b6099546001600160a01b0316600061228e611556565b609b54909150600061229e612753565b905060008060005b8c518110156124835760008d82815181106122d157634e487b7160e01b600052603260045260246000fd5b6020026020010151905060008d83815181106122fd57634e487b7160e01b600052603260045260246000fd5b602002602001015190506000808e1561238f57506000838152609e60209081526040808320609c909252909120548061234c57604051632d3c1ad360e01b81526004810182905260240161079c565b6123588d828d8c6124e7565b9250828a111561237e57604051632d3c1ad360e01b81526004810182905260240161079c565b6123898584866127b5565b506123c4565b506000838152609f602052604090206123ab8e8e8e8d8c612095565b9150818911156123b9578891505b6123c4848385612803565b82421015806123d7575082816001015410155b156123f85760405163d107e31960e01b81526004810184905260240161079c565b600281018054825491849055600183018590556001600160a01b0319821633178355906001600160a01b031661242e848a612fa0565b98506001600160a01b0381163314156124525761244b8289612fa0565b975061246c565b811561246c5761246c6001600160a01b038e1682846126be565b5050505050508061247c90613069565b90506122a6565b50808211156124b2576124ad333061249b8486613026565b6001600160a01b038a16929190612848565b6124d9565b808210156124d9576124d9336124c88484613026565b6001600160a01b03891691906126be565b505050505050505050505050565b6000838152609d602090815260408083208151808301909252546001600160801b03808216808452600160801b9092041692820192909252901580612537575060208101516001600160801b0316155b1561254657600091505061095d565b8286602001516001600160801b031687600001516001600160801b03168684602001516001600160801b031685600001516001600160801b03168961258b9190613007565b6125959190612fb8565b61259f9190613026565b6125b190670de0b6b3a7640000613007565b6125bb9190613007565b6125c59190612fb8565b6125cf9190612fb8565b9695505050505050565b600054610100900460ff166126445760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161079c565b6110d833611eb9565b600054610100900460ff166126b85760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840161079c565b60018055565b6040516001600160a01b03831660248201526044810182905261274e90849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152612880565b505050565b6097546099546040516332c4fe1360e01b81526001600160a01b03918216600482015260009291909116906332c4fe1390602401602060405180830381600087803b1580156127a157600080fd5b505af11580156115d4573d6000803e3d6000fd5b6040805183815260208101839052600191810191909152839033907ffd5203a7a82db968d610bb174f84cc6787f9f290f7743959ae3a2a8ed69dc28d906060015b60405180910390a3505050565b6040805183815260208101839052600091810191909152839033907ffd5203a7a82db968d610bb174f84cc6787f9f290f7743959ae3a2a8ed69dc28d906060016127f6565b6040516001600160a01b03808516602483015283166044820152606481018290526111c29085906323b872dd60e01b906084016126ea565b60006128d5826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166129659092919063ffffffff16565b80519091501561274e57808060200190518101906128f39190612ca8565b61274e5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161079c565b606061095d8484600085856001600160a01b0385163b6129c75760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161079c565b600080866001600160a01b031685876040516129e39190612eeb565b60006040518083038185875af1925050503d8060008114612a20576040519150601f19603f3d011682016040523d82523d6000602084013e612a25565b606091505b5091509150612a35828286612a40565b979650505050505050565b60608315612a4f575081611121565b825115612a5f5782518084602001fd5b8160405162461bcd60e51b815260040161079c9190612f07565b60008083601f840112612a8a578182fd5b50813567ffffffffffffffff811115612aa1578182fd5b6020830191508360208260051b8501011115612abc57600080fd5b9250929050565b600060408284031215612ad4578081fd5b50919050565b600060208284031215612aeb578081fd5b813561112181613117565b60008060408385031215612b08578081fd5b8235612b1381613117565b946020939093013593505050565b60008060208385031215612b33578182fd5b823567ffffffffffffffff811115612b49578283fd5b612b5585828601612a79565b90969095509350505050565b60008060008060408587031215612b76578182fd5b843567ffffffffffffffff80821115612b8d578384fd5b612b9988838901612a79565b90965094506020870135915080821115612bb1578384fd5b818701915087601f830112612bc4578384fd5b813581811115612bd2578485fd5b886020606083028501011115612be6578485fd5b95989497505060200194505050565b60008060008060408587031215612c0a578384fd5b843567ffffffffffffffff80821115612c21578586fd5b612c2d88838901612a79565b90965094506020870135915080821115612c45578384fd5b50612c5287828801612a79565b95989497509550505050565b600080600060408486031215612c72578283fd5b833567ffffffffffffffff811115612c88578384fd5b612c9486828701612a79565b909790965060209590950135949350505050565b600060208284031215612cb9578081fd5b81518015158114611121578182fd5b600060208284031215612cd9578081fd5b5035919050565b60008060608385031215612cf2578182fd5b82359150612d038460208501612ac3565b90509250929050565b60008060408385031215612d1e578182fd5b50508035926020909101359150565b6000806000806000806000806000806102008b8d031215612d4c578586fd5b8a35612d5781613117565b995060208b0135612d6781613117565b985060408b0135612d7781613117565b9750612d868c60608d01612ac3565b9650612d958c60a08d01612ac3565b9550612da48c60e08d01612ac3565b9450612db48c6101208d01612ac3565b9350612dc48c6101608d01612ac3565b9250612dd48c6101a08d01612ac3565b91506101e08b013590509295989b9194979a5092959850565b6000806000806000806101608789031215612e06578384fd5b8635612e1181613117565b9550612e208860208901612ac3565b9450612e2f8860608901612ac3565b9350612e3e8860a08901612ac3565b9250612e4d8860e08901612ac3565b9150612e5d886101208901612ac3565b90509295509295509295565b600060408284031215612e7a578081fd5b6040516040810181811067ffffffffffffffff82111715612ea957634e487b7160e01b83526041600452602483fd5b6040528235612eb78161312c565b81526020830135612ec78161312c565b60208201529392505050565b600060208284031215612ee4578081fd5b5051919050565b60008251612efd81846020870161303d565b9190910192915050565b6020815260008251806020840152612f2681604085016020870161303d565b601f01601f19169190910160400192915050565b604081018235612f498161312c565b6001600160801b039081168352602084013590612f658261312c565b8082166020850152505092915050565b60006001600160801b03808316818516808303821115612f9757612f97613084565b01949350505050565b60008219821115612fb357612fb3613084565b500190565b600082612fd357634e487b7160e01b81526012600452602481fd5b500490565b60006001600160801b0380831681851681830481118215151615612ffe57612ffe613084565b02949350505050565b600081600019048311821515161561302157613021613084565b500290565b60008282101561303857613038613084565b500390565b60005b83811015613058578181015183820152602001613040565b838111156111c25750506000910152565b600060001982141561307d5761307d613084565b5060010190565b634e487b7160e01b600052601160045260246000fd5b81356130a581613117565b6001600160a01b0381166001600160a01b03198354161782555060208201356001820155604082013560028201555050565b81356130e28161312c565b6001600160801b03811690506001600160801b03198181845416178355602084013561310d8161312c565b60801b1617905550565b6001600160a01b0381168114611a6557600080fd5b6001600160801b0381168114611a6557600080fdfe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a26469706673582212209a101682e3a1b2f7d59f397819ed6b0f6aa1b87a1aafea97b36331e664ca63c364736f6c63430008040033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
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.