More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
107557884 | 567 days ago | 0 ETH | ||||
107557884 | 567 days ago | 0 ETH | ||||
107557857 | 567 days ago | 0 ETH | ||||
107557857 | 567 days ago | 0 ETH | ||||
107557857 | 567 days ago | 0 ETH | ||||
107557857 | 567 days ago | 0 ETH | ||||
107557857 | 567 days ago | 0 ETH | ||||
107557857 | 567 days ago | 0 ETH | ||||
107557857 | 567 days ago | 0 ETH | ||||
107557857 | 567 days ago | 0 ETH | ||||
107557815 | 567 days ago | 0 ETH | ||||
107557815 | 567 days ago | 0 ETH | ||||
107557815 | 567 days ago | 0 ETH | ||||
107557815 | 567 days ago | 0 ETH | ||||
107557815 | 567 days ago | 0 ETH | ||||
107557794 | 567 days ago | 0 ETH | ||||
107557794 | 567 days ago | 0 ETH | ||||
107557794 | 567 days ago | 0 ETH | ||||
107557794 | 567 days ago | 0 ETH | ||||
107557794 | 567 days ago | 0 ETH | ||||
107557794 | 567 days ago | 0 ETH | ||||
107557794 | 567 days ago | 0 ETH | ||||
107555511 | 567 days ago | 0 ETH | ||||
107555511 | 567 days ago | 0 ETH | ||||
107552833 | 567 days ago | 0 ETH |
Loading...
Loading
Contract Name:
DebtToken
Compiler Version
v0.8.9+commit.e5eed63a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "./dependencies/openzeppelin/security/ReentrancyGuard.sol"; import "./utils/TokenHolder.sol"; import "./access/Manageable.sol"; import "./storage/DebtTokenStorage.sol"; import "./lib/WadRayMath.sol"; error SyntheticDoesNotExist(); error SyntheticIsInactive(); error DebtTokenInactive(); error NameIsNull(); error SymbolIsNull(); error PoolIsNull(); error SyntheticIsNull(); error AllowanceNotSupported(); error ApprovalNotSupported(); error AmountIsZero(); error NotEnoughCollateral(); error DebtLowerThanTheFloor(); error RemainingDebtIsLowerThanTheFloor(); error TransferNotSupported(); error BurnFromNullAddress(); error BurnAmountExceedsBalance(); error MintToNullAddress(); error SurpassMaxDebtSupply(); error NewValueIsSameAsCurrent(); /** * @title Non-transferable token that represents users' debts */ contract DebtToken is ReentrancyGuard, TokenHolder, Manageable, DebtTokenStorageV2 { using WadRayMath for uint256; uint256 public constant SECONDS_PER_YEAR = 365.25 days; uint256 private constant HUNDRED_PERCENT = 1e18; string public constant VERSION = "1.2.0"; /// @notice Emitted when synthetic's debt is repaid event DebtRepaid(address indexed payer, address indexed account, uint256 amount, uint256 repaid, uint256 fee); /// @notice Emitted when active flag is updated event DebtTokenActiveUpdated(bool newActive); /// @notice Emitted when interest rate is updated event InterestRateUpdated(uint256 oldInterestRate, uint256 newInterestRate); /// @notice Emitted when max total supply is updated event MaxTotalSupplyUpdated(uint256 oldMaxTotalSupply, uint256 newMaxTotalSupply); /// @notice Emitted when synthetic token is issued event SyntheticTokenIssued( address indexed account, address indexed to, uint256 amount, uint256 issued, uint256 fee ); /** * @dev Throws if sender can't burn */ modifier onlyIfPool() { if (msg.sender != address(pool)) revert SenderIsNotPool(); _; } /** * @dev Throws if synthetic token doesn't exist */ modifier onlyIfSyntheticTokenExists() { if (!pool.doesSyntheticTokenExist(syntheticToken)) revert SyntheticDoesNotExist(); _; } /** * @dev Throws if synthetic token isn't enabled */ modifier onlyIfSyntheticTokenIsActive() { if (!syntheticToken.isActive()) revert SyntheticIsInactive(); if (!isActive) revert DebtTokenInactive(); _; } /** * @notice Update reward contracts' states * @dev Should be called before balance changes (i.e. mint/burn) */ modifier updateRewardsBeforeMintOrBurn(address account_) { address[] memory _rewardsDistributors = pool.getRewardsDistributors(); ISyntheticToken _syntheticToken = syntheticToken; uint256 _length = _rewardsDistributors.length; for (uint256 i; i < _length; ++i) { IRewardsDistributor(_rewardsDistributors[i]).updateBeforeMintOrBurn(_syntheticToken, account_); } _; } function initialize( string calldata name_, string calldata symbol_, IPool pool_, ISyntheticToken syntheticToken_, uint256 interestRate_, uint256 maxTotalSupply_ ) external initializer { if (bytes(name_).length == 0) revert NameIsNull(); if (bytes(symbol_).length == 0) revert SymbolIsNull(); if (address(pool_) == address(0)) revert PoolIsNull(); if (address(syntheticToken_) == address(0)) revert SyntheticIsNull(); __ReentrancyGuard_init(); __Manageable_init(pool_); name = name_; symbol = symbol_; decimals = syntheticToken_.decimals(); syntheticToken = syntheticToken_; lastTimestampAccrued = block.timestamp; debtIndex = 1e18; interestRate = interestRate_; maxTotalSupply = maxTotalSupply_; isActive = true; } /** * @notice Accrue interest over debt supply */ function accrueInterest() public override { ( uint256 _interestAmountAccrued, uint256 _debtIndex, uint256 _lastTimestampAccrued ) = _calculateInterestAccrual(); if (block.timestamp == _lastTimestampAccrued) { return; } lastTimestampAccrued = block.timestamp; if (_interestAmountAccrued > 0) { totalSupply_ += _interestAmountAccrued; debtIndex = _debtIndex; // Note: Address states where minting will fail (e.g. the token is inactive, it reached max supply, etc) try syntheticToken.mint(pool.feeCollector(), _interestAmountAccrued + pendingInterestFee) { pendingInterestFee = 0; } catch { pendingInterestFee += _interestAmountAccrued; } } } /// @inheritdoc IERC20 function allowance(address /*owner_*/, address /*spender_*/) external pure override returns (uint256) { revert AllowanceNotSupported(); } /// @inheritdoc IERC20 // solhint-disable-next-line function approve(address /*spender_*/, uint256 /*amount_*/) external override returns (bool) { revert ApprovalNotSupported(); } /** * @notice Get the updated (principal + interest) user's debt */ function balanceOf(address account_) public view override returns (uint256) { uint256 _principal = principalOf[account_]; if (_principal == 0) { return 0; } (, uint256 _debtIndex, ) = _calculateInterestAccrual(); // Note: The `debtIndex / debtIndexOf` gives the interest to apply to the principal amount return (_principal * _debtIndex) / debtIndexOf[account_]; } /** * @notice Burn debt token * @param from_ The account to burn from * @param amount_ The amount to burn */ function burn(address from_, uint256 amount_) external override onlyIfPool { _burn(from_, amount_); } /** * @notice Collect pending interest fee if any */ function collectPendingInterestFee() external { uint256 _pendingInterestFee = pendingInterestFee; if (_pendingInterestFee > 0) { syntheticToken.mint(pool.feeCollector(), _pendingInterestFee); pendingInterestFee = 0; } } /** * @notice Lock collateral and mint synthetic token * @param amount_ The amount to mint * @param to_ The beneficiary account * @return _issued The amount issued after fees * @return _fee The fee amount collected */ function issue( uint256 amount_, address to_ ) external override whenNotShutdown nonReentrant onlyIfSyntheticTokenExists onlyIfSyntheticTokenIsActive returns (uint256 _issued, uint256 _fee) { if (amount_ == 0) revert AmountIsZero(); accrueInterest(); IPool _pool = pool; ISyntheticToken _syntheticToken = syntheticToken; (, , , , uint256 _issuableInUsd) = _pool.debtPositionOf(msg.sender); IMasterOracle _masterOracle = _pool.masterOracle(); if (amount_ > _masterOracle.quoteUsdToToken(address(_syntheticToken), _issuableInUsd)) { revert NotEnoughCollateral(); } return _issue(_pool, _masterOracle, _syntheticToken, msg.sender, amount_, to_); } /** * @notice Issue synth without checking collateral * @dev The healthy of outcome position must be done afterhand * @param borrower_ The debtor account * @param amount_ The amount to mint * @return _issued The amount issued after fees * @return _fee The fee amount collected */ function flashIssue( address borrower_, uint256 amount_ ) external override onlyIfPool whenNotShutdown nonReentrant onlyIfSyntheticTokenExists onlyIfSyntheticTokenIsActive returns (uint256 _issued, uint256 _fee) { if (amount_ == 0) revert AmountIsZero(); accrueInterest(); IPool _pool = pool; return _issue(_pool, _pool.masterOracle(), syntheticToken, borrower_, amount_, msg.sender); } /** * @notice Return interest rate (in percent) per second */ function interestRatePerSecond() public view override returns (uint256) { return interestRate / SECONDS_PER_YEAR; } /** * @notice Quote gross `_amount` to issue `amountToIssue_` synthetic tokens * @param amountToIssue_ Synth to issue * @return _amount Gross amount * @return _fee The fee amount to collect */ function quoteIssueIn(uint256 amountToIssue_) external view override returns (uint256 _amount, uint256 _fee) { uint256 _issueFee = pool.feeProvider().issueFee(); if (_issueFee == 0) { return (amountToIssue_, _fee); } _amount = amountToIssue_.wadDiv(HUNDRED_PERCENT - _issueFee); _fee = _amount - amountToIssue_; } /** * @notice Quote synthetic tokens `_amountToIssue` by using gross `_amount` * @param amount_ Gross amount * @return _amountToIssue Synth to issue * @return _fee The fee amount to collect */ function quoteIssueOut(uint256 amount_) public view override returns (uint256 _amountToIssue, uint256 _fee) { uint256 _issueFee = pool.feeProvider().issueFee(); if (_issueFee == 0) { return (amount_, _fee); } _fee = amount_.wadMul(_issueFee); _amountToIssue = amount_ - _fee; } /** * @notice Quote synthetic token `_amount` need to repay `amountToRepay_` debt * @param amountToRepay_ Debt amount to repay * @return _amount Gross amount * @return _fee The fee amount to collect */ function quoteRepayIn(uint256 amountToRepay_) public view override returns (uint256 _amount, uint256 _fee) { uint256 _repayFee = pool.feeProvider().repayFee(); if (_repayFee == 0) { return (amountToRepay_, _fee); } _fee = amountToRepay_.wadMul(_repayFee); _amount = amountToRepay_ + _fee; } /** * @notice Quote debt `_amountToRepay` by burning `_amount` synthetic tokens * @param amount_ Gross amount * @return _amountToRepay Debt amount to repay * @return _fee The fee amount to collect */ function quoteRepayOut(uint256 amount_) public view override returns (uint256 _amountToRepay, uint256 _fee) { uint256 _repayFee = pool.feeProvider().repayFee(); if (_repayFee == 0) { return (amount_, _fee); } _amountToRepay = amount_.wadDiv(HUNDRED_PERCENT + _repayFee); _fee = amount_ - _amountToRepay; } /** * @notice Send synthetic token to decrease debt * @dev The msg.sender is the payer and the account beneficed * @param onBehalfOf_ The account that will have debt decreased * @param amount_ The amount of synthetic token to burn (this is the gross amount, the repay fee will be subtracted from it) * @return _repaid The amount repaid after fees */ function repay( address onBehalfOf_, uint256 amount_ ) external override whenNotShutdown nonReentrant onlyIfSyntheticTokenExists returns (uint256 _repaid, uint256 _fee) { if (amount_ == 0) revert AmountIsZero(); accrueInterest(); IPool _pool = pool; ISyntheticToken _syntheticToken = syntheticToken; (_repaid, _fee) = quoteRepayOut(amount_); if (_fee > 0) { _syntheticToken.seize(msg.sender, _pool.feeCollector(), _fee); } uint256 _debtFloorInUsd = _pool.debtFloorInUsd(); if (_debtFloorInUsd > 0) { uint256 _newDebtInUsd = _pool.masterOracle().quoteTokenToUsd( address(_syntheticToken), balanceOf(onBehalfOf_) - _repaid ); if (_newDebtInUsd > 0 && _newDebtInUsd < _debtFloorInUsd) { revert RemainingDebtIsLowerThanTheFloor(); } } _syntheticToken.burn(msg.sender, _repaid); _burn(onBehalfOf_, _repaid); emit DebtRepaid(msg.sender, onBehalfOf_, amount_, _repaid, _fee); } /** * @notice Send synthetic token to decrease debt * @dev This function helps users to no leave debt dust behind * @param onBehalfOf_ The account that will have debt decreased * @return _repaid The amount repaid after fees * @return _fee The fee amount collected */ function repayAll( address onBehalfOf_ ) external override whenNotShutdown nonReentrant onlyIfSyntheticTokenExists returns (uint256 _repaid, uint256 _fee) { accrueInterest(); _repaid = balanceOf(onBehalfOf_); if (_repaid == 0) revert AmountIsZero(); ISyntheticToken _syntheticToken = syntheticToken; uint256 _amount; (_amount, _fee) = quoteRepayIn(_repaid); if (_fee > 0) { _syntheticToken.seize(msg.sender, pool.feeCollector(), _fee); } _syntheticToken.burn(msg.sender, _repaid); _burn(onBehalfOf_, _repaid); emit DebtRepaid(msg.sender, onBehalfOf_, _amount, _repaid, _fee); } /** * @notice Return the total supply */ function totalSupply() external view override returns (uint256) { (uint256 _interestAmountAccrued, , ) = _calculateInterestAccrual(); return totalSupply_ + _interestAmountAccrued; } /// @inheritdoc IERC20 // solhint-disable-next-line function transfer(address /*recipient_*/, uint256 /*amount_*/) external override returns (bool) { revert TransferNotSupported(); } /// @inheritdoc IERC20 // solhint-disable-next-line function transferFrom( address /*sender_*/, address /*recipient_*/, uint256 /*amount_*/ ) external override returns (bool) { revert TransferNotSupported(); } /** * @notice Destroy `amount` tokens from `account`, reducing the * total supply */ function _burn(address account_, uint256 amount_) private updateRewardsBeforeMintOrBurn(account_) { if (account_ == address(0)) revert BurnFromNullAddress(); uint256 _accountBalance = balanceOf(account_); if (_accountBalance < amount_) revert BurnAmountExceedsBalance(); unchecked { principalOf[account_] = _accountBalance - amount_; debtIndexOf[account_] = debtIndex; totalSupply_ -= amount_; } emit Transfer(account_, address(0), amount_); // Remove this token from the debt tokens list if the sender's balance goes to zero if (amount_ > 0 && balanceOf(account_) == 0) { pool.removeFromDebtTokensOfAccount(account_); } } /** * @notice Calculate interest to accrue * @dev This util function avoids code duplication across `balanceOf` and `accrueInterest` * @return _interestAmountAccrued The total amount of debt tokens accrued * @return _debtIndex The new `debtIndex` value */ function _calculateInterestAccrual() private view returns (uint256 _interestAmountAccrued, uint256 _debtIndex, uint256 _lastTimestampAccrued) { _lastTimestampAccrued = lastTimestampAccrued; _debtIndex = debtIndex; if (block.timestamp > _lastTimestampAccrued) { uint256 _interestRateToAccrue = interestRatePerSecond() * (block.timestamp - _lastTimestampAccrued); if (_interestRateToAccrue > 0) { _interestAmountAccrued = _interestRateToAccrue.wadMul(totalSupply_); _debtIndex += _interestRateToAccrue.wadMul(debtIndex); } } } /** * @notice Internal function for mint synthetic token * @dev Not getting contracts from storage in order to save gas * @param pool_ The pool * @param masterOracle_ The oracle * @param syntheticToken_ The synthetic token * @param borrower_ The debtor account * @param amount_ The amount to mint * @param to_ The beneficiary account * @return _issued The amount issued after fees * @return _fee The fee amount collected */ function _issue( IPool pool_, IMasterOracle masterOracle_, ISyntheticToken syntheticToken_, address borrower_, uint256 amount_, address to_ ) private returns (uint256 _issued, uint256 _fee) { uint256 _debtFloorInUsd = pool_.debtFloorInUsd(); if ( _debtFloorInUsd > 0 && masterOracle_.quoteTokenToUsd(address(syntheticToken), balanceOf(borrower_) + amount_) < _debtFloorInUsd ) { revert DebtLowerThanTheFloor(); } (_issued, _fee) = quoteIssueOut(amount_); if (_fee > 0) { syntheticToken_.mint(pool_.feeCollector(), _fee); } syntheticToken_.mint(to_, _issued); _mint(borrower_, amount_); emit SyntheticTokenIssued(borrower_, to_, amount_, _issued, _fee); } /** * @notice Create `amount` tokens and assigns them to `account`, increasing * the total supply */ function _mint(address account_, uint256 amount_) private updateRewardsBeforeMintOrBurn(account_) { if (account_ == address(0)) revert MintToNullAddress(); uint256 _balanceBefore = balanceOf(account_); totalSupply_ += amount_; if (totalSupply_ > maxTotalSupply) revert SurpassMaxDebtSupply(); principalOf[account_] = _balanceBefore + amount_; debtIndexOf[account_] = debtIndex; emit Transfer(address(0), account_, amount_); // Add this token to the debt tokens list if the recipient is receiving it for the 1st time if (_balanceBefore == 0 && amount_ > 0) { pool.addToDebtTokensOfAccount(account_); } } /// @inheritdoc TokenHolder // solhint-disable-next-line no-empty-blocks function _requireCanSweep() internal view override onlyGovernor {} /** * @notice Update max total supply */ function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external override onlyGovernor { uint256 _currentMaxTotalSupply = maxTotalSupply; if (newMaxTotalSupply_ == _currentMaxTotalSupply) revert NewValueIsSameAsCurrent(); emit MaxTotalSupplyUpdated(_currentMaxTotalSupply, newMaxTotalSupply_); maxTotalSupply = newMaxTotalSupply_; } /** * @notice Update interest rate (APR) */ function updateInterestRate(uint256 newInterestRate_) external override onlyGovernor { accrueInterest(); uint256 _currentInterestRate = interestRate; if (newInterestRate_ == _currentInterestRate) revert NewValueIsSameAsCurrent(); emit InterestRateUpdated(_currentInterestRate, newInterestRate_); interestRate = newInterestRate_; } /** * @notice Enable/Disable the Debt Token */ function toggleIsActive() external override onlyGovernor { bool _newIsActive = !isActive; emit DebtTokenActiveUpdated(_newIsActive); isActive = _newIsActive; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../dependencies/openzeppelin/proxy/utils/Initializable.sol"; import "../interfaces/IGovernable.sol"; import "../interfaces/IManageable.sol"; error SenderIsNotPool(); error SenderIsNotGovernor(); error IsPaused(); error IsShutdown(); error PoolAddressIsNull(); /** * @title Reusable contract that handles accesses */ abstract contract Manageable is IManageable, Initializable { /** * @notice Pool contract */ IPool public pool; /** * @dev Throws if `msg.sender` isn't the pool */ modifier onlyPool() { if (msg.sender != address(pool)) revert SenderIsNotPool(); _; } /** * @dev Throws if `msg.sender` isn't the governor */ modifier onlyGovernor() { if (msg.sender != governor()) revert SenderIsNotGovernor(); _; } /** * @dev Throws if contract is paused */ modifier whenNotPaused() { if (pool.paused()) revert IsPaused(); _; } /** * @dev Throws if contract is shutdown */ modifier whenNotShutdown() { if (pool.everythingStopped()) revert IsShutdown(); _; } // solhint-disable-next-line func-name-mixedcase function __Manageable_init(IPool pool_) internal initializer { if (address(pool_) == address(0)) revert PoolAddressIsNull(); pool = pool_; } /** * @notice Get the governor * @return _governor The governor */ function governor() public view returns (address _governor) { _governor = IGovernable(address(pool)).governor(); } uint256[49] private __gap; }
// SPDX-License-Identifier: MIT 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. */ 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 pragma solidity ^0.8.0; import "../proxy/utils/Initializable.sol"; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard is Initializable { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; function __ReentrancyGuard_init() internal initializer { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @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 pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); 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.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ 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 Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(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 pragma solidity 0.8.9; import "../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol"; import "./ISyntheticToken.sol"; interface IDebtToken is IERC20Metadata { function lastTimestampAccrued() external view returns (uint256); function isActive() external view returns (bool); function syntheticToken() external view returns (ISyntheticToken); function accrueInterest() external; function debtIndex() external returns (uint256 debtIndex_); function burn(address from_, uint256 amount_) external; function issue(uint256 amount_, address to_) external returns (uint256 _issued, uint256 _fee); function flashIssue(address borrower_, uint256 amount_) external returns (uint256 _issued, uint256 _fee); function repay(address onBehalfOf_, uint256 amount_) external returns (uint256 _repaid, uint256 _fee); function repayAll(address onBehalfOf_) external returns (uint256 _repaid, uint256 _fee); function quoteIssueIn(uint256 amountToIssue_) external view returns (uint256 _amount, uint256 _fee); function quoteIssueOut(uint256 amount_) external view returns (uint256 _amountToIssue, uint256 _fee); function quoteRepayIn(uint256 amountToRepay_) external view returns (uint256 _amount, uint256 _fee); function quoteRepayOut(uint256 amount_) external view returns (uint256 _amountToRepay, uint256 _fee); function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external; function updateInterestRate(uint256 newInterestRate_) external; function maxTotalSupply() external view returns (uint256); function interestRate() external view returns (uint256); function interestRatePerSecond() external view returns (uint256); function toggleIsActive() external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol"; interface IDepositToken is IERC20Metadata { function underlying() external view returns (IERC20); function collateralFactor() external view returns (uint256); function unlockedBalanceOf(address account_) external view returns (uint256); function lockedBalanceOf(address account_) external view returns (uint256); function flashWithdraw(address account_, uint256 amount_) external returns (uint256 _withdrawn, uint256 _fee); function deposit(uint256 amount_, address onBehalfOf_) external returns (uint256 _deposited, uint256 _fee); function quoteDepositIn(uint256 amountToDeposit_) external view returns (uint256 _amount, uint256 _fee); function quoteDepositOut(uint256 amount_) external view returns (uint256 _amountToDeposit, uint256 _fee); function quoteWithdrawIn(uint256 amountToWithdraw_) external view returns (uint256 _amount, uint256 _fee); function quoteWithdrawOut(uint256 amount_) external view returns (uint256 _amountToWithdraw, uint256 _fee); function withdraw(uint256 amount_, address to_) external returns (uint256 _withdrawn, uint256 _fee); function seize(address from_, address to_, uint256 amount_) external; function updateCollateralFactor(uint128 newCollateralFactor_) external; function isActive() external view returns (bool); function toggleIsActive() external; function maxTotalSupply() external view returns (uint256); function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; /** * @notice FeeProvider interface */ interface IFeeProvider { struct LiquidationFees { uint128 liquidatorIncentive; uint128 protocolFee; } function defaultSwapFee() external view returns (uint256); function depositFee() external view returns (uint256); function issueFee() external view returns (uint256); function liquidationFees() external view returns (uint128 liquidatorIncentive, uint128 protocolFee); function repayFee() external view returns (uint256); function swapFeeFor(address account_) external view returns (uint256); function withdrawFee() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; /** * @notice Governable interface */ interface IGovernable { function governor() external view returns (address _governor); function transferGovernorship(address _proposedGovernor) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "./IPool.sol"; /** * @notice Manageable interface */ interface IManageable { function pool() external view returns (IPool _pool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IPauseable { function paused() external view returns (bool); function everythingStopped() external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "./IDepositToken.sol"; import "./IDebtToken.sol"; import "./ITreasury.sol"; import "./IRewardsDistributor.sol"; import "./IPoolRegistry.sol"; import "./IFeeProvider.sol"; import "./external/ISwapper.sol"; import "../interfaces/IFeeProvider.sol"; /** * @notice Pool interface */ interface IPool is IPauseable, IGovernable { function debtFloorInUsd() external view returns (uint256); function feeCollector() external view returns (address); function swapper() external view returns (ISwapper); function feeProvider() external view returns (IFeeProvider); function maxLiquidable() external view returns (uint256); function flashRepay( ISyntheticToken syntheticToken_, IDepositToken depositToken_, uint256 withdrawAmount_, uint256 repayAmountMin_ ) external returns (uint256 _withdrawn, uint256 _repaid); function doesSyntheticTokenExist(ISyntheticToken syntheticToken_) external view returns (bool); function doesDebtTokenExist(IDebtToken debtToken_) external view returns (bool); function doesDepositTokenExist(IDepositToken depositToken_) external view returns (bool); function depositTokenOf(IERC20 underlying_) external view returns (IDepositToken); function debtTokenOf(ISyntheticToken syntheticToken_) external view returns (IDebtToken); function getDepositTokens() external view returns (address[] memory); function getDebtTokens() external view returns (address[] memory); function getRewardsDistributors() external view returns (address[] memory); function debtOf(address account_) external view returns (uint256 _debtInUsd); function depositOf(address account_) external view returns (uint256 _depositInUsd, uint256 _issuableLimitInUsd); function debtPositionOf( address account_ ) external view returns ( bool _isHealthy, uint256 _depositInUsd, uint256 _debtInUsd, uint256 _issuableLimitInUsd, uint256 _issuableInUsd ); function leverage( IERC20 tokenIn_, IDepositToken depositToken_, ISyntheticToken syntheticToken_, uint256 amountIn_, uint256 leverage_, uint256 depositAmountMin_ ) external returns (uint256 _deposited, uint256 _issued); function liquidate( ISyntheticToken syntheticToken_, address account_, uint256 amountToRepay_, IDepositToken depositToken_ ) external returns (uint256 _totalSeized, uint256 _toLiquidator, uint256 _fee); function quoteLiquidateIn( ISyntheticToken syntheticToken_, uint256 totalToSeized_, IDepositToken depositToken_ ) external view returns (uint256 _amountToRepay, uint256 _toLiquidator, uint256 _fee); function quoteLiquidateMax( ISyntheticToken syntheticToken_, address account_, IDepositToken depositToken_ ) external view returns (uint256 _maxAmountToRepay); function quoteLiquidateOut( ISyntheticToken syntheticToken_, uint256 amountToRepay_, IDepositToken depositToken_ ) external view returns (uint256 _totalSeized, uint256 _toLiquidator, uint256 _fee); function quoteSwapIn( ISyntheticToken syntheticTokenIn_, ISyntheticToken syntheticTokenOut_, uint256 amountOut_ ) external view returns (uint256 _amountIn, uint256 _fee); function quoteSwapOut( ISyntheticToken syntheticTokenIn_, ISyntheticToken syntheticTokenOut_, uint256 amountIn_ ) external view returns (uint256 _amountOut, uint256 _fee); function swap( ISyntheticToken syntheticTokenIn_, ISyntheticToken syntheticTokenOut_, uint256 amountIn_ ) external returns (uint256 _amountOut, uint256 _fee); function treasury() external view returns (ITreasury); function masterOracle() external view returns (IMasterOracle); function poolRegistry() external view returns (IPoolRegistry); function addToDepositTokensOfAccount(address account_) external; function removeFromDepositTokensOfAccount(address account_) external; function addToDebtTokensOfAccount(address account_) external; function removeFromDebtTokensOfAccount(address account_) external; function getDepositTokensOfAccount(address account_) external view returns (address[] memory); function getDebtTokensOfAccount(address account_) external view returns (address[] memory); function isSwapActive() external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "./external/IMasterOracle.sol"; import "./IPauseable.sol"; import "./IGovernable.sol"; import "./ISyntheticToken.sol"; interface IPoolRegistry is IPauseable, IGovernable { function isPoolRegistered(address pool_) external view returns (bool); function feeCollector() external view returns (address); function nativeTokenGateway() external view returns (address); function getPools() external view returns (address[] memory); function registerPool(address pool_) external; function unregisterPool(address pool_) external; function masterOracle() external view returns (IMasterOracle); function updateMasterOracle(IMasterOracle newOracle_) external; function updateFeeCollector(address newFeeCollector_) external; function updateNativeTokenGateway(address newGateway_) external; function idOfPool(address pool_) external view returns (uint256); function nextPoolId() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../dependencies/openzeppelin/token/ERC20/IERC20.sol"; /** * @notice Reward Distributor interface */ interface IRewardsDistributor { function rewardToken() external view returns (IERC20); function tokenSpeeds(IERC20 token_) external view returns (uint256); function tokensAccruedOf(address account_) external view returns (uint256); function updateBeforeMintOrBurn(IERC20 token_, address account_) external; function updateBeforeTransfer(IERC20 token_, address from_, address to_) external; function claimable(address account_) external view returns (uint256 _claimable); function claimable(address account_, IERC20 token_) external view returns (uint256 _claimable); function claimRewards(address account_) external; function claimRewards(address account_, IERC20[] memory tokens_) external; function claimRewards(address[] memory accounts_, IERC20[] memory tokens_) external; function updateTokenSpeed(IERC20 token_, uint256 newSpeed_) external; function updateTokenSpeeds(IERC20[] calldata tokens_, uint256[] calldata speeds_) external; function tokens(uint256) external view returns (IERC20); function tokenStates(IERC20) external view returns (uint224 index, uint32 timestamp); function accountIndexOf(IERC20, address) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../dependencies/openzeppelin/token/ERC20/extensions/IERC20Metadata.sol"; import "./IDebtToken.sol"; import "./IPoolRegistry.sol"; interface ISyntheticToken is IERC20Metadata { function isActive() external view returns (bool); function mint(address to_, uint256 amount_) external; function burn(address from_, uint256 amount) external; function poolRegistry() external returns (IPoolRegistry); function toggleIsActive() external; function seize(address from_, address to_, uint256 amount_) external; function updateMaxTotalSupply(uint256 newMaxTotalSupply_) external; function maxTotalSupply() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface ITreasury { function pull(address to_, uint256 amount_) external; function migrateTo(address newTreasury_) external; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IMasterOracle { function quoteTokenToUsd(address _asset, uint256 _amount) external view returns (uint256 _amountInUsd); function quoteUsdToToken(address _asset, uint256 _amountInUsd) external view returns (uint256 _amount); function quote(address _assetIn, address _assetOut, uint256 _amountIn) external view returns (uint256 _amountOut); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface ISwapper { function swapExactInput( address tokenIn_, address tokenOut_, uint256 amountIn_, uint256 amountOutMin_, address receiver_ ) external returns (uint256 _amountOut); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; /** * @title Math library * @dev Provides mul and div function for wads (decimal numbers with 18 digits precision) and rays (decimals with 27 digits) * @dev Based on https://github.com/dapphub/ds-math/blob/master/src/math.sol */ library WadRayMath { uint256 internal constant WAD = 1e18; uint256 internal constant HALF_WAD = WAD / 2; uint256 internal constant RAY = 1e27; uint256 internal constant HALF_RAY = RAY / 2; uint256 internal constant WAD_RAY_RATIO = 1e9; /** * @dev Multiplies two wad, rounding half up to the nearest wad * @param a Wad * @param b Wad * @return The result of a*b, in wad */ function wadMul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0 || b == 0) { return 0; } return (a * b + HALF_WAD) / WAD; } /** * @dev Divides two wad, rounding half up to the nearest wad * @param a Wad * @param b Wad * @return The result of a/b, in wad */ function wadDiv(uint256 a, uint256 b) internal pure returns (uint256) { return (a * WAD + b / 2) / b; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../interfaces/IDebtToken.sol"; abstract contract DebtTokenStorageV1 is IDebtToken { /** * @notice The name of the token */ string public override name; /** * @notice The symbol of the token */ string public override symbol; /** * @notice The mapping of the users' minted tokens * @dev This value changes within the mint and burn operations */ mapping(address => uint256) internal principalOf; /** * @notice The `debtIndex` "snapshot" of the account's latest `principalOf` update (i.e. mint/burn) */ mapping(address => uint256) internal debtIndexOf; /** * @notice The supply cap */ uint256 public override maxTotalSupply; /** * @notice The total amount of minted tokens */ uint256 internal totalSupply_; /** * @notice The timestamp when interest accrual was calculated for the last time */ uint256 public override lastTimestampAccrued; /** * @notice Accumulator of the total earned interest rate since the beginning */ uint256 public override debtIndex; /** * @notice Interest rate * @dev Use 0.1e18 for 10% APR */ uint256 public override interestRate; /** * @notice The Synthetic token */ ISyntheticToken public override syntheticToken; /** * @notice If true, disables msAsset minting on this pool */ bool public override isActive; /** * @notice The decimals of the token */ uint8 public override decimals; } abstract contract DebtTokenStorageV2 is DebtTokenStorageV1 { /** * @notice Pending interest fee to collect */ uint256 public pendingInterestFee; }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../dependencies/openzeppelin/token/ERC20/utils/SafeERC20.sol"; error FallbackIsNotAllowed(); error ReceiveIsNotAllowed(); /** * @title Utils contract that handles tokens sent to it */ abstract contract TokenHolder { using SafeERC20 for IERC20; /** * @dev Revert fallback calls */ fallback() external payable { revert FallbackIsNotAllowed(); } /** * @dev Revert when receiving by default */ receive() external payable virtual { revert ReceiveIsNotAllowed(); } /** * @notice ERC20 recovery in case of stuck tokens due direct transfers to the contract address. * @param token_ The token to transfer * @param to_ The recipient of the transfer * @param amount_ The amount to send */ function sweep(IERC20 token_, address to_, uint256 amount_) external { _requireCanSweep(); if (address(token_) == address(0)) { Address.sendValue(payable(to_), amount_); } else { token_.safeTransfer(to_, amount_); } } /** * @notice Function that reverts if the caller isn't allowed to sweep tokens * @dev Usually requires the owner or governor as the caller */ function _requireCanSweep() internal view virtual; }
{ "evmVersion": "london", "libraries": {}, "metadata": { "bytecodeHash": "ipfs", "useLiteralContent": true }, "optimizer": { "enabled": true, "runs": 200 }, "remappings": [], "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"name":"AllowanceNotSupported","type":"error"},{"inputs":[],"name":"AmountIsZero","type":"error"},{"inputs":[],"name":"ApprovalNotSupported","type":"error"},{"inputs":[],"name":"BurnAmountExceedsBalance","type":"error"},{"inputs":[],"name":"BurnFromNullAddress","type":"error"},{"inputs":[],"name":"DebtLowerThanTheFloor","type":"error"},{"inputs":[],"name":"DebtTokenInactive","type":"error"},{"inputs":[],"name":"FallbackIsNotAllowed","type":"error"},{"inputs":[],"name":"IsShutdown","type":"error"},{"inputs":[],"name":"MintToNullAddress","type":"error"},{"inputs":[],"name":"NameIsNull","type":"error"},{"inputs":[],"name":"NewValueIsSameAsCurrent","type":"error"},{"inputs":[],"name":"NotEnoughCollateral","type":"error"},{"inputs":[],"name":"PoolAddressIsNull","type":"error"},{"inputs":[],"name":"PoolIsNull","type":"error"},{"inputs":[],"name":"ReceiveIsNotAllowed","type":"error"},{"inputs":[],"name":"RemainingDebtIsLowerThanTheFloor","type":"error"},{"inputs":[],"name":"SenderIsNotGovernor","type":"error"},{"inputs":[],"name":"SenderIsNotPool","type":"error"},{"inputs":[],"name":"SurpassMaxDebtSupply","type":"error"},{"inputs":[],"name":"SymbolIsNull","type":"error"},{"inputs":[],"name":"SyntheticDoesNotExist","type":"error"},{"inputs":[],"name":"SyntheticIsInactive","type":"error"},{"inputs":[],"name":"SyntheticIsNull","type":"error"},{"inputs":[],"name":"TransferNotSupported","type":"error"},{"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":true,"internalType":"address","name":"payer","type":"address"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"repaid","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"DebtRepaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"newActive","type":"bool"}],"name":"DebtTokenActiveUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldInterestRate","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newInterestRate","type":"uint256"}],"name":"InterestRateUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxTotalSupply","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxTotalSupply","type":"uint256"}],"name":"MaxTotalSupplyUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"issued","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fee","type":"uint256"}],"name":"SyntheticTokenIssued","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"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"SECONDS_PER_YEAR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accrueInterest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account_","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectPendingInterestFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"debtIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"borrower_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"flashIssue","outputs":[{"internalType":"uint256","name":"_issued","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"governor","outputs":[{"internalType":"address","name":"_governor","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"contract IPool","name":"pool_","type":"address"},{"internalType":"contract ISyntheticToken","name":"syntheticToken_","type":"address"},{"internalType":"uint256","name":"interestRate_","type":"uint256"},{"internalType":"uint256","name":"maxTotalSupply_","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"interestRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"interestRatePerSecond","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"},{"internalType":"address","name":"to_","type":"address"}],"name":"issue","outputs":[{"internalType":"uint256","name":"_issued","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"lastTimestampAccrued","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTotalSupply","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":"pendingInterestFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pool","outputs":[{"internalType":"contract IPool","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToIssue_","type":"uint256"}],"name":"quoteIssueIn","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"quoteIssueOut","outputs":[{"internalType":"uint256","name":"_amountToIssue","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amountToRepay_","type":"uint256"}],"name":"quoteRepayIn","outputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"quoteRepayOut","outputs":[{"internalType":"uint256","name":"_amountToRepay","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"onBehalfOf_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"repay","outputs":[{"internalType":"uint256","name":"_repaid","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"onBehalfOf_","type":"address"}],"name":"repayAll","outputs":[{"internalType":"uint256","name":"_repaid","type":"uint256"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token_","type":"address"},{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"sweep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"syntheticToken","outputs":[{"internalType":"contract ISyntheticToken","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleIsActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newInterestRate_","type":"uint256"}],"name":"updateInterestRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newMaxTotalSupply_","type":"uint256"}],"name":"updateMaxTotalSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
608060405234801561001057600080fd5b50613858806100206000396000f3fe60806040526004361061021e5760003560e01c8063752a50a611610123578063b696a6ad116100ab578063d38f2ba91161006f578063d38f2ba914610647578063d7da606614610667578063dd62ed3e1461067d578063e6a69ab81461069d578063ffa1ad74146106b55761023c565b8063b696a6ad146105bc578063bb8c631f146105dc578063bfa17656146105f2578063c9dc4b4d14610612578063d2593329146106325761023c565b806395d89b41116100f257806395d89b41146105425780639cc820da146105575780639dc29fac1461056c578063a6afed951461058c578063a9059cbb146105a15761023c565b8063752a50a6146104cc5780637c27383b146104ec5780637c3a00fd1461050c5780638230ecd6146105225761023c565b80632ab4d052116101a65780634754d176116101755780634754d17614610436578063565f3d4f1461045657806362c067671461046c57806370a082311461048c57806374e87e1e146104ac5761023c565b80632ab4d052146103b85780632d4aeea1146103ce578063313ce567146103ee57806336248ab4146104215761023c565b8063172f50a4116101ed578063172f50a4146102fd57806318160ddd1461031f57806322867d781461034257806322f3e2d41461037757806323b872dd146103985761023c565b806306fdde0314610255578063095ea7b3146102805780630c340a24146102b057806316f0115b146102dd5761023c565b3661023c57604051636436c22d60e11b815260040160405180910390fd5b60405163a0152e6360e01b815260040160405180910390fd5b34801561026157600080fd5b5061026a6106e6565b6040516102779190613287565b60405180910390f35b34801561028c57600080fd5b506102a061029b3660046132cf565b610774565b6040519015158152602001610277565b3480156102bc57600080fd5b506102c561078f565b6040516001600160a01b039091168152602001610277565b3480156102e957600080fd5b506002546102c5906001600160a01b031681565b34801561030957600080fd5b5061031d6103183660046132fb565b610811565b005b34801561032b57600080fd5b506103346108ad565b604051908152602001610277565b34801561034e57600080fd5b5061036261035d3660046132cf565b6108d0565b60408051928352602083019190915201610277565b34801561038357600080fd5b50603d546102a090600160a01b900460ff1681565b3480156103a457600080fd5b506102a06103b3366004613314565b610df1565b3480156103c457600080fd5b5061033460385481565b3480156103da57600080fd5b506103626103e93660046132fb565b610e0c565b3480156103fa57600080fd5b50603d5461040f90600160a81b900460ff1681565b60405160ff9091168152602001610277565b34801561042d57600080fd5b5061031d610f45565b34801561044257600080fd5b506103626104513660046132fb565b61102e565b34801561046257600080fd5b50610334603a5481565b34801561047857600080fd5b5061031d610487366004613314565b611155565b34801561049857600080fd5b506103346104a7366004613355565b61118e565b3480156104b857600080fd5b5061031d6104c73660046133bb565b6111fa565b3480156104d857600080fd5b5061031d6104e73660046132fb565b6113ee565b3480156104f857600080fd5b50610362610507366004613355565b611492565b34801561051857600080fd5b50610334603c5481565b34801561052e57600080fd5b50603d546102c5906001600160a01b031681565b34801561054e57600080fd5b5061026a611812565b34801561056357600080fd5b5061033461181f565b34801561057857600080fd5b5061031d6105873660046132cf565b611833565b34801561059857600080fd5b5061031d61186c565b3480156105ad57600080fd5b506102a06103b33660046132cf565b3480156105c857600080fd5b506103626105d7366004613462565b6119b9565b3480156105e857600080fd5b50610334603b5481565b3480156105fe57600080fd5b5061036261060d3660046132cf565b611dd8565b34801561061e57600080fd5b5061036261062d3660046132fb565b61210b565b34801561063e57600080fd5b5061031d61222a565b34801561065357600080fd5b506103626106623660046132fb565b6122c4565b34801561067357600080fd5b50610334603e5481565b34801561068957600080fd5b50610334610698366004613492565b6123ee565b3480156106a957600080fd5b506103346301e187e081565b3480156106c157600080fd5b5061026a604051806040016040528060058152602001640312e322e360dc1b81525081565b603480546106f3906134c0565b80601f016020809104026020016040519081016040528092919081815260200182805461071f906134c0565b801561076c5780601f106107415761010080835404028352916020019161076c565b820191906000526020600020905b81548152906001019060200180831161074f57829003601f168201915b505050505081565b6000604051631b48e8f360e21b815260040160405180910390fd5b6002546040805163030d028960e21b815290516000926001600160a01b031691630c340a24916004808301926020929190829003018186803b1580156107d457600080fd5b505afa1580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080c919061350b565b905090565b61081961078f565b6001600160a01b0316336001600160a01b03161461084a57604051634b98449160e11b815260040160405180910390fd5b6038548181141561086e57604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527fc58cd6132bb46df23d468939c03dd023b74b509aaa6b04c39d5a6461c65963bd910160405180910390a150603855565b6000806108b8612409565b50509050806039546108ca919061353e565b91505090565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561092157600080fd5b505afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109599190613566565b1561097757604051631b0e923f60e11b815260040160405180910390fd5b600260015414156109a35760405162461bcd60e51b815260040161099a90613581565b60405180910390fd5b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b1580156109ef57600080fd5b505afa158015610a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a279190613566565b610a445760405163a596698b60e01b815260040160405180910390fd5b82610a62576040516310eb483f60e21b815260040160405180910390fd5b610a6a61186c565b600254603d546001600160a01b039182169116610a8685610e0c565b90945092508215610b7a57806001600160a01b031663b2a02ff133846001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ada57600080fd5b505afa158015610aee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b12919061350b565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b158015610b6157600080fd5b505af1158015610b75573d6000803e3d6000fd5b505050505b6000826001600160a01b031663f60928096040518163ffffffff1660e01b815260040160206040518083038186803b158015610bb557600080fd5b505afa158015610bc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bed91906135b8565b90508015610d29576000836001600160a01b031663eaada3826040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3057600080fd5b505afa158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c68919061350b565b6001600160a01b0316638d0dba008488610c818c61118e565b610c8b91906135d1565b6040518363ffffffff1660e01b8152600401610ca89291906135e8565b60206040518083038186803b158015610cc057600080fd5b505afa158015610cd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf891906135b8565b9050600081118015610d0957508181105b15610d27576040516332b9d47360e01b815260040160405180910390fd5b505b604051632770a7eb60e21b81526001600160a01b03831690639dc29fac90610d5790339089906004016135e8565b600060405180830381600087803b158015610d7157600080fd5b505af1158015610d85573d6000803e3d6000fd5b50505050610d938786612479565b60408051878152602081018790529081018590526001600160a01b0388169033907fe02887340b03318642b6755f258294b795be42ed57d4b5d0ef27be3038d8a7649060600160405180910390a35050600180555090939092509050565b600060405163d21ad44b60e01b815260040160405180910390fd5b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e5f57600080fd5b505afa158015610e73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e97919061350b565b6001600160a01b0316637c0f59f46040518163ffffffff1660e01b815260040160206040518083038186803b158015610ecf57600080fd5b505afa158015610ee3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0791906135b8565b905080610f15575091929050565b610f31610f2a82670de0b6b3a764000061353e565b85906126f5565b9250610f3d83856135d1565b915050915091565b603e54801561102b57603d54600254604080516331056e5760e21b815290516001600160a01b03938416936340c10f1993169163c415b95c916004808301926020929190829003018186803b158015610f9d57600080fd5b505afa158015610fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd5919061350b565b836040518363ffffffff1660e01b8152600401610ff39291906135e8565b600060405180830381600087803b15801561100d57600080fd5b505af1158015611021573d6000803e3d6000fd5b50506000603e5550505b50565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561108157600080fd5b505afa158015611095573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b9919061350b565b6001600160a01b0316632a9133c16040518163ffffffff1660e01b815260040160206040518083038186803b1580156110f157600080fd5b505afa158015611105573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112991906135b8565b905080611137575091929050565b6111418482612732565b915061114d82856135d1565b925050915091565b61115d61276a565b6001600160a01b03831661117a5761117582826127a5565b505050565b6111756001600160a01b03841683836128be565b6001600160a01b038116600090815260366020526040812054806111b55750600092915050565b60006111bf612409565b506001600160a01b03861660009081526037602052604090205490925090506111e88284613601565b6111f29190613620565b949350505050565b600054610100900460ff1680611213575060005460ff16155b61122f5760405162461bcd60e51b815260040161099a90613642565b600054610100900460ff16158015611251576000805461ffff19166101011790555b8761126f57604051636e83f50760e01b815260040160405180910390fd5b8561128d576040516330507cff60e11b815260040160405180910390fd5b6001600160a01b0385166112b457604051633cb1fb1f60e11b815260040160405180910390fd5b6001600160a01b0384166112db5760405163013a1b4360e51b815260040160405180910390fd5b6112e3612914565b6112ec85612983565b6112f860348a8a6131be565b50611305603588886131be565b50836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561133f57600080fd5b505afa158015611353573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113779190613690565b603d805442603a55670de0b6b3a7640000603b55603c86905560388590556001600160a81b031960ff93909316600160a81b02929092166001600160b01b0319909216919091176001600160a01b03861617600160a01b17905580156113e3576000805461ff00191690555b505050505050505050565b6113f661078f565b6001600160a01b0316336001600160a01b03161461142757604051634b98449160e11b815260040160405180910390fd5b61142f61186c565b603c548181141561145357604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527f41e376fd99913dea7fda140f5c0bd997515b1a181acc58737320322548ec6e72910160405180910390a150603c55565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b1580156114e357600080fd5b505afa1580156114f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151b9190613566565b1561153957604051631b0e923f60e11b815260040160405180910390fd5b6002600154141561155c5760405162461bcd60e51b815260040161099a90613581565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b1580156115a857600080fd5b505afa1580156115bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e09190613566565b6115fd5760405163a596698b60e01b815260040160405180910390fd5b61160561186c565b61160e8361118e565b91508161162e576040516310eb483f60e21b815260040160405180910390fd5b603d546001600160a01b031660006116458461210b565b93509050821561174d57816001600160a01b031663b2a02ff133600260009054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116ad57600080fd5b505afa1580156116c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e5919061350b565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b15801561173457600080fd5b505af1158015611748573d6000803e3d6000fd5b505050505b604051632770a7eb60e21b81526001600160a01b03831690639dc29fac9061177b90339088906004016135e8565b600060405180830381600087803b15801561179557600080fd5b505af11580156117a9573d6000803e3d6000fd5b505050506117b78585612479565b60408051828152602081018690529081018490526001600160a01b0386169033907fe02887340b03318642b6755f258294b795be42ed57d4b5d0ef27be3038d8a7649060600160405180910390a35050600180559092909150565b603580546106f3906134c0565b60006301e187e0603c5461080c9190613620565b6002546001600160a01b0316331461185e5760405163531f2aa960e11b815260040160405180910390fd5b6118688282612479565b5050565b6000806000611879612409565b9250925092508042141561188c57505050565b42603a5582156111755782603960008282546118a8919061353e565b9091555050603b829055603d54600254604080516331056e5760e21b815290516001600160a01b03938416936340c10f1993169163c415b95c916004808301926020929190829003018186803b15801561190157600080fd5b505afa158015611915573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611939919061350b565b603e54611946908761353e565b6040518363ffffffff1660e01b81526004016119639291906135e8565b600060405180830381600087803b15801561197d57600080fd5b505af192505050801561198e575060015b6119af5782603e60008282546119a4919061353e565b909155506111759050565b6000603e55505050565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b158015611a0a57600080fd5b505afa158015611a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a429190613566565b15611a6057604051631b0e923f60e11b815260040160405180910390fd5b60026001541415611a835760405162461bcd60e51b815260040161099a90613581565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b158015611acf57600080fd5b505afa158015611ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b079190613566565b611b245760405163a596698b60e01b815260040160405180910390fd5b603d60009054906101000a90046001600160a01b03166001600160a01b03166322f3e2d46040518163ffffffff1660e01b815260040160206040518083038186803b158015611b7257600080fd5b505afa158015611b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611baa9190613566565b611bc7576040516303127d9160e31b815260040160405180910390fd5b603d54600160a01b900460ff16611bf15760405163a4382ae360e01b815260040160405180910390fd5b83611c0f576040516310eb483f60e21b815260040160405180910390fd5b611c1761186c565b600254603d5460405163dde3ab9560e01b81523360048201526001600160a01b039283169290911690600090839063dde3ab959060240160a06040518083038186803b158015611c6657600080fd5b505afa158015611c7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9e91906136b3565b9450505050506000836001600160a01b031663eaada3826040518163ffffffff1660e01b815260040160206040518083038186803b158015611cdf57600080fd5b505afa158015611cf3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d17919061350b565b60405163b5e9bef560e01b81529091506001600160a01b0382169063b5e9bef590611d4890869086906004016135e8565b60206040518083038186803b158015611d6057600080fd5b505afa158015611d74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9891906135b8565b881115611db75760405162d11df360e61b815260040160405180910390fd5b611dc5848285338c8c612a31565b6001805590999098509650505050505050565b60025460009081906001600160a01b03163314611e085760405163531f2aa960e11b815260040160405180910390fd5b600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b158015611e5657600080fd5b505afa158015611e6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8e9190613566565b15611eac57604051631b0e923f60e11b815260040160405180910390fd5b60026001541415611ecf5760405162461bcd60e51b815260040161099a90613581565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b158015611f1b57600080fd5b505afa158015611f2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f539190613566565b611f705760405163a596698b60e01b815260040160405180910390fd5b603d60009054906101000a90046001600160a01b03166001600160a01b03166322f3e2d46040518163ffffffff1660e01b815260040160206040518083038186803b158015611fbe57600080fd5b505afa158015611fd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff69190613566565b612013576040516303127d9160e31b815260040160405180910390fd5b603d54600160a01b900460ff1661203d5760405163a4382ae360e01b815260040160405180910390fd5b8261205b576040516310eb483f60e21b815260040160405180910390fd5b61206361186c565b60025460408051637556d1c160e11b815290516001600160a01b03909216916120fb918391829163eaada382916004808301926020929190829003018186803b1580156120af57600080fd5b505afa1580156120c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e7919061350b565b603d546001600160a01b0316888833612a31565b6001805590969095509350505050565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561215e57600080fd5b505afa158015612172573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612196919061350b565b6001600160a01b0316637c0f59f46040518163ffffffff1660e01b815260040160206040518083038186803b1580156121ce57600080fd5b505afa1580156121e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220691906135b8565b905080612214575091929050565b61221e8482612732565b915061114d828561353e565b61223261078f565b6001600160a01b0316336001600160a01b03161461226357604051634b98449160e11b815260040160405180910390fd5b603d54604051600160a01b90910460ff1615808252907fb1d9ceb4467fd05a16930f966760d70eb5926cf0c1c19a7b6bfe59d805c190459060200160405180910390a1603d8054911515600160a01b0260ff60a01b19909216919091179055565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561231757600080fd5b505afa15801561232b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234f919061350b565b6001600160a01b0316632a9133c16040518163ffffffff1660e01b815260040160206040518083038186803b15801561238757600080fd5b505afa15801561239b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123bf91906135b8565b9050806123cd575091929050565b6123e2610f2a82670de0b6b3a76400006135d1565b9250610f3d84846135d1565b600060405163effde13d60e01b815260040160405180910390fd5b603a54603b546000914281101561247457600061242682426135d1565b61242e61181f565b6124389190613601565b905080156124725760395461244e908290612732565b9350612465603b548261273290919063ffffffff16565b61246f908461353e565b92505b505b909192565b816000600260009054906101000a90046001600160a01b03166001600160a01b0316633605b51b6040518163ffffffff1660e01b815260040160006040518083038186803b1580156124ca57600080fd5b505afa1580156124de573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526125069190810190613710565b603d5481519192506001600160a01b03169060005b818110156125b457838181518110612535576125356137d5565b6020908102919091010151604051626cc3c360e61b81526001600160a01b038581166004830152878116602483015290911690631b30f0c090604401600060405180830381600087803b15801561258b57600080fd5b505af115801561259f573d6000803e3d6000fd5b50505050806125ad906137eb565b905061251b565b506001600160a01b0386166125dc5760405163170476af60e21b815260040160405180910390fd5b60006125e78761118e565b90508581101561260a57604051630bba337f60e11b815260040160405180910390fd5b6001600160a01b03871660008181526036602090815260408083208a86039055603b546037835281842055603980548b90039055518981529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a360008611801561268657506126848761118e565b155b156126ec57600254604051631d71be3b60e21b81526001600160a01b038981166004830152909116906375c6f8ec906024015b600060405180830381600087803b1580156126d357600080fd5b505af11580156126e7573d6000803e3d6000fd5b505050505b50505050505050565b600081612703600282613620565b612715670de0b6b3a764000086613601565b61271f919061353e565b6127299190613620565b90505b92915050565b600082158061273f575081155b1561274c5750600061272c565b670de0b6b3a7640000612760600282613620565b6127158486613601565b61277261078f565b6001600160a01b0316336001600160a01b0316146127a357604051634b98449160e11b815260040160405180910390fd5b565b804710156127f55760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161099a565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612842576040519150601f19603f3d011682016040523d82523d6000602084013e612847565b606091505b50509050806111755760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161099a565b6111758363a9059cbb60e01b84846040516024016128dd9291906135e8565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612d19565b600054610100900460ff168061292d575060005460ff16155b6129495760405162461bcd60e51b815260040161099a90613642565b600054610100900460ff1615801561296b576000805461ffff19166101011790555b60018055801561102b576000805461ff001916905550565b600054610100900460ff168061299c575060005460ff16155b6129b85760405162461bcd60e51b815260040161099a90613642565b600054610100900460ff161580156129da576000805461ffff19166101011790555b6001600160a01b038216612a015760405163724f500960e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0384161790558015611868576000805461ff00191690555050565b6000806000886001600160a01b031663f60928096040518163ffffffff1660e01b815260040160206040518083038186803b158015612a6f57600080fd5b505afa158015612a83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa791906135b8565b9050600081118015612b4f5750603d5481906001600160a01b03808b1691638d0dba00911688612ad68b61118e565b612ae0919061353e565b6040518363ffffffff1660e01b8152600401612afd9291906135e8565b60206040518083038186803b158015612b1557600080fd5b505afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d91906135b8565b105b15612b6d57604051637e76d52960e11b815260040160405180910390fd5b612b768561102e565b90935091508115612c5257866001600160a01b03166340c10f198a6001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b158015612bc957600080fd5b505afa158015612bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c01919061350b565b846040518363ffffffff1660e01b8152600401612c1f9291906135e8565b600060405180830381600087803b158015612c3957600080fd5b505af1158015612c4d573d6000803e3d6000fd5b505050505b6040516340c10f1960e01b81526001600160a01b038816906340c10f1990612c8090879087906004016135e8565b600060405180830381600087803b158015612c9a57600080fd5b505af1158015612cae573d6000803e3d6000fd5b50505050612cbc8686612deb565b60408051868152602081018590529081018390526001600160a01b0380861691908816907f197d5e1e72d62df9dad3add8609553402104dbeb4f83f9789e33aeb6723a78399060600160405180910390a350965096945050505050565b6000612d6e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166130449092919063ffffffff16565b8051909150156111755780806020019051810190612d8c9190613566565b6111755760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161099a565b816000600260009054906101000a90046001600160a01b03166001600160a01b0316633605b51b6040518163ffffffff1660e01b815260040160006040518083038186803b158015612e3c57600080fd5b505afa158015612e50573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e789190810190613710565b603d5481519192506001600160a01b03169060005b81811015612f2657838181518110612ea757612ea76137d5565b6020908102919091010151604051626cc3c360e61b81526001600160a01b038581166004830152878116602483015290911690631b30f0c090604401600060405180830381600087803b158015612efd57600080fd5b505af1158015612f11573d6000803e3d6000fd5b5050505080612f1f906137eb565b9050612e8d565b506001600160a01b038616612f4e57604051632b61339160e21b815260040160405180910390fd5b6000612f598761118e565b90508560396000828254612f6d919061353e565b90915550506038546039541115612f9757604051634aed251160e11b815260040160405180910390fd5b612fa1868261353e565b6001600160a01b038816600081815260366020908152604080832094909455603b5460378252848320559251898152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a38015801561300d5750600086115b156126ec57600254604051631dc2da6d60e21b81526001600160a01b0389811660048301529091169063770b69b4906024016126b9565b6060613053848460008561305d565b90505b9392505050565b6060824710156130be5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161099a565b843b61310c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161099a565b600080866001600160a01b031685876040516131289190613806565b60006040518083038185875af1925050503d8060008114613165576040519150601f19603f3d011682016040523d82523d6000602084013e61316a565b606091505b509150915061317a828286613185565b979650505050505050565b60608315613194575081613056565b8251156131a45782518084602001fd5b8160405162461bcd60e51b815260040161099a9190613287565b8280546131ca906134c0565b90600052602060002090601f0160209004810192826131ec5760008555613232565b82601f106132055782800160ff19823516178555613232565b82800160010185558215613232579182015b82811115613232578235825591602001919060010190613217565b5061323e929150613242565b5090565b5b8082111561323e5760008155600101613243565b60005b8381101561327257818101518382015260200161325a565b83811115613281576000848401525b50505050565b60208152600082518060208401526132a6816040850160208701613257565b601f01601f19169190910160400192915050565b6001600160a01b038116811461102b57600080fd5b600080604083850312156132e257600080fd5b82356132ed816132ba565b946020939093013593505050565b60006020828403121561330d57600080fd5b5035919050565b60008060006060848603121561332957600080fd5b8335613334816132ba565b92506020840135613344816132ba565b929592945050506040919091013590565b60006020828403121561336757600080fd5b8135613056816132ba565b60008083601f84011261338457600080fd5b50813567ffffffffffffffff81111561339c57600080fd5b6020830191508360208285010111156133b457600080fd5b9250929050565b60008060008060008060008060c0898b0312156133d757600080fd5b883567ffffffffffffffff808211156133ef57600080fd5b6133fb8c838d01613372565b909a50985060208b013591508082111561341457600080fd5b506134218b828c01613372565b9097509550506040890135613435816132ba565b93506060890135613445816132ba565b979a969950949793969295929450505060808201359160a0013590565b6000806040838503121561347557600080fd5b823591506020830135613487816132ba565b809150509250929050565b600080604083850312156134a557600080fd5b82356134b0816132ba565b91506020830135613487816132ba565b600181811c908216806134d457607f821691505b602082108114156134f557634e487b7160e01b600052602260045260246000fd5b50919050565b8051613506816132ba565b919050565b60006020828403121561351d57600080fd5b8151613056816132ba565b634e487b7160e01b600052601160045260246000fd5b6000821982111561355157613551613528565b500190565b8051801515811461350657600080fd5b60006020828403121561357857600080fd5b61272982613556565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000602082840312156135ca57600080fd5b5051919050565b6000828210156135e3576135e3613528565b500390565b6001600160a01b03929092168252602082015260400190565b600081600019048311821515161561361b5761361b613528565b500290565b60008261363d57634e487b7160e01b600052601260045260246000fd5b500490565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6000602082840312156136a257600080fd5b815160ff8116811461305657600080fd5b600080600080600060a086880312156136cb57600080fd5b6136d486613556565b602087015160408801516060890151608090990151929a91995097965090945092505050565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561372357600080fd5b825167ffffffffffffffff8082111561373b57600080fd5b818501915085601f83011261374f57600080fd5b815181811115613761576137616136fa565b8060051b604051601f19603f83011681018181108582111715613786576137866136fa565b6040529182528482019250838101850191888311156137a457600080fd5b938501935b828510156137c9576137ba856134fb565b845293850193928501926137a9565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b60006000198214156137ff576137ff613528565b5060010190565b60008251613818818460208701613257565b919091019291505056fea2646970667358221220b685175892ef791903c99c1c321a13ec713fb43e10de5eeaa7711f93de841cca64736f6c63430008090033
Deployed Bytecode
0x60806040526004361061021e5760003560e01c8063752a50a611610123578063b696a6ad116100ab578063d38f2ba91161006f578063d38f2ba914610647578063d7da606614610667578063dd62ed3e1461067d578063e6a69ab81461069d578063ffa1ad74146106b55761023c565b8063b696a6ad146105bc578063bb8c631f146105dc578063bfa17656146105f2578063c9dc4b4d14610612578063d2593329146106325761023c565b806395d89b41116100f257806395d89b41146105425780639cc820da146105575780639dc29fac1461056c578063a6afed951461058c578063a9059cbb146105a15761023c565b8063752a50a6146104cc5780637c27383b146104ec5780637c3a00fd1461050c5780638230ecd6146105225761023c565b80632ab4d052116101a65780634754d176116101755780634754d17614610436578063565f3d4f1461045657806362c067671461046c57806370a082311461048c57806374e87e1e146104ac5761023c565b80632ab4d052146103b85780632d4aeea1146103ce578063313ce567146103ee57806336248ab4146104215761023c565b8063172f50a4116101ed578063172f50a4146102fd57806318160ddd1461031f57806322867d781461034257806322f3e2d41461037757806323b872dd146103985761023c565b806306fdde0314610255578063095ea7b3146102805780630c340a24146102b057806316f0115b146102dd5761023c565b3661023c57604051636436c22d60e11b815260040160405180910390fd5b60405163a0152e6360e01b815260040160405180910390fd5b34801561026157600080fd5b5061026a6106e6565b6040516102779190613287565b60405180910390f35b34801561028c57600080fd5b506102a061029b3660046132cf565b610774565b6040519015158152602001610277565b3480156102bc57600080fd5b506102c561078f565b6040516001600160a01b039091168152602001610277565b3480156102e957600080fd5b506002546102c5906001600160a01b031681565b34801561030957600080fd5b5061031d6103183660046132fb565b610811565b005b34801561032b57600080fd5b506103346108ad565b604051908152602001610277565b34801561034e57600080fd5b5061036261035d3660046132cf565b6108d0565b60408051928352602083019190915201610277565b34801561038357600080fd5b50603d546102a090600160a01b900460ff1681565b3480156103a457600080fd5b506102a06103b3366004613314565b610df1565b3480156103c457600080fd5b5061033460385481565b3480156103da57600080fd5b506103626103e93660046132fb565b610e0c565b3480156103fa57600080fd5b50603d5461040f90600160a81b900460ff1681565b60405160ff9091168152602001610277565b34801561042d57600080fd5b5061031d610f45565b34801561044257600080fd5b506103626104513660046132fb565b61102e565b34801561046257600080fd5b50610334603a5481565b34801561047857600080fd5b5061031d610487366004613314565b611155565b34801561049857600080fd5b506103346104a7366004613355565b61118e565b3480156104b857600080fd5b5061031d6104c73660046133bb565b6111fa565b3480156104d857600080fd5b5061031d6104e73660046132fb565b6113ee565b3480156104f857600080fd5b50610362610507366004613355565b611492565b34801561051857600080fd5b50610334603c5481565b34801561052e57600080fd5b50603d546102c5906001600160a01b031681565b34801561054e57600080fd5b5061026a611812565b34801561056357600080fd5b5061033461181f565b34801561057857600080fd5b5061031d6105873660046132cf565b611833565b34801561059857600080fd5b5061031d61186c565b3480156105ad57600080fd5b506102a06103b33660046132cf565b3480156105c857600080fd5b506103626105d7366004613462565b6119b9565b3480156105e857600080fd5b50610334603b5481565b3480156105fe57600080fd5b5061036261060d3660046132cf565b611dd8565b34801561061e57600080fd5b5061036261062d3660046132fb565b61210b565b34801561063e57600080fd5b5061031d61222a565b34801561065357600080fd5b506103626106623660046132fb565b6122c4565b34801561067357600080fd5b50610334603e5481565b34801561068957600080fd5b50610334610698366004613492565b6123ee565b3480156106a957600080fd5b506103346301e187e081565b3480156106c157600080fd5b5061026a604051806040016040528060058152602001640312e322e360dc1b81525081565b603480546106f3906134c0565b80601f016020809104026020016040519081016040528092919081815260200182805461071f906134c0565b801561076c5780601f106107415761010080835404028352916020019161076c565b820191906000526020600020905b81548152906001019060200180831161074f57829003601f168201915b505050505081565b6000604051631b48e8f360e21b815260040160405180910390fd5b6002546040805163030d028960e21b815290516000926001600160a01b031691630c340a24916004808301926020929190829003018186803b1580156107d457600080fd5b505afa1580156107e8573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061080c919061350b565b905090565b61081961078f565b6001600160a01b0316336001600160a01b03161461084a57604051634b98449160e11b815260040160405180910390fd5b6038548181141561086e57604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527fc58cd6132bb46df23d468939c03dd023b74b509aaa6b04c39d5a6461c65963bd910160405180910390a150603855565b6000806108b8612409565b50509050806039546108ca919061353e565b91505090565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b15801561092157600080fd5b505afa158015610935573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109599190613566565b1561097757604051631b0e923f60e11b815260040160405180910390fd5b600260015414156109a35760405162461bcd60e51b815260040161099a90613581565b60405180910390fd5b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b1580156109ef57600080fd5b505afa158015610a03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a279190613566565b610a445760405163a596698b60e01b815260040160405180910390fd5b82610a62576040516310eb483f60e21b815260040160405180910390fd5b610a6a61186c565b600254603d546001600160a01b039182169116610a8685610e0c565b90945092508215610b7a57806001600160a01b031663b2a02ff133846001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b158015610ada57600080fd5b505afa158015610aee573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b12919061350b565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b158015610b6157600080fd5b505af1158015610b75573d6000803e3d6000fd5b505050505b6000826001600160a01b031663f60928096040518163ffffffff1660e01b815260040160206040518083038186803b158015610bb557600080fd5b505afa158015610bc9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610bed91906135b8565b90508015610d29576000836001600160a01b031663eaada3826040518163ffffffff1660e01b815260040160206040518083038186803b158015610c3057600080fd5b505afa158015610c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c68919061350b565b6001600160a01b0316638d0dba008488610c818c61118e565b610c8b91906135d1565b6040518363ffffffff1660e01b8152600401610ca89291906135e8565b60206040518083038186803b158015610cc057600080fd5b505afa158015610cd4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cf891906135b8565b9050600081118015610d0957508181105b15610d27576040516332b9d47360e01b815260040160405180910390fd5b505b604051632770a7eb60e21b81526001600160a01b03831690639dc29fac90610d5790339089906004016135e8565b600060405180830381600087803b158015610d7157600080fd5b505af1158015610d85573d6000803e3d6000fd5b50505050610d938786612479565b60408051878152602081018790529081018590526001600160a01b0388169033907fe02887340b03318642b6755f258294b795be42ed57d4b5d0ef27be3038d8a7649060600160405180910390a35050600180555090939092509050565b600060405163d21ad44b60e01b815260040160405180910390fd5b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b158015610e5f57600080fd5b505afa158015610e73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e97919061350b565b6001600160a01b0316637c0f59f46040518163ffffffff1660e01b815260040160206040518083038186803b158015610ecf57600080fd5b505afa158015610ee3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0791906135b8565b905080610f15575091929050565b610f31610f2a82670de0b6b3a764000061353e565b85906126f5565b9250610f3d83856135d1565b915050915091565b603e54801561102b57603d54600254604080516331056e5760e21b815290516001600160a01b03938416936340c10f1993169163c415b95c916004808301926020929190829003018186803b158015610f9d57600080fd5b505afa158015610fb1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fd5919061350b565b836040518363ffffffff1660e01b8152600401610ff39291906135e8565b600060405180830381600087803b15801561100d57600080fd5b505af1158015611021573d6000803e3d6000fd5b50506000603e5550505b50565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561108157600080fd5b505afa158015611095573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110b9919061350b565b6001600160a01b0316632a9133c16040518163ffffffff1660e01b815260040160206040518083038186803b1580156110f157600080fd5b505afa158015611105573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061112991906135b8565b905080611137575091929050565b6111418482612732565b915061114d82856135d1565b925050915091565b61115d61276a565b6001600160a01b03831661117a5761117582826127a5565b505050565b6111756001600160a01b03841683836128be565b6001600160a01b038116600090815260366020526040812054806111b55750600092915050565b60006111bf612409565b506001600160a01b03861660009081526037602052604090205490925090506111e88284613601565b6111f29190613620565b949350505050565b600054610100900460ff1680611213575060005460ff16155b61122f5760405162461bcd60e51b815260040161099a90613642565b600054610100900460ff16158015611251576000805461ffff19166101011790555b8761126f57604051636e83f50760e01b815260040160405180910390fd5b8561128d576040516330507cff60e11b815260040160405180910390fd5b6001600160a01b0385166112b457604051633cb1fb1f60e11b815260040160405180910390fd5b6001600160a01b0384166112db5760405163013a1b4360e51b815260040160405180910390fd5b6112e3612914565b6112ec85612983565b6112f860348a8a6131be565b50611305603588886131be565b50836001600160a01b031663313ce5676040518163ffffffff1660e01b815260040160206040518083038186803b15801561133f57600080fd5b505afa158015611353573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113779190613690565b603d805442603a55670de0b6b3a7640000603b55603c86905560388590556001600160a81b031960ff93909316600160a81b02929092166001600160b01b0319909216919091176001600160a01b03861617600160a01b17905580156113e3576000805461ff00191690555b505050505050505050565b6113f661078f565b6001600160a01b0316336001600160a01b03161461142757604051634b98449160e11b815260040160405180910390fd5b61142f61186c565b603c548181141561145357604051630333a68160e41b815260040160405180910390fd5b60408051828152602081018490527f41e376fd99913dea7fda140f5c0bd997515b1a181acc58737320322548ec6e72910160405180910390a150603c55565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b1580156114e357600080fd5b505afa1580156114f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061151b9190613566565b1561153957604051631b0e923f60e11b815260040160405180910390fd5b6002600154141561155c5760405162461bcd60e51b815260040161099a90613581565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b1580156115a857600080fd5b505afa1580156115bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115e09190613566565b6115fd5760405163a596698b60e01b815260040160405180910390fd5b61160561186c565b61160e8361118e565b91508161162e576040516310eb483f60e21b815260040160405180910390fd5b603d546001600160a01b031660006116458461210b565b93509050821561174d57816001600160a01b031663b2a02ff133600260009054906101000a90046001600160a01b03166001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b1580156116ad57600080fd5b505afa1580156116c1573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116e5919061350b565b6040516001600160e01b031960e085901b1681526001600160a01b0392831660048201529116602482015260448101869052606401600060405180830381600087803b15801561173457600080fd5b505af1158015611748573d6000803e3d6000fd5b505050505b604051632770a7eb60e21b81526001600160a01b03831690639dc29fac9061177b90339088906004016135e8565b600060405180830381600087803b15801561179557600080fd5b505af11580156117a9573d6000803e3d6000fd5b505050506117b78585612479565b60408051828152602081018690529081018490526001600160a01b0386169033907fe02887340b03318642b6755f258294b795be42ed57d4b5d0ef27be3038d8a7649060600160405180910390a35050600180559092909150565b603580546106f3906134c0565b60006301e187e0603c5461080c9190613620565b6002546001600160a01b0316331461185e5760405163531f2aa960e11b815260040160405180910390fd5b6118688282612479565b5050565b6000806000611879612409565b9250925092508042141561188c57505050565b42603a5582156111755782603960008282546118a8919061353e565b9091555050603b829055603d54600254604080516331056e5760e21b815290516001600160a01b03938416936340c10f1993169163c415b95c916004808301926020929190829003018186803b15801561190157600080fd5b505afa158015611915573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611939919061350b565b603e54611946908761353e565b6040518363ffffffff1660e01b81526004016119639291906135e8565b600060405180830381600087803b15801561197d57600080fd5b505af192505050801561198e575060015b6119af5782603e60008282546119a4919061353e565b909155506111759050565b6000603e55505050565b600080600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b158015611a0a57600080fd5b505afa158015611a1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a429190613566565b15611a6057604051631b0e923f60e11b815260040160405180910390fd5b60026001541415611a835760405162461bcd60e51b815260040161099a90613581565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b158015611acf57600080fd5b505afa158015611ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611b079190613566565b611b245760405163a596698b60e01b815260040160405180910390fd5b603d60009054906101000a90046001600160a01b03166001600160a01b03166322f3e2d46040518163ffffffff1660e01b815260040160206040518083038186803b158015611b7257600080fd5b505afa158015611b86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611baa9190613566565b611bc7576040516303127d9160e31b815260040160405180910390fd5b603d54600160a01b900460ff16611bf15760405163a4382ae360e01b815260040160405180910390fd5b83611c0f576040516310eb483f60e21b815260040160405180910390fd5b611c1761186c565b600254603d5460405163dde3ab9560e01b81523360048201526001600160a01b039283169290911690600090839063dde3ab959060240160a06040518083038186803b158015611c6657600080fd5b505afa158015611c7a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c9e91906136b3565b9450505050506000836001600160a01b031663eaada3826040518163ffffffff1660e01b815260040160206040518083038186803b158015611cdf57600080fd5b505afa158015611cf3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d17919061350b565b60405163b5e9bef560e01b81529091506001600160a01b0382169063b5e9bef590611d4890869086906004016135e8565b60206040518083038186803b158015611d6057600080fd5b505afa158015611d74573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d9891906135b8565b881115611db75760405162d11df360e61b815260040160405180910390fd5b611dc5848285338c8c612a31565b6001805590999098509650505050505050565b60025460009081906001600160a01b03163314611e085760405163531f2aa960e11b815260040160405180910390fd5b600260009054906101000a90046001600160a01b03166001600160a01b031663ecf3a3f96040518163ffffffff1660e01b815260040160206040518083038186803b158015611e5657600080fd5b505afa158015611e6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e8e9190613566565b15611eac57604051631b0e923f60e11b815260040160405180910390fd5b60026001541415611ecf5760405162461bcd60e51b815260040161099a90613581565b6002600181905554603d54604051631a0dd00b60e01b81526001600160a01b039182166004820152911690631a0dd00b9060240160206040518083038186803b158015611f1b57600080fd5b505afa158015611f2f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f539190613566565b611f705760405163a596698b60e01b815260040160405180910390fd5b603d60009054906101000a90046001600160a01b03166001600160a01b03166322f3e2d46040518163ffffffff1660e01b815260040160206040518083038186803b158015611fbe57600080fd5b505afa158015611fd2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ff69190613566565b612013576040516303127d9160e31b815260040160405180910390fd5b603d54600160a01b900460ff1661203d5760405163a4382ae360e01b815260040160405180910390fd5b8261205b576040516310eb483f60e21b815260040160405180910390fd5b61206361186c565b60025460408051637556d1c160e11b815290516001600160a01b03909216916120fb918391829163eaada382916004808301926020929190829003018186803b1580156120af57600080fd5b505afa1580156120c3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120e7919061350b565b603d546001600160a01b0316888833612a31565b6001805590969095509350505050565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561215e57600080fd5b505afa158015612172573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612196919061350b565b6001600160a01b0316637c0f59f46040518163ffffffff1660e01b815260040160206040518083038186803b1580156121ce57600080fd5b505afa1580156121e2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061220691906135b8565b905080612214575091929050565b61221e8482612732565b915061114d828561353e565b61223261078f565b6001600160a01b0316336001600160a01b03161461226357604051634b98449160e11b815260040160405180910390fd5b603d54604051600160a01b90910460ff1615808252907fb1d9ceb4467fd05a16930f966760d70eb5926cf0c1c19a7b6bfe59d805c190459060200160405180910390a1603d8054911515600160a01b0260ff60a01b19909216919091179055565b6000806000600260009054906101000a90046001600160a01b03166001600160a01b0316634066fdea6040518163ffffffff1660e01b815260040160206040518083038186803b15801561231757600080fd5b505afa15801561232b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061234f919061350b565b6001600160a01b0316632a9133c16040518163ffffffff1660e01b815260040160206040518083038186803b15801561238757600080fd5b505afa15801561239b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123bf91906135b8565b9050806123cd575091929050565b6123e2610f2a82670de0b6b3a76400006135d1565b9250610f3d84846135d1565b600060405163effde13d60e01b815260040160405180910390fd5b603a54603b546000914281101561247457600061242682426135d1565b61242e61181f565b6124389190613601565b905080156124725760395461244e908290612732565b9350612465603b548261273290919063ffffffff16565b61246f908461353e565b92505b505b909192565b816000600260009054906101000a90046001600160a01b03166001600160a01b0316633605b51b6040518163ffffffff1660e01b815260040160006040518083038186803b1580156124ca57600080fd5b505afa1580156124de573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526125069190810190613710565b603d5481519192506001600160a01b03169060005b818110156125b457838181518110612535576125356137d5565b6020908102919091010151604051626cc3c360e61b81526001600160a01b038581166004830152878116602483015290911690631b30f0c090604401600060405180830381600087803b15801561258b57600080fd5b505af115801561259f573d6000803e3d6000fd5b50505050806125ad906137eb565b905061251b565b506001600160a01b0386166125dc5760405163170476af60e21b815260040160405180910390fd5b60006125e78761118e565b90508581101561260a57604051630bba337f60e11b815260040160405180910390fd5b6001600160a01b03871660008181526036602090815260408083208a86039055603b546037835281842055603980548b90039055518981529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a360008611801561268657506126848761118e565b155b156126ec57600254604051631d71be3b60e21b81526001600160a01b038981166004830152909116906375c6f8ec906024015b600060405180830381600087803b1580156126d357600080fd5b505af11580156126e7573d6000803e3d6000fd5b505050505b50505050505050565b600081612703600282613620565b612715670de0b6b3a764000086613601565b61271f919061353e565b6127299190613620565b90505b92915050565b600082158061273f575081155b1561274c5750600061272c565b670de0b6b3a7640000612760600282613620565b6127158486613601565b61277261078f565b6001600160a01b0316336001600160a01b0316146127a357604051634b98449160e11b815260040160405180910390fd5b565b804710156127f55760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161099a565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612842576040519150601f19603f3d011682016040523d82523d6000602084013e612847565b606091505b50509050806111755760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161099a565b6111758363a9059cbb60e01b84846040516024016128dd9291906135e8565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612d19565b600054610100900460ff168061292d575060005460ff16155b6129495760405162461bcd60e51b815260040161099a90613642565b600054610100900460ff1615801561296b576000805461ffff19166101011790555b60018055801561102b576000805461ff001916905550565b600054610100900460ff168061299c575060005460ff16155b6129b85760405162461bcd60e51b815260040161099a90613642565b600054610100900460ff161580156129da576000805461ffff19166101011790555b6001600160a01b038216612a015760405163724f500960e01b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0384161790558015611868576000805461ff00191690555050565b6000806000886001600160a01b031663f60928096040518163ffffffff1660e01b815260040160206040518083038186803b158015612a6f57600080fd5b505afa158015612a83573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aa791906135b8565b9050600081118015612b4f5750603d5481906001600160a01b03808b1691638d0dba00911688612ad68b61118e565b612ae0919061353e565b6040518363ffffffff1660e01b8152600401612afd9291906135e8565b60206040518083038186803b158015612b1557600080fd5b505afa158015612b29573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b4d91906135b8565b105b15612b6d57604051637e76d52960e11b815260040160405180910390fd5b612b768561102e565b90935091508115612c5257866001600160a01b03166340c10f198a6001600160a01b031663c415b95c6040518163ffffffff1660e01b815260040160206040518083038186803b158015612bc957600080fd5b505afa158015612bdd573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c01919061350b565b846040518363ffffffff1660e01b8152600401612c1f9291906135e8565b600060405180830381600087803b158015612c3957600080fd5b505af1158015612c4d573d6000803e3d6000fd5b505050505b6040516340c10f1960e01b81526001600160a01b038816906340c10f1990612c8090879087906004016135e8565b600060405180830381600087803b158015612c9a57600080fd5b505af1158015612cae573d6000803e3d6000fd5b50505050612cbc8686612deb565b60408051868152602081018590529081018390526001600160a01b0380861691908816907f197d5e1e72d62df9dad3add8609553402104dbeb4f83f9789e33aeb6723a78399060600160405180910390a350965096945050505050565b6000612d6e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166130449092919063ffffffff16565b8051909150156111755780806020019051810190612d8c9190613566565b6111755760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b606482015260840161099a565b816000600260009054906101000a90046001600160a01b03166001600160a01b0316633605b51b6040518163ffffffff1660e01b815260040160006040518083038186803b158015612e3c57600080fd5b505afa158015612e50573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612e789190810190613710565b603d5481519192506001600160a01b03169060005b81811015612f2657838181518110612ea757612ea76137d5565b6020908102919091010151604051626cc3c360e61b81526001600160a01b038581166004830152878116602483015290911690631b30f0c090604401600060405180830381600087803b158015612efd57600080fd5b505af1158015612f11573d6000803e3d6000fd5b5050505080612f1f906137eb565b9050612e8d565b506001600160a01b038616612f4e57604051632b61339160e21b815260040160405180910390fd5b6000612f598761118e565b90508560396000828254612f6d919061353e565b90915550506038546039541115612f9757604051634aed251160e11b815260040160405180910390fd5b612fa1868261353e565b6001600160a01b038816600081815260366020908152604080832094909455603b5460378252848320559251898152919290917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a38015801561300d5750600086115b156126ec57600254604051631dc2da6d60e21b81526001600160a01b0389811660048301529091169063770b69b4906024016126b9565b6060613053848460008561305d565b90505b9392505050565b6060824710156130be5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b606482015260840161099a565b843b61310c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161099a565b600080866001600160a01b031685876040516131289190613806565b60006040518083038185875af1925050503d8060008114613165576040519150601f19603f3d011682016040523d82523d6000602084013e61316a565b606091505b509150915061317a828286613185565b979650505050505050565b60608315613194575081613056565b8251156131a45782518084602001fd5b8160405162461bcd60e51b815260040161099a9190613287565b8280546131ca906134c0565b90600052602060002090601f0160209004810192826131ec5760008555613232565b82601f106132055782800160ff19823516178555613232565b82800160010185558215613232579182015b82811115613232578235825591602001919060010190613217565b5061323e929150613242565b5090565b5b8082111561323e5760008155600101613243565b60005b8381101561327257818101518382015260200161325a565b83811115613281576000848401525b50505050565b60208152600082518060208401526132a6816040850160208701613257565b601f01601f19169190910160400192915050565b6001600160a01b038116811461102b57600080fd5b600080604083850312156132e257600080fd5b82356132ed816132ba565b946020939093013593505050565b60006020828403121561330d57600080fd5b5035919050565b60008060006060848603121561332957600080fd5b8335613334816132ba565b92506020840135613344816132ba565b929592945050506040919091013590565b60006020828403121561336757600080fd5b8135613056816132ba565b60008083601f84011261338457600080fd5b50813567ffffffffffffffff81111561339c57600080fd5b6020830191508360208285010111156133b457600080fd5b9250929050565b60008060008060008060008060c0898b0312156133d757600080fd5b883567ffffffffffffffff808211156133ef57600080fd5b6133fb8c838d01613372565b909a50985060208b013591508082111561341457600080fd5b506134218b828c01613372565b9097509550506040890135613435816132ba565b93506060890135613445816132ba565b979a969950949793969295929450505060808201359160a0013590565b6000806040838503121561347557600080fd5b823591506020830135613487816132ba565b809150509250929050565b600080604083850312156134a557600080fd5b82356134b0816132ba565b91506020830135613487816132ba565b600181811c908216806134d457607f821691505b602082108114156134f557634e487b7160e01b600052602260045260246000fd5b50919050565b8051613506816132ba565b919050565b60006020828403121561351d57600080fd5b8151613056816132ba565b634e487b7160e01b600052601160045260246000fd5b6000821982111561355157613551613528565b500190565b8051801515811461350657600080fd5b60006020828403121561357857600080fd5b61272982613556565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6000602082840312156135ca57600080fd5b5051919050565b6000828210156135e3576135e3613528565b500390565b6001600160a01b03929092168252602082015260400190565b600081600019048311821515161561361b5761361b613528565b500290565b60008261363d57634e487b7160e01b600052601260045260246000fd5b500490565b6020808252602e908201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160408201526d191e481a5b9a5d1a585b1a5e995960921b606082015260800190565b6000602082840312156136a257600080fd5b815160ff8116811461305657600080fd5b600080600080600060a086880312156136cb57600080fd5b6136d486613556565b602087015160408801516060890151608090990151929a91995097965090945092505050565b634e487b7160e01b600052604160045260246000fd5b6000602080838503121561372357600080fd5b825167ffffffffffffffff8082111561373b57600080fd5b818501915085601f83011261374f57600080fd5b815181811115613761576137616136fa565b8060051b604051601f19603f83011681018181108582111715613786576137866136fa565b6040529182528482019250838101850191888311156137a457600080fd5b938501935b828510156137c9576137ba856134fb565b845293850193928501926137a9565b98975050505050505050565b634e487b7160e01b600052603260045260246000fd5b60006000198214156137ff576137ff613528565b5060010190565b60008251613818818460208701613257565b919091019291505056fea2646970667358221220b685175892ef791903c99c1c321a13ec713fb43e10de5eeaa7711f93de841cca64736f6c63430008090033
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.