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 Source Code Verified (Exact Match)
Contract Name:
PoolMaster
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "./PoolMetadata.sol"; import "./PoolRewards.sol"; contract PoolMaster is PoolRewards, PoolMetadata { // CONSTRUCTOR /** * @notice Upgradeable contract constructor * @param manager_ Address of the Pool's manager * @param currency_ Address of the currency token */ function initialize(address manager_, IERC20Upgradeable currency_) external initializer { __PoolBaseInfo_init(manager_, currency_); } // OVERRIDES function _mint(address account, uint256 value) internal override(ERC20Upgradeable, PoolRewards) { super._mint(account, value); } function _burn(address account, uint256 value) internal override(ERC20Upgradeable, PoolRewards) { super._burn(account, value); } function decimals() public view override(ERC20Upgradeable, PoolMetadata) returns (uint8) { return super.decimals(); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20MetadataUpgradeable.sol"; import "./PoolBase.sol"; import "../libraries/Decimal.sol"; abstract contract PoolMetadata is PoolBase { using Decimal for uint256; /** * @notice Function that returns cp-token decimals * @return Cp-token decimals */ function decimals() public view virtual override returns (uint8) { return IERC20MetadataUpgradeable(address(currency)).decimals(); } /** * @notice Function returns current (with accrual) pool state * @return Current state */ function state() external view returns (State) { return _state(_accrueInterestVirtual()); } /** * @notice Function returns current (with accrual) last accrual timestamp * @return Last accrual timestamp */ function lastAccrual() external view returns (uint256) { return _accrueInterestVirtual().lastAccrual; } /** * @notice Function returns current (with accrual) interest value * @return Current interest */ function interest() external view returns (uint256) { return _interest(_accrueInterestVirtual()); } /** * @notice Function returns current (with accrual) amount of funds available to LP for withdrawal * @return Current available to withdraw funds */ function availableToWithdraw() external view returns (uint256) { if (debtClaimed) { return cash(); } else { BorrowInfo memory info = _accrueInterestVirtual(); return MathUpgradeable.min( _availableToProviders(info), _availableProvisionalDefault(info) ); } } /** * @notice Function returns current (with accrual) amount of funds available for manager to borrow * @return Current available to borrow funds */ function availableToBorrow() external view returns (uint256) { return _availableToBorrow(_accrueInterestVirtual()); } /** * @notice Function returns current (with accrual) pool size * @return Current pool size */ function poolSize() external view returns (uint256) { return _poolSize(_accrueInterestVirtual()); } /** * @notice Function returns current principal value * @return Current principal */ function principal() external view returns (uint256) { return _info.principal; } /** * @notice Function returns current (with accrual) total borrows value * @return Current borrows */ function borrows() external view returns (uint256) { return _accrueInterestVirtual().borrows; } /** * @notice Function returns current (with accrual) reserves value * @return Current reserves */ function reserves() public view returns (uint256) { return _accrueInterestVirtual().reserves; } /** * @notice Function returns current (with accrual) insurance value * @return Current insurance */ function insurance() external view returns (uint256) { return _accrueInterestVirtual().insurance; } /** * @notice Function returns timestamp when pool entered zero utilization state (0 if didn't enter) * @return Timestamp of entering zero utilization */ function enteredZeroUtilization() external view returns (uint256) { return _info.enteredZeroUtilization; } /** * @notice Function returns timestamp when pool entered warning utilization state (0 if didn't enter) * @return Timestamp of entering warning utilization */ function enteredProvisionalDefault() external view returns (uint256) { return _accrueInterestVirtual().enteredProvisionalDefault; } /** * @notice Function returns current (with accrual) exchange rate of cpTokens for currency tokens * @return Current exchange rate as 10-digits decimal */ function getCurrentExchangeRate() external view returns (uint256) { if (totalSupply() == 0) { return Decimal.ONE; } else if (debtClaimed) { return cash().divDecimal(totalSupply()); } else { BorrowInfo memory info = _accrueInterestVirtual(); return (_availableToProviders(info) + info.borrows).divDecimal( totalSupply() ); } } /** * @notice Function to get current borrow interest rate * @return Borrow interest rate as 18-digit decimal */ function getBorrowRate() public view returns (uint256) { BorrowInfo memory info = _accrueInterestVirtual(); return interestRateModel.getBorrowRate( currency.balanceOf(address(this)), info.borrows, info.reserves + info.insurance + (info.borrows - info.principal) ); } /** * @notice Function to get current supply interest rate * @return Supply interest rate as 18-digit decimal */ function getSupplyRate() external view returns (uint256) { BorrowInfo memory info = _accrueInterestVirtual(); return interestRateModel.getSupplyRate( currency.balanceOf(address(this)), info.borrows, info.reserves + info.insurance + (info.borrows - info.principal), reserveFactor + insuranceFactor ); } /** * @notice Function to get current utilization rate * @return Utilization rate as 18-digit decimal */ function getUtilizationRate() external view returns (uint256) { BorrowInfo memory info = _accrueInterestVirtual(); return interestRateModel.utilizationRate( cash(), info.borrows, info.insurance + info.reserves + _interest(info) ); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/math/SafeCastUpgradeable.sol"; import "./PoolBase.sol"; abstract contract PoolRewards is PoolBase { using SafeCastUpgradeable for uint256; using SafeCastUpgradeable for int256; using SafeERC20Upgradeable for IERC20Upgradeable; /// @notice Amount of CPOOL rewards per block for liquidity providers in this pool uint256 public rewardPerBlock; /// @notice Value by which all rewards are magnified for calculation uint256 internal constant REWARD_MAGNITUDE = 2**128; /// @notice Block when last staking reward distribution occured uint256 internal _lastRewardDistribution; /// @notice Reward per LP token, magnified by 2**128 for increased precision uint256 internal _magnifiedRewardPerShare; /// @notice Reward corrections of accounts (to remain previous rewards unchanged when user's balance changes) mapping(address => int256) internal _magnifiedRewardCorrections; /// @notice Reward withdrawals of accounts mapping(address => uint256) internal _withdrawals; // EVENTS /// @notice Event emitted when account withdraws his reward event RewardWithdrawn(address indexed account, uint256 amount); /// @notice Event emitted when new reward per block is set event RewardPerBlockSet(uint256 newRewardPerBlock); // PUBLIC FUNCTIONS /** * @notice Function is called through Factory to withdraw reward for some user * @param account Account to withdraw reward for * @return Withdrawn amount */ function withdrawReward(address account) external onlyFactory returns (uint256) { _accrueInterest(); _distributeReward(); uint256 withdrawable = withdrawableRewardOf(account); if (withdrawable > 0) { _withdrawals[account] += withdrawable; emit RewardWithdrawn(account, withdrawable); } return withdrawable; } /** * @notice Function is called by Factory to set new reward speed per block * @param rewardPerBlock_ New reward per block */ function setRewardPerBlock(uint256 rewardPerBlock_) external onlyFactory { _accrueInterest(); _distributeReward(); if (_lastRewardDistribution == 0) { _lastRewardDistribution = _info.lastAccrual; } rewardPerBlock = rewardPerBlock_; emit RewardPerBlockSet(rewardPerBlock_); } // VIEW FUNCTIONS /** * @notice Gets total accumulated reward of some account * @return Total accumulated reward of account */ function accumulativeRewardOf(address account) public view returns (uint256) { BorrowInfo memory info = _accrueInterestVirtual(); uint256 currentRewardPerShare = _magnifiedRewardPerShare; if ( _lastRewardDistribution != 0 && info.lastAccrual > _lastRewardDistribution && totalSupply() > 0 ) { uint256 period = info.lastAccrual - _lastRewardDistribution; currentRewardPerShare += (REWARD_MAGNITUDE * period * rewardPerBlock) / totalSupply(); } return ((balanceOf(account) * currentRewardPerShare).toInt256() + _magnifiedRewardCorrections[account]).toUint256() / REWARD_MAGNITUDE; } /** * @notice Gets withdrawn part of reward of some account * @return Withdrawn reward of account */ function withdrawnRewardOf(address account) public view returns (uint256) { return _withdrawals[account]; } /** * @notice Gets currently withdrawable reward of some account * @return Withdrawable reward of account */ function withdrawableRewardOf(address account) public view returns (uint256) { return accumulativeRewardOf(account) - withdrawnRewardOf(account); } // INTERNAL FUNCTIONS /** * @notice Internal function for rewards distribution */ function _distributeReward() internal { if ( rewardPerBlock > 0 && _lastRewardDistribution != 0 && _info.lastAccrual > _lastRewardDistribution && totalSupply() > 0 ) { uint256 period = _info.lastAccrual - _lastRewardDistribution; _magnifiedRewardPerShare += (REWARD_MAGNITUDE * period * rewardPerBlock) / totalSupply(); } _lastRewardDistribution = _info.lastAccrual; } /** * @notice Override of mint function with rewards corrections * @param account Account to mint for * @param value Amount to mint */ function _mint(address account, uint256 value) internal virtual override { _distributeReward(); super._mint(account, value); _magnifiedRewardCorrections[account] -= (_magnifiedRewardPerShare * value).toInt256(); } /** * @notice Override of burn function with rewards corrections * @param account Account to burn from * @param value Amount to burn */ function _burn(address account, uint256 value) internal virtual override { _distributeReward(); super._burn(account, value); _magnifiedRewardCorrections[account] += (_magnifiedRewardPerShare * value).toInt256(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUpgradeable { /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a / b + (a % b == 0 ? 0 : 1); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20Upgradeable.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol"; import "./PoolBaseInfo.sol"; import "../libraries/Decimal.sol"; import "../interfaces/IAuction.sol"; abstract contract PoolBase is PoolBaseInfo { using SafeERC20Upgradeable for IERC20Upgradeable; using Decimal for uint256; // PUBLIC FUNCTIONS /** * @notice Function is used to provide liquidity for Pool in exchange for cpTokens * @dev Approval for desired amount of currency token should be given in prior * @param currencyAmount Amount of currency token that user want to provide */ function provide(uint256 currencyAmount) external onlyActiveAccrual { uint256 exchangeRate = _storedExchangeRate(); currency.safeTransferFrom(msg.sender, address(this), currencyAmount); uint256 tokens = currencyAmount.divDecimal(exchangeRate); _mint(msg.sender, tokens); _checkUtilization(); emit Provided(msg.sender, currencyAmount, tokens); } /** * @notice Function is used to redeem previously provided liquidity with interest, burning cpTokens * @param tokens Amount of cpTokens to burn (MaxUint256 to burn maximal possible) */ function redeem(uint256 tokens) external { _accrueInterest(); uint256 exchangeRate = _storedExchangeRate(); uint256 currencyAmount; if (tokens == type(uint256).max) { (tokens, currencyAmount) = _maxWithdrawable(exchangeRate); } else { currencyAmount = tokens.mulDecimal(exchangeRate); } _redeem(tokens, currencyAmount); } /** * @notice Function is used to redeem previously provided liquidity with interest, burning cpTokens * @param currencyAmount Amount of currency to redeem (MaxUint256 to redeem maximal possible) */ function redeemCurrency(uint256 currencyAmount) external { _accrueInterest(); uint256 exchangeRate = _storedExchangeRate(); uint256 tokens; if (currencyAmount == type(uint256).max) { (tokens, currencyAmount) = _maxWithdrawable(exchangeRate); } else { tokens = currencyAmount.divDecimal(exchangeRate); } _redeem(tokens, currencyAmount); } /** * @notice Function is used to borrow from the pool * @param amount Amount of currency to borrow (MaxUint256 to borrow everything available) * @param receiver Address where to transfer currency */ function borrow(uint256 amount, address receiver) external onlyManager onlyActiveAccrual { if (amount == type(uint256).max) { amount = _availableToBorrow(_info); } else { require(amount <= _availableToBorrow(_info), "NEL"); } require(amount > 0, "CBZ"); _info.principal += amount; _info.borrows += amount; currency.safeTransfer(receiver, amount); _checkUtilization(); emit Borrowed(amount, receiver); } /** * @notice Function is used to repay borrowed funds * @param amount Amount to repay (MaxUint256 to repay all debt) * @param closeNow True to close pool immedeately */ function repay(uint256 amount, bool closeNow) external onlyManager onlyActiveAccrual { if (amount == type(uint256).max) { amount = _info.borrows; } else { require(amount <= _info.borrows, "MTB"); } currency.safeTransferFrom(msg.sender, address(this), amount); if (amount > _info.borrows - _info.principal) { _info.principal -= amount - (_info.borrows - _info.principal); } _info.borrows -= amount; _checkUtilization(); emit Repaid(amount); if (closeNow) { require(_info.borrows == 0, "BNZ"); _close(); } } /** * @notice Function is used to close pool */ function close() external { _accrueInterest(); address governor = factory.owner(); address debtOwner = ownerOfDebt(); bool managerClosing = _info.borrows == 0 && msg.sender == manager; bool inactiveOverMax = _info.enteredZeroUtilization != 0 && block.timestamp > _info.enteredZeroUtilization + maxInactivePeriod; bool governorClosing = msg.sender == governor && (inactiveOverMax || debtOwner != address(0)); bool ownerOfDebtClosing = msg.sender == debtOwner; require(managerClosing || governorClosing || ownerOfDebtClosing, "SCC"); _close(); } /** * @notice Function is used to distribute insurance and close pool after period to start auction passed */ function allowWithdrawalAfterNoAuction() external { _accrueInterest(); bool isDefaulting = _state(_info) == State.Default; bool auctionNotStarted = IAuction(factory.auction()).state( address(this) ) == IAuction.State.NotStarted; bool periodToStartPassed = block.timestamp >= _info.lastAccrual + periodToStartAuction; require( isDefaulting && auctionNotStarted && periodToStartPassed, "CDC" ); _info.insurance = 0; debtClaimed = true; _close(); } /** * @notice Function is called by governor to transfer reserves to the treasury */ function transferReserves() external onlyGovernor { _accrueInterest(); _transferReserves(); } /** * @notice Function is called by Auction contract when auction is started */ function processAuctionStart() external onlyAuction { _accrueInterest(); _transferReserves(); factory.burnStake(); } /** * @notice Function is called by Auction contract to process pool debt claim */ function processDebtClaim() external onlyAuction { _accrueInterest(); _info.state = State.Default; address debtOwner = ownerOfDebt(); if (_info.insurance > 0) { currency.safeTransfer(debtOwner, _info.insurance); _info.insurance = 0; } debtClaimed = true; } // INTERNAL FUNCTIONS /** * @notice Internal function that processes token redemption * @param tokensAmount Amount of tokens being redeemed * @param currencyAmount Equivalent amount of currency */ function _redeem(uint256 tokensAmount, uint256 currencyAmount) internal { if (debtClaimed) { require(currencyAmount <= cash(), "NEC"); } else { require( currencyAmount <= _availableToProviders(_info) && currencyAmount <= _availableProvisionalDefault(_info), "NEC" ); } _burn(msg.sender, tokensAmount); currency.safeTransfer(msg.sender, currencyAmount); if (!debtClaimed) { _checkUtilization(); } emit Redeemed(msg.sender, currencyAmount, tokensAmount); } /** * @notice Internal function to transfer reserves to the treasury */ function _transferReserves() internal { currency.safeTransfer(factory.treasury(), _info.reserves); _info.reserves = 0; } /** * @notice Internal function for closing pool */ function _close() internal { require(_info.state != State.Closed, "PIC"); _info.state = State.Closed; _transferReserves(); if (_info.insurance > 0) { currency.safeTransfer(manager, _info.insurance); _info.insurance = 0; } factory.closePool(); emit Closed(); } /** * @notice Internal function to accrue interest */ function _accrueInterest() internal { _info = _accrueInterestVirtual(); } /** * @notice Internal function that is called at each action to check for zero/warning/default utilization */ function _checkUtilization() internal { if (_info.borrows == 0) { _info.enteredProvisionalDefault = 0; if (_info.enteredZeroUtilization == 0) { _info.enteredZeroUtilization = block.timestamp; } return; } _info.enteredZeroUtilization = 0; if (_info.borrows >= _poolSize(_info).mulDecimal(warningUtilization)) { if ( _info.enteredProvisionalDefault == 0 && _info.borrows >= _poolSize(_info).mulDecimal(provisionalDefaultUtilization) ) { _info.enteredProvisionalDefault = block.timestamp; } } else { _info.enteredProvisionalDefault = 0; } } // PUBLIC VIEW /** * @notice Function to get owner of the pool's debt * @return Pool's debt owner */ function ownerOfDebt() public view returns (address) { return IAuction(factory.auction()).ownerOfDebt(address(this)); } /** * @notice Function returns cash amount (balance of currency in the pool) * @return Cash amount */ function cash() public view returns (uint256) { return currency.balanceOf(address(this)); } // INTERNAL VIEW /** * @notice Function to get current pool state * @return Pool state as State enumerable */ function _state(BorrowInfo memory info) internal view returns (State) { if (info.state == State.Closed || info.state == State.Default) { return info.state; } if (info.enteredProvisionalDefault != 0) { if ( block.timestamp >= info.enteredProvisionalDefault + warningGracePeriod ) { return State.Default; } else { return State.ProvisionalDefault; } } if ( info.borrows > 0 && info.borrows >= _poolSize(info).mulDecimal(warningUtilization) ) { return State.Warning; } return info.state; } /** * @notice Function returns interest value for given borrow info * @param info Borrow info struct * @return Interest for given info */ function _interest(BorrowInfo memory info) internal pure returns (uint256) { return info.borrows - info.principal; } /** * @notice Function returns amount of funds generally available for providers value for given borrow info * @param info Borrow info struct * @return Available to providers for given info */ function _availableToProviders(BorrowInfo memory info) internal view returns (uint256) { return cash() - info.reserves - info.insurance; } /** * @notice Function returns available to borrow value for given borrow info * @param info Borrow info struct * @return Available to borrow for given info */ function _availableToBorrow(BorrowInfo memory info) internal view returns (uint256) { uint256 basicAvailable = _availableToProviders(info) - _interest(info); uint256 borrowsForWarning = _poolSize(info).mulDecimal( warningUtilization ); if (borrowsForWarning > info.borrows) { return MathUpgradeable.min( borrowsForWarning - info.borrows, basicAvailable ); } else { return 0; } } /** * @notice Function returns pool size for given borrow info * @param info Borrow info struct * @return Pool size for given info */ function _poolSize(BorrowInfo memory info) internal view returns (uint256) { return _availableToProviders(info) + info.principal; } /** * @notice Function returns funds available to be taken from pool before provisional default will be reached * @param info Borrow info struct * @return Pool size for given info */ function _availableProvisionalDefault(BorrowInfo memory info) internal view returns (uint256) { if (provisionalDefaultUtilization == 0) { return 0; } uint256 poolSizeForProvisionalDefault = info.borrows.divDecimal( provisionalDefaultUtilization ); uint256 currentPoolSize = _poolSize(info); return currentPoolSize > poolSizeForProvisionalDefault ? currentPoolSize - poolSizeForProvisionalDefault : 0; } /** * @notice Function returns maximal redeemable amount for given exchange rate * @param exchangeRate Exchange rate of cp-tokens to currency * @return tokensAmount Maximal redeemable amount of tokens * @return currencyAmount Maximal redeemable amount of currency */ function _maxWithdrawable(uint256 exchangeRate) internal view returns (uint256 tokensAmount, uint256 currencyAmount) { currencyAmount = _availableToProviders(_info); if (!debtClaimed) { uint256 availableProvisionalDefault = _availableProvisionalDefault( _info ); if (availableProvisionalDefault < currencyAmount) { currencyAmount = availableProvisionalDefault; } } tokensAmount = currencyAmount.divDecimal(exchangeRate); if (balanceOf(msg.sender) < tokensAmount) { tokensAmount = balanceOf(msg.sender); currencyAmount = tokensAmount.mulDecimal(exchangeRate); } } /** * @notice Function returns stored (without accruing) exchange rate of cpTokens for currency tokens * @return Stored exchange rate as 10-digits decimal */ function _storedExchangeRate() internal view returns (uint256) { if (totalSupply() == 0) { return Decimal.ONE; } else if (debtClaimed) { return cash().divDecimal(totalSupply()); } else { return (_availableToProviders(_info) + _info.borrows).divDecimal( totalSupply() ); } } /** * @notice Function returns timestamp when pool entered or will enter provisional default at given interest rate * @param interestRate Borrows interest rate at current period * @return Timestamp of entering provisional default (0 if won't ever enter) */ function _entranceOfProvisionalDefault(uint256 interestRate) internal view returns (uint256) { if (_info.enteredProvisionalDefault != 0) { return _info.enteredProvisionalDefault; } if (_info.borrows == 0 || interestRate == 0) { return 0; } // Consider: // IFPD - Interest for provisional default // PSPD = Pool size at provisional default // IRPD = Reserves & insurance at provisional default // IR = Current reserves and insurance // PDU = Provisional default utilization // We have: Borrows + IFPD = PDU * PSPD // => Borrows + IFPD = PDU * (Principal + Cash + IRPD) // => Borrows + IFPD = PDU * (Principal + Cash + IR + IFPD * (insuranceFactor + reserveFactor)) // => IFPD * (1 + PDU * (reserveFactor + insuranceFactor)) = PDU * PoolSize - Borrows // => IFPD = (PDU * PoolSize - Borrows) / (1 + PDU * (reserveFactor + insuranceFactor)) uint256 numerator = _poolSize(_info).mulDecimal( provisionalDefaultUtilization ) - _info.borrows; uint256 denominator = Decimal.ONE + provisionalDefaultUtilization.mulDecimal( reserveFactor + insuranceFactor ); uint256 interestForProvisionalDefault = numerator.divDecimal( denominator ); uint256 interestPerSec = _info.borrows * interestRate; // Time delta is calculated as interest for provisional default divided by interest per sec (rounded up) uint256 timeDelta = (interestForProvisionalDefault * Decimal.ONE + interestPerSec - 1) / interestPerSec; uint256 entrance = _info.lastAccrual + timeDelta; return entrance <= block.timestamp ? entrance : 0; } /** * @notice Function virtually accrues interest and returns updated borrow info struct * @return Borrow info struct after accrual */ function _accrueInterestVirtual() internal view returns (BorrowInfo memory) { BorrowInfo memory newInfo = _info; if ( block.timestamp == newInfo.lastAccrual || newInfo.state == State.Default || newInfo.state == State.Closed ) { return newInfo; } uint256 interestRate = interestRateModel.getBorrowRate( cash(), newInfo.borrows, newInfo.reserves + newInfo.insurance + _interest(newInfo) ); newInfo.lastAccrual = block.timestamp; newInfo.enteredProvisionalDefault = _entranceOfProvisionalDefault( interestRate ); if ( newInfo.enteredProvisionalDefault != 0 && newInfo.enteredProvisionalDefault + warningGracePeriod < newInfo.lastAccrual ) { newInfo.lastAccrual = newInfo.enteredProvisionalDefault + warningGracePeriod; } uint256 interestDelta = newInfo.borrows.mulDecimal( interestRate * (newInfo.lastAccrual - _info.lastAccrual) ); uint256 reservesDelta = interestDelta.mulDecimal(reserveFactor); uint256 insuranceDelta = interestDelta.mulDecimal(insuranceFactor); if ( newInfo.borrows + interestDelta + reservesDelta + insuranceDelta > _poolSize(newInfo) ) { interestDelta = (_poolSize(newInfo) - newInfo.borrows).divDecimal( Decimal.ONE + reserveFactor + insuranceFactor ); uint256 interestPerSec = newInfo.borrows.mulDecimal(interestRate); if (interestPerSec > 0) { // Previous last accrual plus interest divided by interest speed (rounded up) newInfo.lastAccrual = _info.lastAccrual + (interestDelta + interestPerSec - 1) / interestPerSec; } reservesDelta = interestDelta.mulDecimal(reserveFactor); insuranceDelta = interestDelta.mulDecimal(insuranceFactor); newInfo.state = State.Default; } newInfo.borrows += interestDelta; newInfo.reserves += reservesDelta; newInfo.insurance += insuranceDelta; return newInfo; } // MODIFIERS /** * @notice Modifier to accrue interest and check that pool is currently active (possibly in warning) */ modifier onlyActiveAccrual() { _accrueInterest(); State currentState = _state(_info); require( currentState == State.Active || currentState == State.Warning || currentState == State.ProvisionalDefault, "PIA" ); _; } /** * @notice Modifier for functions restricted to manager */ modifier onlyManager() { require(msg.sender == manager, "OM"); _; } /** * @notice Modifier for functions restricted to protocol governor */ modifier onlyGovernor() { require(msg.sender == factory.owner(), "OG"); _; } /** * @notice Modifier for functions restricted to auction contract */ modifier onlyAuction() { require(msg.sender == factory.auction(), "OA"); _; } /** * @notice Modifier for the functions restricted to factory */ modifier onlyFactory() { require(msg.sender == address(factory), "OF"); _; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; library Decimal { /// @notice Number one as 18-digit decimal uint256 internal constant ONE = 1e18; /** * @notice Internal function for 10-digits decimal division * @param number Integer number * @param decimal Decimal number * @return Returns multiplied numbers */ function mulDecimal(uint256 number, uint256 decimal) internal pure returns (uint256) { return (number * decimal) / ONE; } /** * @notice Internal function for 10-digits decimal multiplication * @param number Integer number * @param decimal Decimal number * @return Returns integer number divided by second */ function divDecimal(uint256 number, uint256 decimal) internal pure returns (uint256) { return (number * ONE) / decimal; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.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 `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, 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 `sender` to `recipient` 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 sender, address recipient, 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (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: MIT pragma solidity 0.8.9; import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol"; import "../interfaces/IPoolFactory.sol"; import "../interfaces/IInterestRateModel.sol"; abstract contract PoolBaseInfo is ERC20Upgradeable { /// @notice Address of the pool's manager address public manager; /// @notice Pool currency token IERC20Upgradeable public currency; /// @notice PoolFactory contract IPoolFactory public factory; /// @notice InterestRateModel contract address IInterestRateModel public interestRateModel; /// @notice Reserve factor as 18-digit decimal uint256 public reserveFactor; /// @notice Insurance factor as 18-digit decimal uint256 public insuranceFactor; /// @notice Pool utilization that leads to warning state (as 18-digit decimal) uint256 public warningUtilization; /// @notice Pool utilization that leads to provisional default (as 18-digit decimal) uint256 public provisionalDefaultUtilization; /// @notice Grace period for warning state before pool goes to default (in seconds) uint256 public warningGracePeriod; /// @notice Max period for which pool can stay not active before it can be closed by governor (in seconds) uint256 public maxInactivePeriod; /// @notice Period after default to start auction after which pool can be closed by anyone (in seconds) uint256 public periodToStartAuction; enum State { Active, Warning, ProvisionalDefault, Default, Closed } /// @notice Indicator if debt has been claimed bool public debtClaimed; struct BorrowInfo { uint256 principal; uint256 borrows; uint256 reserves; uint256 insurance; uint256 lastAccrual; uint256 enteredProvisionalDefault; uint256 enteredZeroUtilization; State state; } /// @notice Last updated borrow info BorrowInfo internal _info; // EVENTS event Closed(); /// @notice Event emitted when liquidity is provided to the Pool event Provided( address indexed provider, uint256 currencyAmount, uint256 tokens ); /// @notice Event emitted when liquidity is redeemed from the Pool event Redeemed( address indexed redeemer, uint256 currencyAmount, uint256 tokens ); /// @notice Event emitted when manager assignes liquidity event Borrowed(uint256 amount, address indexed receiver); /// @notice Event emitted when manager returns liquidity assignment event Repaid(uint256 amount); // CONSTRUCTOR /** * @notice Upgradeable contract constructor * @param manager_ Address of the Pool's manager * @param currency_ Address of the currency token */ function __PoolBaseInfo_init(address manager_, IERC20Upgradeable currency_) internal initializer { require(manager_ != address(0), "AIZ"); require(address(currency_) != address(0), "AIZ"); manager = manager_; currency = currency_; factory = IPoolFactory(msg.sender); interestRateModel = IInterestRateModel(factory.interestRateModel()); reserveFactor = factory.reserveFactor(); insuranceFactor = factory.insuranceFactor(); warningUtilization = factory.warningUtilization(); provisionalDefaultUtilization = factory.provisionalDefaultUtilization(); warningGracePeriod = factory.warningGracePeriod(); maxInactivePeriod = factory.maxInactivePeriod(); periodToStartAuction = factory.periodToStartAuction(); string memory symbol = factory.getPoolSymbol( address(currency), address(manager) ); __ERC20_init( string(bytes.concat(bytes("Pool "), bytes(symbol))), symbol ); _info.enteredZeroUtilization = block.timestamp; _info.lastAccrual = block.timestamp; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IAuction { function bid(address pool, uint256 amount) external; function ownerOfDebt(address pool) external view returns (address); /// @notice States of auction /// @dev None: A pool is not default and auction can't be started /// @dev NotStarted: A pool is default and auction can be started /// @dev Active: An auction is started /// @dev Finished: An auction is finished but NFT is not claimed /// @dev Closed: An auction is finished and NFT is claimed enum State { None, NotStarted, Active, Finished, Closed } function state(address pool) external view returns (State); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/Address.sol) pragma solidity ^0.8.0; /** * @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 * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 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 v4.4.0 (token/ERC20/ERC20.sol) pragma solidity ^0.8.0; import "./IERC20Upgradeable.sol"; import "./extensions/IERC20MetadataUpgradeable.sol"; import "../../utils/ContextUpgradeable.sol"; import "../../proxy/utils/Initializable.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal initializer { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5.05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be transferred to `to`. * - when `from` is zero, `amount` tokens will be minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} uint256[45] private __gap; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IPoolFactory { function getPoolSymbol(address currency, address manager) external view returns (string memory); function isPool(address pool) external view returns (bool); function interestRateModel() external view returns (address); function auction() external view returns (address); function treasury() external view returns (address); function reserveFactor() external view returns (uint256); function insuranceFactor() external view returns (uint256); function warningUtilization() external view returns (uint256); function provisionalDefaultUtilization() external view returns (uint256); function warningGracePeriod() external view returns (uint256); function maxInactivePeriod() external view returns (uint256); function periodToStartAuction() external view returns (uint256); function owner() external view returns (address); function closePool() external; function burnStake() external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IInterestRateModel { function getBorrowRate( uint256 balance, uint256 totalBorrows, uint256 totalReserves ) external view returns (uint256); function utilizationRate( uint256 balance, uint256 borrows, uint256 reserves ) external pure returns (uint256); function getSupplyRate( uint256 balance, uint256 borrows, uint256 reserves, uint256 reserveFactor ) external view returns (uint256); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (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 initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; /** * @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 a proxied contract can't have 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() { require(_initializing || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.0 (utils/math/SafeCast.sol) pragma solidity ^0.8.0; /** * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow * checks. * * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can * easily result in undesired exploitation or bugs, since developers usually * assume that overflows raise errors. `SafeCast` restores this intuition by * reverting the transaction when such an operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. * * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing * all math on `uint256` and `int256` and then downcasting. */ library SafeCastUpgradeable { /** * @dev Returns the downcasted uint224 from uint256, reverting on * overflow (when the input is greater than largest uint224). * * Counterpart to Solidity's `uint224` operator. * * Requirements: * * - input must fit into 224 bits */ function toUint224(uint256 value) internal pure returns (uint224) { require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits"); return uint224(value); } /** * @dev Returns the downcasted uint128 from uint256, reverting on * overflow (when the input is greater than largest uint128). * * Counterpart to Solidity's `uint128` operator. * * Requirements: * * - input must fit into 128 bits */ function toUint128(uint256 value) internal pure returns (uint128) { require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits"); return uint128(value); } /** * @dev Returns the downcasted uint96 from uint256, reverting on * overflow (when the input is greater than largest uint96). * * Counterpart to Solidity's `uint96` operator. * * Requirements: * * - input must fit into 96 bits */ function toUint96(uint256 value) internal pure returns (uint96) { require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits"); return uint96(value); } /** * @dev Returns the downcasted uint64 from uint256, reverting on * overflow (when the input is greater than largest uint64). * * Counterpart to Solidity's `uint64` operator. * * Requirements: * * - input must fit into 64 bits */ function toUint64(uint256 value) internal pure returns (uint64) { require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits"); return uint64(value); } /** * @dev Returns the downcasted uint32 from uint256, reverting on * overflow (when the input is greater than largest uint32). * * Counterpart to Solidity's `uint32` operator. * * Requirements: * * - input must fit into 32 bits */ function toUint32(uint256 value) internal pure returns (uint32) { require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits"); return uint32(value); } /** * @dev Returns the downcasted uint16 from uint256, reverting on * overflow (when the input is greater than largest uint16). * * Counterpart to Solidity's `uint16` operator. * * Requirements: * * - input must fit into 16 bits */ function toUint16(uint256 value) internal pure returns (uint16) { require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits"); return uint16(value); } /** * @dev Returns the downcasted uint8 from uint256, reverting on * overflow (when the input is greater than largest uint8). * * Counterpart to Solidity's `uint8` operator. * * Requirements: * * - input must fit into 8 bits. */ function toUint8(uint256 value) internal pure returns (uint8) { require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits"); return uint8(value); } /** * @dev Converts a signed int256 into an unsigned uint256. * * Requirements: * * - input must be greater than or equal to 0. */ function toUint256(int256 value) internal pure returns (uint256) { require(value >= 0, "SafeCast: value must be positive"); return uint256(value); } /** * @dev Returns the downcasted int128 from int256, reverting on * overflow (when the input is less than smallest int128 or * greater than largest int128). * * Counterpart to Solidity's `int128` operator. * * Requirements: * * - input must fit into 128 bits * * _Available since v3.1._ */ function toInt128(int256 value) internal pure returns (int128) { require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits"); return int128(value); } /** * @dev Returns the downcasted int64 from int256, reverting on * overflow (when the input is less than smallest int64 or * greater than largest int64). * * Counterpart to Solidity's `int64` operator. * * Requirements: * * - input must fit into 64 bits * * _Available since v3.1._ */ function toInt64(int256 value) internal pure returns (int64) { require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits"); return int64(value); } /** * @dev Returns the downcasted int32 from int256, reverting on * overflow (when the input is less than smallest int32 or * greater than largest int32). * * Counterpart to Solidity's `int32` operator. * * Requirements: * * - input must fit into 32 bits * * _Available since v3.1._ */ function toInt32(int256 value) internal pure returns (int32) { require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits"); return int32(value); } /** * @dev Returns the downcasted int16 from int256, reverting on * overflow (when the input is less than smallest int16 or * greater than largest int16). * * Counterpart to Solidity's `int16` operator. * * Requirements: * * - input must fit into 16 bits * * _Available since v3.1._ */ function toInt16(int256 value) internal pure returns (int16) { require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits"); return int16(value); } /** * @dev Returns the downcasted int8 from int256, reverting on * overflow (when the input is less than smallest int8 or * greater than largest int8). * * Counterpart to Solidity's `int8` operator. * * Requirements: * * - input must fit into 8 bits. * * _Available since v3.1._ */ function toInt8(int256 value) internal pure returns (int8) { require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits"); return int8(value); } /** * @dev Converts an unsigned uint256 into a signed int256. * * Requirements: * * - input must be less than or equal to maxInt256. */ function toInt256(uint256 value) internal pure returns (int256) { // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256"); return int256(value); } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"}],"name":"Borrowed","type":"event"},{"anonymous":false,"inputs":[],"name":"Closed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"currencyAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"Provided","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"redeemer","type":"address"},{"indexed":false,"internalType":"uint256","name":"currencyAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"Redeemed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Repaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newRewardPerBlock","type":"uint256"}],"name":"RewardPerBlockSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"RewardWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"accumulativeRewardOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowWithdrawalAfterNoAuction","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"availableToBorrow","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"availableToWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"borrow","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"borrows","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cash","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"close","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currency","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"debtClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enteredProvisionalDefault","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enteredZeroUtilization","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"factory","outputs":[{"internalType":"contract IPoolFactory","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBorrowRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentExchangeRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSupplyRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUtilizationRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"manager_","type":"address"},{"internalType":"contract IERC20Upgradeable","name":"currency_","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"insurance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"insuranceFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"interest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"interestRateModel","outputs":[{"internalType":"contract IInterestRateModel","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastAccrual","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"manager","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxInactivePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ownerOfDebt","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"periodToStartAuction","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"poolSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"principal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"processAuctionStart","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"processDebtClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"currencyAmount","type":"uint256"}],"name":"provide","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"provisionalDefaultUtilization","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokens","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"currencyAmount","type":"uint256"}],"name":"redeemCurrency","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bool","name":"closeNow","type":"bool"}],"name":"repay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveFactor","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserves","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"rewardPerBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"rewardPerBlock_","type":"uint256"}],"name":"setRewardPerBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"state","outputs":[{"internalType":"enum PoolBaseInfo.State","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"transferReserves","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"warningGracePeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"warningUtilization","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"withdrawReward","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"withdrawableRewardOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"withdrawnRewardOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405234801561001057600080fd5b506146b3806100206000396000f3fe608060405234801561001057600080fd5b506004361061038e5760003560e01c8063a457c2d7116101de578063c6c6c2371161010f578063eb81033f116100ad578063fa7fc3d21161007c578063fa7fc3d2146106f1578063fce03d5214610704578063ff3f60e71461070d578063ffbaefb71461071557600080fd5b8063eb81033f146106c6578063ecaf804b146106ce578063f3fdb15a146106d6578063f8fd3100146106e957600080fd5b8063db006a75116100e9578063db006a751461065f578063dd62ed3e14610672578063e322ad2b146106ab578063e5a6b10f146106b357600080fd5b8063c6c6c23714610645578063c6e672c81461064e578063d75146b71461065757600080fd5b8063ba5d30781161017c578063c19d93fb11610156578063c19d93fb1461060d578063c392f76614610622578063c45a01551461062a578063c62757d51461063d57600080fd5b8063ba5d3078146105ea578063bb872b4a146105f2578063c15045ef1461060557600080fd5b8063b4f03369116101b8578063b4f03369146105b4578063b86e321c146105bc578063ba0b3623146105cf578063ba1c5e80146105e257600080fd5b8063a457c2d714610565578063a9059cbb14610578578063ad76d6861461058b57600080fd5b8063485cc955116102c35780637b3baab41161026157806389ddd0ed1161023057806389ddd0ed146105435780638ae39cac1461054c57806395d89b4114610555578063961be3911461055d57600080fd5b80637b3baab4146105225780637f8ee87f1461052a57806384bdc9a81461053357806389cf32041461053b57600080fd5b80634ec18db91161029d5780634ec18db9146104dc57806357f37da5146104e457806370a08231146104f157806375172a8b1461051a57600080fd5b8063485cc955146104ae5780634a417a53146104c15780634b3fd148146104c957600080fd5b80632e2ebe06116103305780633ca967f31161030a5780633ca967f31461046a5780634322b7141461047257806343d726d61461047b578063481c6a751461048357600080fd5b80632e2ebe0614610428578063313ce5671461043d578063395093511461045757600080fd5b80630c70754e1161036c5780630c70754e146103f157806318160ddd1461040457806323b872dd1461040c5780632b08ed541461041f57600080fd5b806305b3ccb41461039357806306fdde03146103b9578063095ea7b3146103ce575b600080fd5b6103a66103a1366004614166565b61071d565b6040519081526020015b60405180910390f35b6103c1610814565b6040516103b091906141af565b6103e16103dc3660046141e2565b6108a6565b60405190151581526020016103b0565b6103a66103ff366004614166565b6108bc565b6035546103a6565b6103e161041a36600461420e565b6108ee565b6103a6606d5481565b61043b61043636600461424f565b61099f565b005b610445610b18565b60405160ff90911681526020016103b0565b6103e16104653660046141e2565b610b27565b6103a6610b63565b6103a660695481565b61043b610bda565b606554610496906001600160a01b031681565b6040516001600160a01b0390911681526020016103b0565b61043b6104bc366004614268565b610d3c565b6103a6610db4565b61043b6104d73660046142a1565b610e84565b6103a6611195565b6070546103e19060ff1681565b6103a66104ff366004614166565b6001600160a01b031660009081526033602052604090205490565b6103a66111a7565b6103a66111ba565b6103a6606e5481565b6103a66111cd565b6103a66112d8565b6103a6606f5481565b6103a660795481565b6103c16112eb565b6103a66112fa565b6103e16105733660046141e2565b611376565b6103e16105863660046141e2565b61140f565b6103a6610599366004614166565b6001600160a01b03166000908152607d602052604090205490565b61043b61141c565b6103a66105ca366004614166565b611630565b61043b6105dd3660046142d4565b611706565b6103a6611966565b6071546103a6565b61043b61060036600461424f565b611a21565b61043b611ab9565b610615611b96565b6040516103b0919061430f565b6103a6611ba8565b606754610496906001600160a01b031681565b6103a6611bba565b6103a6606c5481565b6103a6606b5481565b6077546103a6565b61043b61066d36600461424f565b611bcd565b6103a6610680366004614268565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b6103a6611c17565b606654610496906001600160a01b031681565b61043b611c53565b610496611d98565b606854610496906001600160a01b031681565b6103a6611e8e565b61043b6106ff36600461424f565b611ea0565b6103a6606a5481565b6103a6611ee9565b61043b611efc565b600080610728612024565b607b54607a5491925090158015906107455750607a548260800151115b80156107595750600061075760355490565b115b156107b0576000607a548360800151610772919061434d565b905061077d60355490565b60795461078e83600160801b614364565b6107989190614364565b6107a29190614383565b6107ac90836143a5565b9150505b6001600160a01b0384166000908152607c6020908152604080832054603390925290912054600160801b91610802916107f3906107ee908690614364565b6123bc565b6107fd91906143bd565b61242a565b61080c9190614383565b949350505050565b606060368054610823906143fe565b80601f016020809104026020016040519081016040528092919081815260200182805461084f906143fe565b801561089c5780601f106108715761010080835404028352916020019161089c565b820191906000526020600020905b81548152906001019060200180831161087f57829003601f168201915b5050505050905090565b60006108b333848461247c565b50600192915050565b6001600160a01b0381166000908152607d60205260408120546108de8361071d565b6108e8919061434d565b92915050565b60006108fb8484846125a0565b6001600160a01b0384166000908152603460209081526040808320338452909152902054828110156109855760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b60648201526084015b60405180910390fd5b610992853385840361247c565b60019150505b9392505050565b6109a761276e565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854600092610a27929160e083019060ff166004811115610a0e57610a0e6142f9565b6004811115610a1f57610a1f6142f9565b9052506127d7565b90506000816004811115610a3d57610a3d6142f9565b1480610a5a57506001816004811115610a5857610a586142f9565b145b80610a7657506002816004811115610a7457610a746142f9565b145b610a925760405162461bcd60e51b815260040161097c90614439565b6000610a9c612892565b606654909150610ab7906001600160a01b0316333086612950565b6000610ac384836129bb565b9050610acf33826129da565b610ad76129e8565b604080518581526020810183905233917f9344f1a0460e7d82a14a16b325b7b5f30a0e9aec0f2de30b9ca95066bdc0c27e910160405180910390a250505050565b6000610b22612b24565b905090565b3360008181526034602090815260408083206001600160a01b038716845290915281205490916108b3918590610b5e9086906143a5565b61247c565b6000610b6e60355490565b610b7f5750670de0b6b3a764000090565b60705460ff1615610ba457610b22610b9660355490565b610b9e6112fa565b906129bb565b6000610bae612024565b9050610bd4610bbc60355490565b8260200151610bca84612ba1565b610b9e91906143a5565b91505090565b610be261276e565b60675460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b916004808301926020929190829003018186803b158015610c2757600080fd5b505afa158015610c3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5f9190614456565b90506000610c6b611d98565b607254909150600090158015610c8b57506065546001600160a01b031633145b60775490915060009015801590610cb05750606e54607754610cad91906143a5565b42115b90506000336001600160a01b038616148015610cdb57508180610cdb57506001600160a01b03841615155b9050336001600160a01b038516148380610cf25750815b80610cfa5750805b610d2c5760405162461bcd60e51b815260206004820152600360248201526253434360e81b604482015260640161097c565b610d34612bbf565b505050505050565b600054610100900460ff1680610d55575060005460ff16155b610d715760405162461bcd60e51b815260040161097c90614473565b600054610100900460ff16158015610d93576000805461ffff19166101011790555b610d9d8383612ce3565b8015610daf576000805461ff00191690555b505050565b600080610dbf612024565b6068549091506001600160a01b0316636e71e2d8610ddb6112fa565b8360200151610de9856132ee565b85604001518660600151610dfd91906143a5565b610e0791906143a5565b6040516001600160e01b031960e086901b1681526004810193909352602483019190915260448201526064015b60206040518083038186803b158015610e4c57600080fd5b505afa158015610e60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd491906144c1565b6065546001600160a01b03163314610ec35760405162461bcd60e51b81526020600482015260026024820152614f4d60f01b604482015260640161097c565b610ecb61276e565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854600092610f32929160e083019060ff166004811115610a0e57610a0e6142f9565b90506000816004811115610f4857610f486142f9565b1480610f6557506001816004811115610f6357610f636142f9565b145b80610f8157506002816004811115610f7f57610f7f6142f9565b145b610f9d5760405162461bcd60e51b815260040161097c90614439565b60001983141561102b5760408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854611024929060e083019060ff16600481111561100b5761100b6142f9565b600481111561101c5761101c6142f9565b905250613301565b92506110c4565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c082015260785461108f929060e083019060ff16600481111561100b5761100b6142f9565b8311156110c45760405162461bcd60e51b815260206004820152600360248201526213915360ea1b604482015260640161097c565b600083116110fa5760405162461bcd60e51b815260206004820152600360248201526221a12d60e91b604482015260640161097c565b826071600001600082825461110f91906143a5565b9091555050607280548491906000906111299084906143a5565b9091555050606654611145906001600160a01b03168385613364565b61114d6129e8565b816001600160a01b03167f84d6fc9f7244aba67b2ad2bfc67d8d3ed92b7e4932a482888bac6a4595019a158460405161118891815260200190565b60405180910390a2505050565b6000610b226111a2612024565b613394565b60006111b1612024565b60400151905090565b60006111c4612024565b60800151905090565b6000806111d8612024565b6068546066546040516370a0823160e01b81523060048201529293506001600160a01b039182169263b816881692909116906370a082319060240160206040518083038186803b15801561122b57600080fd5b505afa15801561123f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126391906144c1565b60208401518451611274908261434d565b8560600151866040015161128891906143a5565b61129291906143a5565b606a546069546112a291906143a5565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401610e34565b60006112e2612024565b60600151905090565b606060378054610823906143fe565b6066546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561133e57600080fd5b505afa158015611352573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2291906144c1565b3360009081526034602090815260408083206001600160a01b0386168452909152812054828110156113f85760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161097c565b611405338585840361247c565b5060019392505050565b60006108b33384846125a0565b61142461276e565b6000600360408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c082015260785461148c929060e083019060ff166004811115610a0e57610a0e6142f9565b600481111561149d5761149d6142f9565b14905060006001606760009054906101000a90046001600160a01b03166001600160a01b0316637d9f6db56040518163ffffffff1660e01b815260040160206040518083038186803b1580156114f257600080fd5b505afa158015611506573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152a9190614456565b6040516331e658a560e01b81523060048201526001600160a01b0391909116906331e658a59060240160206040518083038186803b15801561156b57600080fd5b505afa15801561157f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a391906144da565b60048111156115b4576115b46142f9565b1490506000606f546071600401546115cc91906143a5565b42101590508280156115db5750815b80156115e45750805b6116165760405162461bcd60e51b815260206004820152600360248201526243444360e81b604482015260640161097c565b60006074556070805460ff19166001179055610daf612bbf565b6067546000906001600160a01b031633146116725760405162461bcd60e51b815260206004820152600260248201526127a360f11b604482015260640161097c565b61167a61276e565b6116826133ac565b600061168d836108bc565b905080156108e8576001600160a01b0383166000908152607d6020526040812080548392906116bd9084906143a5565b90915550506040518181526001600160a01b038416907f1d3eee4ca001cff39eec6ec7615aacf2f2bd61791273830728ba00ccbd6e13379060200160405180910390a292915050565b6065546001600160a01b031633146117455760405162461bcd60e51b81526020600482015260026024820152614f4d60f01b604482015260640161097c565b61174d61276e565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c08201526078546000926117b4929160e083019060ff166004811115610a0e57610a0e6142f9565b905060008160048111156117ca576117ca6142f9565b14806117e7575060018160048111156117e5576117e56142f9565b145b8061180357506002816004811115611801576118016142f9565b145b61181f5760405162461bcd60e51b815260040161097c90614439565b60001983141561183357607254925061186b565b60725483111561186b5760405162461bcd60e51b815260206004820152600360248201526226aa2160e91b604482015260640161097c565b606654611883906001600160a01b0316333086612950565b607154607254611893919061434d565b8311156118cc576071546072546118aa919061434d565b6118b4908461434d565b607180546000906118c690849061434d565b90915550505b82607160010160008282546118e1919061434d565b909155506118ef90506129e8565b6040518381527f33a382daad6aace935340a474d09fec82af4bec7e2b69518d283231b03a65f249060200160405180910390a18115610daf576072541561195e5760405162461bcd60e51b815260206004820152600360248201526221272d60e91b604482015260640161097c565b610daf612bbf565b600080611971612024565b6068546066546040516370a0823160e01b81523060048201529293506001600160a01b03918216926315f2405392909116906370a082319060240160206040518083038186803b1580156119c457600080fd5b505afa1580156119d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fc91906144c1565b60208401518451611a0d908261434d565b85606001518660400151610dfd91906143a5565b6067546001600160a01b03163314611a605760405162461bcd60e51b815260206004820152600260248201526127a360f11b604482015260640161097c565b611a6861276e565b611a706133ac565b607a54611a7e57607554607a555b60798190556040518181527f5d7c78d0ee3ce6196f90e74ed58c0ada9ac7ccc47d3aca0547ac893776f038269060200160405180910390a150565b606760009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b0757600080fd5b505afa158015611b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3f9190614456565b6001600160a01b0316336001600160a01b031614611b845760405162461bcd60e51b81526020600482015260026024820152614f4760f01b604482015260640161097c565b611b8c61276e565b611b94613449565b565b6000610b22611ba3612024565b6127d7565b6000610b22611bb5612024565b6132ee565b6000611bc4612024565b60a00151905090565b611bd561276e565b6000611bdf612892565b90506000600019831415611c0057611bf6826134e4565b9093509050611c0d565b611c0a8383613634565b90505b610daf8382613649565b60705460009060ff1615611c2d57610b226112fa565b6000611c37612024565b9050610bd4611c4582612ba1565b611c4e83613810565b613867565b606760009054906101000a90046001600160a01b03166001600160a01b0316637d9f6db56040518163ffffffff1660e01b815260040160206040518083038186803b158015611ca157600080fd5b505afa158015611cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd99190614456565b6001600160a01b0316336001600160a01b031614611d1e5760405162461bcd60e51b81526020600482015260026024820152614f4160f01b604482015260640161097c565b611d2661276e565b611d2e613449565b606760009054906101000a90046001600160a01b03166001600160a01b031663206eeb816040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611d7e57600080fd5b505af1158015611d92573d6000803e3d6000fd5b50505050565b60675460408051637d9f6db560e01b815290516000926001600160a01b031691637d9f6db5916004808301926020929190829003018186803b158015611ddd57600080fd5b505afa158015611df1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e159190614456565b604051633b7bf93160e01b81523060048201526001600160a01b039190911690633b7bf9319060240160206040518083038186803b158015611e5657600080fd5b505afa158015611e6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b229190614456565b6000610b22611e9b612024565b613301565b611ea861276e565b6000611eb2612892565b90506000600019831415611ed257611ec9826134e4565b93509050611edf565b611edc83836129bb565b90505b610daf8184613649565b6000611ef3612024565b60200151905090565b606760009054906101000a90046001600160a01b03166001600160a01b0316637d9f6db56040518163ffffffff1660e01b815260040160206040518083038186803b158015611f4a57600080fd5b505afa158015611f5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f829190614456565b6001600160a01b0316336001600160a01b031614611fc75760405162461bcd60e51b81526020600482015260026024820152614f4160f01b604482015260640161097c565b611fcf61276e565b6078805460ff191660031790556000611fe6611d98565b607454909150156120145760745460665461200e916001600160a01b03909116908390613364565b60006074555b506070805460ff19166001179055565b61202c61406c565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c08201526078546000929060e083019060ff16600481111561208f5761208f6142f9565b60048111156120a0576120a06142f9565b81525050905080608001514214806120cd575060038160e0015160048111156120cb576120cb6142f9565b145b806120ed575060048160e0015160048111156120eb576120eb6142f9565b145b156120f757919050565b6068546000906001600160a01b03166315f240536121136112fa565b8460200151612121866132ee565b8660600151876040015161213591906143a5565b61213f91906143a5565b6040516001600160e01b031960e086901b16815260048101939093526024830191909152604482015260640160206040518083038186803b15801561218357600080fd5b505afa158015612197573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121bb91906144c1565b42608084015290506121cc8161387d565b60a08301819052158015906121f557508160800151606d548360a001516121f391906143a5565b105b1561221257606d548260a0015161220c91906143a5565b60808301525b6000612241607160040154846080015161222c919061434d565b6122369084614364565b602085015190613634565b9050600061225a6069548361363490919063ffffffff16565b90506000612273606a548461363490919063ffffffff16565b905061227e85613394565b818385886020015161229091906143a5565b61229a91906143a5565b6122a491906143a5565b111561236f576122e8606a54606954670de0b6b3a76400006122c691906143a5565b6122d091906143a5565b86602001516122de88613394565b610b9e919061434d565b9250600061230385876020015161363490919063ffffffff16565b9050801561233f5780600161231882876143a5565b612322919061434d565b61232c9190614383565b60755461233991906143a5565b60808701525b60695461234d908590613634565b9250612364606a548561363490919063ffffffff16565b600360e08801529150505b828560200181815161238191906143a5565b9052506040850180518391906123989083906143a5565b9052506060850180518291906123af9083906143a5565b9052509395945050505050565b60006001600160ff1b038211156124265760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b606482015260840161097c565b5090565b6000808212156124265760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f736974697665604482015260640161097c565b6001600160a01b0383166124de5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161097c565b6001600160a01b03821661253f5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161097c565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166126045760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161097c565b6001600160a01b0382166126665760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161097c565b6001600160a01b038316600090815260336020526040902054818110156126de5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161097c565b6001600160a01b038085166000908152603360205260408082208585039055918516815290812080548492906127159084906143a5565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161276191815260200190565b60405180910390a3611d92565b612776612024565b80516071908155602082015160725560408201516073556060820151607455608082015160755560a082015160765560c082015160775560e08201516078805460ff191660018360048111156127ce576127ce6142f9565b02179055505050565b600060048260e0015160048111156127f1576127f16142f9565b1480612812575060038260e001516004811115612810576128106142f9565b145b1561281f575060e0015190565b60a08201511561285157606d548260a0015161283b91906143a5565b421061284957506003919050565b506002919050565b6000826020015111801561287d5750612875606b5461286f84613394565b90613634565b826020015110155b1561288a57506001919050565b5060e0015190565b600061289d60355490565b6128ae5750670de0b6b3a764000090565b60705460ff16156128c557610b22610b9660355490565b610b226128d160355490565b607254604080516101008101825260718054825260208201849052607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854610bca929060e083019060ff166004811115612937576129376142f9565b6004811115612948576129486142f9565b905250612ba1565b6040516001600160a01b0380851660248301528316604482015260648101829052611d929085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526139ea565b6000816129d0670de0b6b3a764000085614364565b6109989190614383565b6129e48282613abc565b5050565b607254612a01576000607655607754611b945742607755565b60006077819055606b5460408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260c0810193909352607854612a8d9361286f92909160e083019060ff166004811115612a7457612a746142f9565b6004811115612a8557612a856142f9565b905250613394565b60725410612b1d57607654158015612b125750606c5460408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854612b0c939261286f929160e083019060ff166004811115612a7457612a746142f9565b60725410155b15611b945742607655565b6000607655565b6066546040805163313ce56760e01b815290516000926001600160a01b03169163313ce567916004808301926020929190829003018186803b158015612b6957600080fd5b505afa158015612b7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2291906144fb565b600081606001518260400151612bb56112fa565b6108de919061434d565b600460785460ff166004811115612bd857612bd86142f9565b1415612c0c5760405162461bcd60e51b815260206004820152600360248201526250494360e81b604482015260640161097c565b6078805460ff19166004179055612c21613449565b60745415612c5057606554607454606654612c4a926001600160a01b0391821692911690613364565b60006074555b606760009054906101000a90046001600160a01b03166001600160a01b03166366805de56040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612ca057600080fd5b505af1158015612cb4573d6000803e3d6000fd5b50506040517f1cdde67b72a90f19919ac732a437ac2f7a10fc128d28c2a6e525d89ce5cd9d3a925060009150a1565b600054610100900460ff1680612cfc575060005460ff16155b612d185760405162461bcd60e51b815260040161097c90614473565b600054610100900460ff16158015612d3a576000805461ffff19166101011790555b6001600160a01b038316612d765760405162461bcd60e51b815260206004820152600360248201526220a4ad60e91b604482015260640161097c565b6001600160a01b038216612db25760405162461bcd60e51b815260206004820152600360248201526220a4ad60e91b604482015260640161097c565b606580546001600160a01b03199081166001600160a01b0386811691909117909255606680548216928516929092179091556067805433921682179055604080516379fed8ad60e11b8152905163f3fdb15a91600480820192602092909190829003018186803b158015612e2557600080fd5b505afa158015612e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e5d9190614456565b606880546001600160a01b0319166001600160a01b03928316179055606754604080516310c8adc560e21b815290519190921691634322b714916004808301926020929190829003018186803b158015612eb657600080fd5b505afa158015612eca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eee91906144c1565b60695560675460408051637e701ea960e11b815290516001600160a01b039092169163fce03d5291600480820192602092909190829003018186803b158015612f3657600080fd5b505afa158015612f4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f6e91906144c1565b606a55606754604080516318dcce5960e31b815290516001600160a01b039092169163c6e672c891600480820192602092909190829003018186803b158015612fb657600080fd5b505afa158015612fca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fee91906144c1565b606b556067546040805163c6c6c23760e01b815290516001600160a01b039092169163c6c6c23791600480820192602092909190829003018186803b15801561303657600080fd5b505afa15801561304a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306e91906144c1565b606c5560675460408051630ac23b5560e21b815290516001600160a01b0390921691632b08ed5491600480820192602092909190829003018186803b1580156130b657600080fd5b505afa1580156130ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ee91906144c1565b606d5560675460408051637f8ee87f60e01b815290516001600160a01b0390921691637f8ee87f91600480820192602092909190829003018186803b15801561313657600080fd5b505afa15801561314a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061316e91906144c1565b606e55606754604080516389ddd0ed60e01b815290516001600160a01b03909216916389ddd0ed91600480820192602092909190829003018186803b1580156131b657600080fd5b505afa1580156131ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131ee91906144c1565b606f55606754606654606554604051637af7199f60e11b81526001600160a01b0392831660048201529082166024820152600092919091169063f5ee333e9060440160006040518083038186803b15801561324857600080fd5b505afa15801561325c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132849190810190614534565b90506132ce6040518060400160405280600581526020016402837b7b6160dd1b815250826040516020016132b99291906145d6565b60405160208183030381529060405282613b10565b504260778190556075558015610daf576000805461ff0019169055505050565b805160208201516000916108e89161434d565b60008061330d836132ee565b61331684612ba1565b613320919061434d565b90506000613333606b5461286f86613394565b9050836020015181111561335a5761080c846020015182613354919061434d565b83613867565b5060009392505050565b6040516001600160a01b038316602482015260448101829052610daf90849063a9059cbb60e01b90606401612984565b80516000906133a283612ba1565b6108e891906143a5565b60006079541180156133bf5750607a5415155b80156133ce5750607a54607554115b80156133e2575060006133e060355490565b115b1561344157607a546075546000916133f99161434d565b905061340460355490565b60795461341583600160801b614364565b61341f9190614364565b6134299190614383565b607b600082825461343a91906143a5565b9091555050505b607554607a55565b606754604080516361d027b360e01b815290516134dd926001600160a01b0316916361d027b3916004808301926020929190829003018186803b15801561348f57600080fd5b505afa1580156134a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c79190614456565b6073546066546001600160a01b03169190613364565b6000607355565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854600092839261354f9290919060e083019060ff166004811115612937576129376142f9565b60705490915060ff166135ec5760408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c08201526078546000926135dc929160e083019060ff1660048111156135c3576135c36142f9565b60048111156135d4576135d46142f9565b905250613810565b9050818110156135ea578091505b505b6135f681846129bb565b3360009081526033602052604090205490925082111561362f5733600090815260336020526040902054915061362c8284613634565b90505b915091565b6000670de0b6b3a76400006129d08385614364565b60705460ff16156136965761365c6112fa565b8111156136915760405162461bcd60e51b81526020600482015260036024820152624e454360e81b604482015260640161097c565b61379e565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c08201526078546136fa929060e083019060ff166004811115612937576129376142f9565b811115801561376c575060408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854613768929060e083019060ff1660048111156135c3576135c36142f9565b8111155b61379e5760405162461bcd60e51b81526020600482015260036024820152624e454360e81b604482015260640161097c565b6137a83383613b79565b6066546137bf906001600160a01b03163383613364565b60705460ff166137d1576137d16129e8565b604080518281526020810184905233917ff3a670cd3af7d64b488926880889d08a8585a138ff455227af6737339a1ec262910160405180910390a25050565b6000606c546000141561382557506000919050565b6000613840606c5484602001516129bb90919063ffffffff16565b9050600061384d84613394565b905081811161385d57600061080c565b61080c828261434d565b60008183106138765781610998565b5090919050565b6076546000901561389057505060765490565b607254158061389d575081155b156138aa57506000919050565b607254606c54604080516101008101825260718054825260208201859052607354928201929092526074546060820152607554608082015260765460a082015260775460c08201526078546000949361391f93909261286f9290919060e083019060ff166004811115612a7457612a746142f9565b613929919061434d565b90506000613949606a5460695461394091906143a5565b606c5490613634565b61395b90670de0b6b3a76400006143a5565b9050600061396983836129bb565b905060008560716001015461397e9190614364565b9050600081600181613998670de0b6b3a764000087614364565b6139a291906143a5565b6139ac919061434d565b6139b69190614383565b90506000816071600401546139cb91906143a5565b9050428111156139dc5760006139de565b805b98975050505050505050565b6000613a3f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613b839092919063ffffffff16565b805190915015610daf5780806020019051810190613a5d9190614605565b610daf5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161097c565b613ac46133ac565b613ace8282613b92565b613adf81607b546107ee9190614364565b6001600160a01b0383166000908152607c602052604081208054909190613b07908490614622565b90915550505050565b600054610100900460ff1680613b29575060005460ff16155b613b455760405162461bcd60e51b815260040161097c90614473565b600054610100900460ff16158015613b67576000805461ffff19166101011790555b613b6f613c71565b610d9d8383613cdd565b6129e48282613d72565b606061080c8484600085613dbd565b6001600160a01b038216613be85760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161097c565b8060356000828254613bfa91906143a5565b90915550506001600160a01b03821660009081526033602052604081208054839290613c279084906143a5565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600054610100900460ff1680613c8a575060005460ff16155b613ca65760405162461bcd60e51b815260040161097c90614473565b600054610100900460ff16158015613cc8576000805461ffff19166101011790555b8015613cda576000805461ff00191690555b50565b600054610100900460ff1680613cf6575060005460ff16155b613d125760405162461bcd60e51b815260040161097c90614473565b600054610100900460ff16158015613d34576000805461ffff19166101011790555b8251613d479060369060208601906140c1565b508151613d5b9060379060208501906140c1565b508015610daf576000805461ff0019169055505050565b613d7a6133ac565b613d848282613ee5565b613d9581607b546107ee9190614364565b6001600160a01b0383166000908152607c602052604081208054909190613b079084906143bd565b606082471015613e1e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161097c565b843b613e6c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161097c565b600080866001600160a01b03168587604051613e889190614661565b60006040518083038185875af1925050503d8060008114613ec5576040519150601f19603f3d011682016040523d82523d6000602084013e613eca565b606091505b5091509150613eda828286614033565b979650505050505050565b6001600160a01b038216613f455760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161097c565b6001600160a01b03821660009081526033602052604090205481811015613fb95760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161097c565b6001600160a01b0383166000908152603360205260408120838303905560358054849290613fe890849061434d565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60608315614042575081610998565b8251156140525782518084602001fd5b8160405162461bcd60e51b815260040161097c91906141af565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600060048111156140bc576140bc6142f9565b905290565b8280546140cd906143fe565b90600052602060002090601f0160209004810192826140ef5760008555614135565b82601f1061410857805160ff1916838001178555614135565b82800160010185558215614135579182015b8281111561413557825182559160200191906001019061411a565b506124269291505b80821115612426576000815560010161413d565b6001600160a01b0381168114613cda57600080fd5b60006020828403121561417857600080fd5b813561099881614151565b60005b8381101561419e578181015183820152602001614186565b83811115611d925750506000910152565b60208152600082518060208401526141ce816040850160208701614183565b601f01601f19169190910160400192915050565b600080604083850312156141f557600080fd5b823561420081614151565b946020939093013593505050565b60008060006060848603121561422357600080fd5b833561422e81614151565b9250602084013561423e81614151565b929592945050506040919091013590565b60006020828403121561426157600080fd5b5035919050565b6000806040838503121561427b57600080fd5b823561428681614151565b9150602083013561429681614151565b809150509250929050565b600080604083850312156142b457600080fd5b82359150602083013561429681614151565b8015158114613cda57600080fd5b600080604083850312156142e757600080fd5b823591506020830135614296816142c6565b634e487b7160e01b600052602160045260246000fd5b602081016005831061433157634e487b7160e01b600052602160045260246000fd5b91905290565b634e487b7160e01b600052601160045260246000fd5b60008282101561435f5761435f614337565b500390565b600081600019048311821515161561437e5761437e614337565b500290565b6000826143a057634e487b7160e01b600052601260045260246000fd5b500490565b600082198211156143b8576143b8614337565b500190565b600080821280156001600160ff1b03849003851316156143df576143df614337565b600160ff1b83900384128116156143f8576143f8614337565b50500190565b600181811c9082168061441257607f821691505b6020821081141561443357634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526003908201526250494160e81b604082015260600190565b60006020828403121561446857600080fd5b815161099881614151565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6000602082840312156144d357600080fd5b5051919050565b6000602082840312156144ec57600080fd5b81516005811061099857600080fd5b60006020828403121561450d57600080fd5b815160ff8116811461099857600080fd5b634e487b7160e01b600052604160045260246000fd5b60006020828403121561454657600080fd5b815167ffffffffffffffff8082111561455e57600080fd5b818401915084601f83011261457257600080fd5b8151818111156145845761458461451e565b604051601f8201601f19908116603f011681019083821181831017156145ac576145ac61451e565b816040528281528760208487010111156145c557600080fd5b613eda836020830160208801614183565b600083516145e8818460208801614183565b8351908301906145fc818360208801614183565b01949350505050565b60006020828403121561461757600080fd5b8151610998816142c6565b60008083128015600160ff1b85018412161561464057614640614337565b6001600160ff1b038401831381161561465b5761465b614337565b50500390565b60008251614673818460208701614183565b919091019291505056fea264697066735822122093a57775e0847a8145d6c0e8ad47e948bcc7899ff99c5a42fd8a2671167d610264736f6c63430008090033
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061038e5760003560e01c8063a457c2d7116101de578063c6c6c2371161010f578063eb81033f116100ad578063fa7fc3d21161007c578063fa7fc3d2146106f1578063fce03d5214610704578063ff3f60e71461070d578063ffbaefb71461071557600080fd5b8063eb81033f146106c6578063ecaf804b146106ce578063f3fdb15a146106d6578063f8fd3100146106e957600080fd5b8063db006a75116100e9578063db006a751461065f578063dd62ed3e14610672578063e322ad2b146106ab578063e5a6b10f146106b357600080fd5b8063c6c6c23714610645578063c6e672c81461064e578063d75146b71461065757600080fd5b8063ba5d30781161017c578063c19d93fb11610156578063c19d93fb1461060d578063c392f76614610622578063c45a01551461062a578063c62757d51461063d57600080fd5b8063ba5d3078146105ea578063bb872b4a146105f2578063c15045ef1461060557600080fd5b8063b4f03369116101b8578063b4f03369146105b4578063b86e321c146105bc578063ba0b3623146105cf578063ba1c5e80146105e257600080fd5b8063a457c2d714610565578063a9059cbb14610578578063ad76d6861461058b57600080fd5b8063485cc955116102c35780637b3baab41161026157806389ddd0ed1161023057806389ddd0ed146105435780638ae39cac1461054c57806395d89b4114610555578063961be3911461055d57600080fd5b80637b3baab4146105225780637f8ee87f1461052a57806384bdc9a81461053357806389cf32041461053b57600080fd5b80634ec18db91161029d5780634ec18db9146104dc57806357f37da5146104e457806370a08231146104f157806375172a8b1461051a57600080fd5b8063485cc955146104ae5780634a417a53146104c15780634b3fd148146104c957600080fd5b80632e2ebe06116103305780633ca967f31161030a5780633ca967f31461046a5780634322b7141461047257806343d726d61461047b578063481c6a751461048357600080fd5b80632e2ebe0614610428578063313ce5671461043d578063395093511461045757600080fd5b80630c70754e1161036c5780630c70754e146103f157806318160ddd1461040457806323b872dd1461040c5780632b08ed541461041f57600080fd5b806305b3ccb41461039357806306fdde03146103b9578063095ea7b3146103ce575b600080fd5b6103a66103a1366004614166565b61071d565b6040519081526020015b60405180910390f35b6103c1610814565b6040516103b091906141af565b6103e16103dc3660046141e2565b6108a6565b60405190151581526020016103b0565b6103a66103ff366004614166565b6108bc565b6035546103a6565b6103e161041a36600461420e565b6108ee565b6103a6606d5481565b61043b61043636600461424f565b61099f565b005b610445610b18565b60405160ff90911681526020016103b0565b6103e16104653660046141e2565b610b27565b6103a6610b63565b6103a660695481565b61043b610bda565b606554610496906001600160a01b031681565b6040516001600160a01b0390911681526020016103b0565b61043b6104bc366004614268565b610d3c565b6103a6610db4565b61043b6104d73660046142a1565b610e84565b6103a6611195565b6070546103e19060ff1681565b6103a66104ff366004614166565b6001600160a01b031660009081526033602052604090205490565b6103a66111a7565b6103a66111ba565b6103a6606e5481565b6103a66111cd565b6103a66112d8565b6103a6606f5481565b6103a660795481565b6103c16112eb565b6103a66112fa565b6103e16105733660046141e2565b611376565b6103e16105863660046141e2565b61140f565b6103a6610599366004614166565b6001600160a01b03166000908152607d602052604090205490565b61043b61141c565b6103a66105ca366004614166565b611630565b61043b6105dd3660046142d4565b611706565b6103a6611966565b6071546103a6565b61043b61060036600461424f565b611a21565b61043b611ab9565b610615611b96565b6040516103b0919061430f565b6103a6611ba8565b606754610496906001600160a01b031681565b6103a6611bba565b6103a6606c5481565b6103a6606b5481565b6077546103a6565b61043b61066d36600461424f565b611bcd565b6103a6610680366004614268565b6001600160a01b03918216600090815260346020908152604080832093909416825291909152205490565b6103a6611c17565b606654610496906001600160a01b031681565b61043b611c53565b610496611d98565b606854610496906001600160a01b031681565b6103a6611e8e565b61043b6106ff36600461424f565b611ea0565b6103a6606a5481565b6103a6611ee9565b61043b611efc565b600080610728612024565b607b54607a5491925090158015906107455750607a548260800151115b80156107595750600061075760355490565b115b156107b0576000607a548360800151610772919061434d565b905061077d60355490565b60795461078e83600160801b614364565b6107989190614364565b6107a29190614383565b6107ac90836143a5565b9150505b6001600160a01b0384166000908152607c6020908152604080832054603390925290912054600160801b91610802916107f3906107ee908690614364565b6123bc565b6107fd91906143bd565b61242a565b61080c9190614383565b949350505050565b606060368054610823906143fe565b80601f016020809104026020016040519081016040528092919081815260200182805461084f906143fe565b801561089c5780601f106108715761010080835404028352916020019161089c565b820191906000526020600020905b81548152906001019060200180831161087f57829003601f168201915b5050505050905090565b60006108b333848461247c565b50600192915050565b6001600160a01b0381166000908152607d60205260408120546108de8361071d565b6108e8919061434d565b92915050565b60006108fb8484846125a0565b6001600160a01b0384166000908152603460209081526040808320338452909152902054828110156109855760405162461bcd60e51b815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e74206578636565647320616044820152676c6c6f77616e636560c01b60648201526084015b60405180910390fd5b610992853385840361247c565b60019150505b9392505050565b6109a761276e565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854600092610a27929160e083019060ff166004811115610a0e57610a0e6142f9565b6004811115610a1f57610a1f6142f9565b9052506127d7565b90506000816004811115610a3d57610a3d6142f9565b1480610a5a57506001816004811115610a5857610a586142f9565b145b80610a7657506002816004811115610a7457610a746142f9565b145b610a925760405162461bcd60e51b815260040161097c90614439565b6000610a9c612892565b606654909150610ab7906001600160a01b0316333086612950565b6000610ac384836129bb565b9050610acf33826129da565b610ad76129e8565b604080518581526020810183905233917f9344f1a0460e7d82a14a16b325b7b5f30a0e9aec0f2de30b9ca95066bdc0c27e910160405180910390a250505050565b6000610b22612b24565b905090565b3360008181526034602090815260408083206001600160a01b038716845290915281205490916108b3918590610b5e9086906143a5565b61247c565b6000610b6e60355490565b610b7f5750670de0b6b3a764000090565b60705460ff1615610ba457610b22610b9660355490565b610b9e6112fa565b906129bb565b6000610bae612024565b9050610bd4610bbc60355490565b8260200151610bca84612ba1565b610b9e91906143a5565b91505090565b610be261276e565b60675460408051638da5cb5b60e01b815290516000926001600160a01b031691638da5cb5b916004808301926020929190829003018186803b158015610c2757600080fd5b505afa158015610c3b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c5f9190614456565b90506000610c6b611d98565b607254909150600090158015610c8b57506065546001600160a01b031633145b60775490915060009015801590610cb05750606e54607754610cad91906143a5565b42115b90506000336001600160a01b038616148015610cdb57508180610cdb57506001600160a01b03841615155b9050336001600160a01b038516148380610cf25750815b80610cfa5750805b610d2c5760405162461bcd60e51b815260206004820152600360248201526253434360e81b604482015260640161097c565b610d34612bbf565b505050505050565b600054610100900460ff1680610d55575060005460ff16155b610d715760405162461bcd60e51b815260040161097c90614473565b600054610100900460ff16158015610d93576000805461ffff19166101011790555b610d9d8383612ce3565b8015610daf576000805461ff00191690555b505050565b600080610dbf612024565b6068549091506001600160a01b0316636e71e2d8610ddb6112fa565b8360200151610de9856132ee565b85604001518660600151610dfd91906143a5565b610e0791906143a5565b6040516001600160e01b031960e086901b1681526004810193909352602483019190915260448201526064015b60206040518083038186803b158015610e4c57600080fd5b505afa158015610e60573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bd491906144c1565b6065546001600160a01b03163314610ec35760405162461bcd60e51b81526020600482015260026024820152614f4d60f01b604482015260640161097c565b610ecb61276e565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854600092610f32929160e083019060ff166004811115610a0e57610a0e6142f9565b90506000816004811115610f4857610f486142f9565b1480610f6557506001816004811115610f6357610f636142f9565b145b80610f8157506002816004811115610f7f57610f7f6142f9565b145b610f9d5760405162461bcd60e51b815260040161097c90614439565b60001983141561102b5760408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854611024929060e083019060ff16600481111561100b5761100b6142f9565b600481111561101c5761101c6142f9565b905250613301565b92506110c4565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c082015260785461108f929060e083019060ff16600481111561100b5761100b6142f9565b8311156110c45760405162461bcd60e51b815260206004820152600360248201526213915360ea1b604482015260640161097c565b600083116110fa5760405162461bcd60e51b815260206004820152600360248201526221a12d60e91b604482015260640161097c565b826071600001600082825461110f91906143a5565b9091555050607280548491906000906111299084906143a5565b9091555050606654611145906001600160a01b03168385613364565b61114d6129e8565b816001600160a01b03167f84d6fc9f7244aba67b2ad2bfc67d8d3ed92b7e4932a482888bac6a4595019a158460405161118891815260200190565b60405180910390a2505050565b6000610b226111a2612024565b613394565b60006111b1612024565b60400151905090565b60006111c4612024565b60800151905090565b6000806111d8612024565b6068546066546040516370a0823160e01b81523060048201529293506001600160a01b039182169263b816881692909116906370a082319060240160206040518083038186803b15801561122b57600080fd5b505afa15801561123f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061126391906144c1565b60208401518451611274908261434d565b8560600151866040015161128891906143a5565b61129291906143a5565b606a546069546112a291906143a5565b6040516001600160e01b031960e087901b1681526004810194909452602484019290925260448301526064820152608401610e34565b60006112e2612024565b60600151905090565b606060378054610823906143fe565b6066546040516370a0823160e01b81523060048201526000916001600160a01b0316906370a082319060240160206040518083038186803b15801561133e57600080fd5b505afa158015611352573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2291906144c1565b3360009081526034602090815260408083206001600160a01b0386168452909152812054828110156113f85760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f77604482015264207a65726f60d81b606482015260840161097c565b611405338585840361247c565b5060019392505050565b60006108b33384846125a0565b61142461276e565b6000600360408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c082015260785461148c929060e083019060ff166004811115610a0e57610a0e6142f9565b600481111561149d5761149d6142f9565b14905060006001606760009054906101000a90046001600160a01b03166001600160a01b0316637d9f6db56040518163ffffffff1660e01b815260040160206040518083038186803b1580156114f257600080fd5b505afa158015611506573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061152a9190614456565b6040516331e658a560e01b81523060048201526001600160a01b0391909116906331e658a59060240160206040518083038186803b15801561156b57600080fd5b505afa15801561157f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115a391906144da565b60048111156115b4576115b46142f9565b1490506000606f546071600401546115cc91906143a5565b42101590508280156115db5750815b80156115e45750805b6116165760405162461bcd60e51b815260206004820152600360248201526243444360e81b604482015260640161097c565b60006074556070805460ff19166001179055610daf612bbf565b6067546000906001600160a01b031633146116725760405162461bcd60e51b815260206004820152600260248201526127a360f11b604482015260640161097c565b61167a61276e565b6116826133ac565b600061168d836108bc565b905080156108e8576001600160a01b0383166000908152607d6020526040812080548392906116bd9084906143a5565b90915550506040518181526001600160a01b038416907f1d3eee4ca001cff39eec6ec7615aacf2f2bd61791273830728ba00ccbd6e13379060200160405180910390a292915050565b6065546001600160a01b031633146117455760405162461bcd60e51b81526020600482015260026024820152614f4d60f01b604482015260640161097c565b61174d61276e565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c08201526078546000926117b4929160e083019060ff166004811115610a0e57610a0e6142f9565b905060008160048111156117ca576117ca6142f9565b14806117e7575060018160048111156117e5576117e56142f9565b145b8061180357506002816004811115611801576118016142f9565b145b61181f5760405162461bcd60e51b815260040161097c90614439565b60001983141561183357607254925061186b565b60725483111561186b5760405162461bcd60e51b815260206004820152600360248201526226aa2160e91b604482015260640161097c565b606654611883906001600160a01b0316333086612950565b607154607254611893919061434d565b8311156118cc576071546072546118aa919061434d565b6118b4908461434d565b607180546000906118c690849061434d565b90915550505b82607160010160008282546118e1919061434d565b909155506118ef90506129e8565b6040518381527f33a382daad6aace935340a474d09fec82af4bec7e2b69518d283231b03a65f249060200160405180910390a18115610daf576072541561195e5760405162461bcd60e51b815260206004820152600360248201526221272d60e91b604482015260640161097c565b610daf612bbf565b600080611971612024565b6068546066546040516370a0823160e01b81523060048201529293506001600160a01b03918216926315f2405392909116906370a082319060240160206040518083038186803b1580156119c457600080fd5b505afa1580156119d8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119fc91906144c1565b60208401518451611a0d908261434d565b85606001518660400151610dfd91906143a5565b6067546001600160a01b03163314611a605760405162461bcd60e51b815260206004820152600260248201526127a360f11b604482015260640161097c565b611a6861276e565b611a706133ac565b607a54611a7e57607554607a555b60798190556040518181527f5d7c78d0ee3ce6196f90e74ed58c0ada9ac7ccc47d3aca0547ac893776f038269060200160405180910390a150565b606760009054906101000a90046001600160a01b03166001600160a01b0316638da5cb5b6040518163ffffffff1660e01b815260040160206040518083038186803b158015611b0757600080fd5b505afa158015611b1b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b3f9190614456565b6001600160a01b0316336001600160a01b031614611b845760405162461bcd60e51b81526020600482015260026024820152614f4760f01b604482015260640161097c565b611b8c61276e565b611b94613449565b565b6000610b22611ba3612024565b6127d7565b6000610b22611bb5612024565b6132ee565b6000611bc4612024565b60a00151905090565b611bd561276e565b6000611bdf612892565b90506000600019831415611c0057611bf6826134e4565b9093509050611c0d565b611c0a8383613634565b90505b610daf8382613649565b60705460009060ff1615611c2d57610b226112fa565b6000611c37612024565b9050610bd4611c4582612ba1565b611c4e83613810565b613867565b606760009054906101000a90046001600160a01b03166001600160a01b0316637d9f6db56040518163ffffffff1660e01b815260040160206040518083038186803b158015611ca157600080fd5b505afa158015611cb5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cd99190614456565b6001600160a01b0316336001600160a01b031614611d1e5760405162461bcd60e51b81526020600482015260026024820152614f4160f01b604482015260640161097c565b611d2661276e565b611d2e613449565b606760009054906101000a90046001600160a01b03166001600160a01b031663206eeb816040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611d7e57600080fd5b505af1158015611d92573d6000803e3d6000fd5b50505050565b60675460408051637d9f6db560e01b815290516000926001600160a01b031691637d9f6db5916004808301926020929190829003018186803b158015611ddd57600080fd5b505afa158015611df1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e159190614456565b604051633b7bf93160e01b81523060048201526001600160a01b039190911690633b7bf9319060240160206040518083038186803b158015611e5657600080fd5b505afa158015611e6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b229190614456565b6000610b22611e9b612024565b613301565b611ea861276e565b6000611eb2612892565b90506000600019831415611ed257611ec9826134e4565b93509050611edf565b611edc83836129bb565b90505b610daf8184613649565b6000611ef3612024565b60200151905090565b606760009054906101000a90046001600160a01b03166001600160a01b0316637d9f6db56040518163ffffffff1660e01b815260040160206040518083038186803b158015611f4a57600080fd5b505afa158015611f5e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f829190614456565b6001600160a01b0316336001600160a01b031614611fc75760405162461bcd60e51b81526020600482015260026024820152614f4160f01b604482015260640161097c565b611fcf61276e565b6078805460ff191660031790556000611fe6611d98565b607454909150156120145760745460665461200e916001600160a01b03909116908390613364565b60006074555b506070805460ff19166001179055565b61202c61406c565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c08201526078546000929060e083019060ff16600481111561208f5761208f6142f9565b60048111156120a0576120a06142f9565b81525050905080608001514214806120cd575060038160e0015160048111156120cb576120cb6142f9565b145b806120ed575060048160e0015160048111156120eb576120eb6142f9565b145b156120f757919050565b6068546000906001600160a01b03166315f240536121136112fa565b8460200151612121866132ee565b8660600151876040015161213591906143a5565b61213f91906143a5565b6040516001600160e01b031960e086901b16815260048101939093526024830191909152604482015260640160206040518083038186803b15801561218357600080fd5b505afa158015612197573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121bb91906144c1565b42608084015290506121cc8161387d565b60a08301819052158015906121f557508160800151606d548360a001516121f391906143a5565b105b1561221257606d548260a0015161220c91906143a5565b60808301525b6000612241607160040154846080015161222c919061434d565b6122369084614364565b602085015190613634565b9050600061225a6069548361363490919063ffffffff16565b90506000612273606a548461363490919063ffffffff16565b905061227e85613394565b818385886020015161229091906143a5565b61229a91906143a5565b6122a491906143a5565b111561236f576122e8606a54606954670de0b6b3a76400006122c691906143a5565b6122d091906143a5565b86602001516122de88613394565b610b9e919061434d565b9250600061230385876020015161363490919063ffffffff16565b9050801561233f5780600161231882876143a5565b612322919061434d565b61232c9190614383565b60755461233991906143a5565b60808701525b60695461234d908590613634565b9250612364606a548561363490919063ffffffff16565b600360e08801529150505b828560200181815161238191906143a5565b9052506040850180518391906123989083906143a5565b9052506060850180518291906123af9083906143a5565b9052509395945050505050565b60006001600160ff1b038211156124265760405162461bcd60e51b815260206004820152602860248201527f53616665436173743a2076616c756520646f65736e27742066697420696e2061604482015267371034b73a191a9b60c11b606482015260840161097c565b5090565b6000808212156124265760405162461bcd60e51b815260206004820181905260248201527f53616665436173743a2076616c7565206d75737420626520706f736974697665604482015260640161097c565b6001600160a01b0383166124de5760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b606482015260840161097c565b6001600160a01b03821661253f5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b606482015260840161097c565b6001600160a01b0383811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b0383166126045760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b606482015260840161097c565b6001600160a01b0382166126665760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b606482015260840161097c565b6001600160a01b038316600090815260336020526040902054818110156126de5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604482015265616c616e636560d01b606482015260840161097c565b6001600160a01b038085166000908152603360205260408082208585039055918516815290812080548492906127159084906143a5565b92505081905550826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161276191815260200190565b60405180910390a3611d92565b612776612024565b80516071908155602082015160725560408201516073556060820151607455608082015160755560a082015160765560c082015160775560e08201516078805460ff191660018360048111156127ce576127ce6142f9565b02179055505050565b600060048260e0015160048111156127f1576127f16142f9565b1480612812575060038260e001516004811115612810576128106142f9565b145b1561281f575060e0015190565b60a08201511561285157606d548260a0015161283b91906143a5565b421061284957506003919050565b506002919050565b6000826020015111801561287d5750612875606b5461286f84613394565b90613634565b826020015110155b1561288a57506001919050565b5060e0015190565b600061289d60355490565b6128ae5750670de0b6b3a764000090565b60705460ff16156128c557610b22610b9660355490565b610b226128d160355490565b607254604080516101008101825260718054825260208201849052607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854610bca929060e083019060ff166004811115612937576129376142f9565b6004811115612948576129486142f9565b905250612ba1565b6040516001600160a01b0380851660248301528316604482015260648101829052611d929085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526139ea565b6000816129d0670de0b6b3a764000085614364565b6109989190614383565b6129e48282613abc565b5050565b607254612a01576000607655607754611b945742607755565b60006077819055606b5460408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260c0810193909352607854612a8d9361286f92909160e083019060ff166004811115612a7457612a746142f9565b6004811115612a8557612a856142f9565b905250613394565b60725410612b1d57607654158015612b125750606c5460408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854612b0c939261286f929160e083019060ff166004811115612a7457612a746142f9565b60725410155b15611b945742607655565b6000607655565b6066546040805163313ce56760e01b815290516000926001600160a01b03169163313ce567916004808301926020929190829003018186803b158015612b6957600080fd5b505afa158015612b7d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b2291906144fb565b600081606001518260400151612bb56112fa565b6108de919061434d565b600460785460ff166004811115612bd857612bd86142f9565b1415612c0c5760405162461bcd60e51b815260206004820152600360248201526250494360e81b604482015260640161097c565b6078805460ff19166004179055612c21613449565b60745415612c5057606554607454606654612c4a926001600160a01b0391821692911690613364565b60006074555b606760009054906101000a90046001600160a01b03166001600160a01b03166366805de56040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612ca057600080fd5b505af1158015612cb4573d6000803e3d6000fd5b50506040517f1cdde67b72a90f19919ac732a437ac2f7a10fc128d28c2a6e525d89ce5cd9d3a925060009150a1565b600054610100900460ff1680612cfc575060005460ff16155b612d185760405162461bcd60e51b815260040161097c90614473565b600054610100900460ff16158015612d3a576000805461ffff19166101011790555b6001600160a01b038316612d765760405162461bcd60e51b815260206004820152600360248201526220a4ad60e91b604482015260640161097c565b6001600160a01b038216612db25760405162461bcd60e51b815260206004820152600360248201526220a4ad60e91b604482015260640161097c565b606580546001600160a01b03199081166001600160a01b0386811691909117909255606680548216928516929092179091556067805433921682179055604080516379fed8ad60e11b8152905163f3fdb15a91600480820192602092909190829003018186803b158015612e2557600080fd5b505afa158015612e39573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e5d9190614456565b606880546001600160a01b0319166001600160a01b03928316179055606754604080516310c8adc560e21b815290519190921691634322b714916004808301926020929190829003018186803b158015612eb657600080fd5b505afa158015612eca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612eee91906144c1565b60695560675460408051637e701ea960e11b815290516001600160a01b039092169163fce03d5291600480820192602092909190829003018186803b158015612f3657600080fd5b505afa158015612f4a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f6e91906144c1565b606a55606754604080516318dcce5960e31b815290516001600160a01b039092169163c6e672c891600480820192602092909190829003018186803b158015612fb657600080fd5b505afa158015612fca573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fee91906144c1565b606b556067546040805163c6c6c23760e01b815290516001600160a01b039092169163c6c6c23791600480820192602092909190829003018186803b15801561303657600080fd5b505afa15801561304a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061306e91906144c1565b606c5560675460408051630ac23b5560e21b815290516001600160a01b0390921691632b08ed5491600480820192602092909190829003018186803b1580156130b657600080fd5b505afa1580156130ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130ee91906144c1565b606d5560675460408051637f8ee87f60e01b815290516001600160a01b0390921691637f8ee87f91600480820192602092909190829003018186803b15801561313657600080fd5b505afa15801561314a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061316e91906144c1565b606e55606754604080516389ddd0ed60e01b815290516001600160a01b03909216916389ddd0ed91600480820192602092909190829003018186803b1580156131b657600080fd5b505afa1580156131ca573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906131ee91906144c1565b606f55606754606654606554604051637af7199f60e11b81526001600160a01b0392831660048201529082166024820152600092919091169063f5ee333e9060440160006040518083038186803b15801561324857600080fd5b505afa15801561325c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526132849190810190614534565b90506132ce6040518060400160405280600581526020016402837b7b6160dd1b815250826040516020016132b99291906145d6565b60405160208183030381529060405282613b10565b504260778190556075558015610daf576000805461ff0019169055505050565b805160208201516000916108e89161434d565b60008061330d836132ee565b61331684612ba1565b613320919061434d565b90506000613333606b5461286f86613394565b9050836020015181111561335a5761080c846020015182613354919061434d565b83613867565b5060009392505050565b6040516001600160a01b038316602482015260448101829052610daf90849063a9059cbb60e01b90606401612984565b80516000906133a283612ba1565b6108e891906143a5565b60006079541180156133bf5750607a5415155b80156133ce5750607a54607554115b80156133e2575060006133e060355490565b115b1561344157607a546075546000916133f99161434d565b905061340460355490565b60795461341583600160801b614364565b61341f9190614364565b6134299190614383565b607b600082825461343a91906143a5565b9091555050505b607554607a55565b606754604080516361d027b360e01b815290516134dd926001600160a01b0316916361d027b3916004808301926020929190829003018186803b15801561348f57600080fd5b505afa1580156134a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134c79190614456565b6073546066546001600160a01b03169190613364565b6000607355565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854600092839261354f9290919060e083019060ff166004811115612937576129376142f9565b60705490915060ff166135ec5760408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c08201526078546000926135dc929160e083019060ff1660048111156135c3576135c36142f9565b60048111156135d4576135d46142f9565b905250613810565b9050818110156135ea578091505b505b6135f681846129bb565b3360009081526033602052604090205490925082111561362f5733600090815260336020526040902054915061362c8284613634565b90505b915091565b6000670de0b6b3a76400006129d08385614364565b60705460ff16156136965761365c6112fa565b8111156136915760405162461bcd60e51b81526020600482015260036024820152624e454360e81b604482015260640161097c565b61379e565b60408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c08201526078546136fa929060e083019060ff166004811115612937576129376142f9565b811115801561376c575060408051610100810182526071805482526072546020830152607354928201929092526074546060820152607554608082015260765460a082015260775460c0820152607854613768929060e083019060ff1660048111156135c3576135c36142f9565b8111155b61379e5760405162461bcd60e51b81526020600482015260036024820152624e454360e81b604482015260640161097c565b6137a83383613b79565b6066546137bf906001600160a01b03163383613364565b60705460ff166137d1576137d16129e8565b604080518281526020810184905233917ff3a670cd3af7d64b488926880889d08a8585a138ff455227af6737339a1ec262910160405180910390a25050565b6000606c546000141561382557506000919050565b6000613840606c5484602001516129bb90919063ffffffff16565b9050600061384d84613394565b905081811161385d57600061080c565b61080c828261434d565b60008183106138765781610998565b5090919050565b6076546000901561389057505060765490565b607254158061389d575081155b156138aa57506000919050565b607254606c54604080516101008101825260718054825260208201859052607354928201929092526074546060820152607554608082015260765460a082015260775460c08201526078546000949361391f93909261286f9290919060e083019060ff166004811115612a7457612a746142f9565b613929919061434d565b90506000613949606a5460695461394091906143a5565b606c5490613634565b61395b90670de0b6b3a76400006143a5565b9050600061396983836129bb565b905060008560716001015461397e9190614364565b9050600081600181613998670de0b6b3a764000087614364565b6139a291906143a5565b6139ac919061434d565b6139b69190614383565b90506000816071600401546139cb91906143a5565b9050428111156139dc5760006139de565b805b98975050505050505050565b6000613a3f826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613b839092919063ffffffff16565b805190915015610daf5780806020019051810190613a5d9190614605565b610daf5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161097c565b613ac46133ac565b613ace8282613b92565b613adf81607b546107ee9190614364565b6001600160a01b0383166000908152607c602052604081208054909190613b07908490614622565b90915550505050565b600054610100900460ff1680613b29575060005460ff16155b613b455760405162461bcd60e51b815260040161097c90614473565b600054610100900460ff16158015613b67576000805461ffff19166101011790555b613b6f613c71565b610d9d8383613cdd565b6129e48282613d72565b606061080c8484600085613dbd565b6001600160a01b038216613be85760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161097c565b8060356000828254613bfa91906143a5565b90915550506001600160a01b03821660009081526033602052604081208054839290613c279084906143a5565b90915550506040518181526001600160a01b038316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b600054610100900460ff1680613c8a575060005460ff16155b613ca65760405162461bcd60e51b815260040161097c90614473565b600054610100900460ff16158015613cc8576000805461ffff19166101011790555b8015613cda576000805461ff00191690555b50565b600054610100900460ff1680613cf6575060005460ff16155b613d125760405162461bcd60e51b815260040161097c90614473565b600054610100900460ff16158015613d34576000805461ffff19166101011790555b8251613d479060369060208601906140c1565b508151613d5b9060379060208501906140c1565b508015610daf576000805461ff0019169055505050565b613d7a6133ac565b613d848282613ee5565b613d9581607b546107ee9190614364565b6001600160a01b0383166000908152607c602052604081208054909190613b079084906143bd565b606082471015613e1e5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161097c565b843b613e6c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161097c565b600080866001600160a01b03168587604051613e889190614661565b60006040518083038185875af1925050503d8060008114613ec5576040519150601f19603f3d011682016040523d82523d6000602084013e613eca565b606091505b5091509150613eda828286614033565b979650505050505050565b6001600160a01b038216613f455760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f206164647265736044820152607360f81b606482015260840161097c565b6001600160a01b03821660009081526033602052604090205481811015613fb95760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e604482015261636560f01b606482015260840161097c565b6001600160a01b0383166000908152603360205260408120838303905560358054849290613fe890849061434d565b90915550506040518281526000906001600160a01b038516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b60608315614042575081610998565b8251156140525782518084602001fd5b8160405162461bcd60e51b815260040161097c91906141af565b60405180610100016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600060048111156140bc576140bc6142f9565b905290565b8280546140cd906143fe565b90600052602060002090601f0160209004810192826140ef5760008555614135565b82601f1061410857805160ff1916838001178555614135565b82800160010185558215614135579182015b8281111561413557825182559160200191906001019061411a565b506124269291505b80821115612426576000815560010161413d565b6001600160a01b0381168114613cda57600080fd5b60006020828403121561417857600080fd5b813561099881614151565b60005b8381101561419e578181015183820152602001614186565b83811115611d925750506000910152565b60208152600082518060208401526141ce816040850160208701614183565b601f01601f19169190910160400192915050565b600080604083850312156141f557600080fd5b823561420081614151565b946020939093013593505050565b60008060006060848603121561422357600080fd5b833561422e81614151565b9250602084013561423e81614151565b929592945050506040919091013590565b60006020828403121561426157600080fd5b5035919050565b6000806040838503121561427b57600080fd5b823561428681614151565b9150602083013561429681614151565b809150509250929050565b600080604083850312156142b457600080fd5b82359150602083013561429681614151565b8015158114613cda57600080fd5b600080604083850312156142e757600080fd5b823591506020830135614296816142c6565b634e487b7160e01b600052602160045260246000fd5b602081016005831061433157634e487b7160e01b600052602160045260246000fd5b91905290565b634e487b7160e01b600052601160045260246000fd5b60008282101561435f5761435f614337565b500390565b600081600019048311821515161561437e5761437e614337565b500290565b6000826143a057634e487b7160e01b600052601260045260246000fd5b500490565b600082198211156143b8576143b8614337565b500190565b600080821280156001600160ff1b03849003851316156143df576143df614337565b600160ff1b83900384128116156143f8576143f8614337565b50500190565b600181811c9082168061441257607f821691505b6020821081141561443357634e487b7160e01b600052602260045260246000fd5b50919050565b60208082526003908201526250494160e81b604082015260600190565b60006020828403121561446857600080fd5b815161099881614151565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6000602082840312156144d357600080fd5b5051919050565b6000602082840312156144ec57600080fd5b81516005811061099857600080fd5b60006020828403121561450d57600080fd5b815160ff8116811461099857600080fd5b634e487b7160e01b600052604160045260246000fd5b60006020828403121561454657600080fd5b815167ffffffffffffffff8082111561455e57600080fd5b818401915084601f83011261457257600080fd5b8151818111156145845761458461451e565b604051601f8201601f19908116603f011681019083821181831017156145ac576145ac61451e565b816040528281528760208487010111156145c557600080fd5b613eda836020830160208801614183565b600083516145e8818460208801614183565b8351908301906145fc818360208801614183565b01949350505050565b60006020828403121561461757600080fd5b8151610998816142c6565b60008083128015600160ff1b85018412161561464057614640614337565b6001600160ff1b038401831381161561465b5761465b614337565b50500390565b60008251614673818460208701614183565b919091019291505056fea264697066735822122093a57775e0847a8145d6c0e8ad47e948bcc7899ff99c5a42fd8a2671167d610264736f6c63430008090033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 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.