Overview
ETH Balance
0 ETH
Eth Value
$0.00Token Holdings
More Info
Private Name Tags
ContractCreator
Latest 5 from a total of 5 transactions
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
StakedEthVault
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 9999 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "contracts/unstable/interfaces/InUSD.sol"; import "contracts/unstable/interfaces/IConfigurator.sol"; import "contracts/unstable/interfaces/IZkOracle.sol"; import "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; contract StakedEthVault is ReentrancyGuard { using SafeERC20 for IERC20; InUSD public immutable nUSD; IERC20 public immutable collateralAsset; IConfigurator public immutable configurator; uint256 public poolTotalCirculation; // Maybe using struct packing would save some gas on critical functions mapping(address => uint256) public depositedAsset; mapping(address => uint256) public borrowed; mapping(address => uint256) public feeStored; mapping(address => uint256) public feeUpdatedAt; event DepositEther(address indexed onBehalfOf, address asset, uint256 etherAmount, uint256 assetAmount, uint256 timestamp); event DepositAsset(address indexed onBehalfOf, address asset, uint256 amount, uint256 timestamp); event WithdrawAsset(address indexed sponsor, address asset, address indexed onBehalfOf, uint256 amount, uint256 timestamp); event Mint(address indexed sponsor, address indexed onBehalfOf, uint256 amount, uint256 originationFee, uint256 timestamp); event Burn(address indexed sponsor, address indexed onBehalfOf, uint256 amount, uint256 timestamp); event LiquidationRecord(address indexed provider, address indexed keeper, address indexed onBehalfOf, uint256 nusdAmount, uint256 LiquidateAssetAmount, uint256 keeperReward, bool superLiquidation); event Redemption(address indexed caller, address indexed provider, uint256 nusdToProtocol, uint256 nusdToRepay, uint256 collateralReceived); // MultiRewards farming functionality struct Reward { uint256 rewardsDuration; uint256 periodFinish; uint256 rewardRate; uint256 lastUpdateTime; uint256 rewardPerTokenStored; } mapping(address => Reward) public rewardData; address[] public rewardTokens; mapping(address => mapping(address => uint256)) public userRewardPerTokenPaid; mapping(address => mapping(address => uint256)) public rewards; event RewardAdded(uint256 reward); event RewardPaid(address indexed user, address indexed rewardsToken, uint256 reward); event RewardsDurationUpdated(address token, uint256 newDuration); event Recovered(address token, uint256 amount); //constructor constructor(address _collateral, address _configurator) { collateralAsset = IERC20(_collateral); configurator = IConfigurator(_configurator); nUSD = InUSD(configurator.nUSD()); } function totalDepositedAsset() public view virtual returns (uint256) { return collateralAsset.balanceOf(address(this)); } /** * @notice Deposit staked ETH, update the interest distribution, can mint nUSD directly * Emits a `DepositAsset` event. * * Requirements: * - `assetAmount` Must be higher than 0. * - `mintAmount` Send 0 if deposit only, no mint of nUSD */ function depositAssetToMint(uint256 assetAmount, uint256 mintAmount) external updateReward(msg.sender) virtual { require(assetAmount > 0, "Deposit should be > 0"); collateralAsset.safeTransferFrom(msg.sender, address(this), assetAmount); depositedAsset[msg.sender] += assetAmount; if (mintAmount > 0) { _mintnUSD(msg.sender, msg.sender, mintAmount); } emit DepositAsset(msg.sender, address(collateralAsset), assetAmount, block.timestamp); } /** * @notice Withdraw collateral assets to an address * Emits a `WithdrawAsset` event. * * Requirements: * - `onBehalfOf` cannot be the zero address. * - `amount` Must be higher than 0. * * @dev Withdraw collateral. Check user’s collateral ratio after withdrawal, should be higher than `safeCollateralRatio` */ function withdraw(address onBehalfOf, uint256 amount) external updateReward(msg.sender) virtual { require(onBehalfOf != address(0), "to zero address"); require(amount != 0, "zero amount"); _withdraw(msg.sender, onBehalfOf, amount); } /** * @notice The mint amount number of nUSD is minted to the address * Emits a `Mint` event. * * Requirements: * - `onBehalfOf` cannot be the zero address. */ function mint(address onBehalfOf, uint256 amount) external virtual { require(onBehalfOf != address(0), "to zero address"); require(amount != 0, "zero amount"); _mintnUSD(msg.sender, onBehalfOf, amount); } /** * @notice Burn the amount of nUSD and payback the amount of minted nUSD * Emits a `Burn` event. * Requirements: * - `onBehalfOf` cannot be the zero address. * - `amount` Must be higher than 0. * @dev Calling the internal`_repay`function. */ function burn(address onBehalfOf, uint256 amount) external virtual { require(onBehalfOf != address(0), "to zero address"); require(amount != 0, "zero amount"); _repay(msg.sender, onBehalfOf, amount); } /** * @notice Keeper liquidates borrowers whose collateral ratio is below badCollateralRatio, using nUSD provided by Liquidation Provider. * * Requirements: * - onBehalfOf Collateral Ratio should be below badCollateralRatio * - assetAmount should be less than 50% of collateral - If liquidating 50% of the collateral doesn't bring the position to health, you should allow a full liquidation. * - provider should authorize Unstable to utilize nUSD * @dev After liquidation, borrower's debt is reduced by assetAmount * assetPrice, providers and keepers can receive up to an additional 10% liquidation reward. */ //TODO: logic for full liquidation in case 50% doesn't bring to health function liquidation(address provider, address debtor, uint256 assetAmount) external updateReward(provider) virtual { uint256 assetPrice = getAssetPrice(); uint256 debtorCollateralRatio = getCollateralRatio(debtor); require(debtorCollateralRatio < configurator.getBadCollateralRatio(address(this)), "Borrowers collateral ratio should below badCollateralRatio"); require(assetAmount * 2 <= depositedAsset[debtor], "a max of 50% collateral can be liquidated"); require(nUSD.allowance(provider, address(this)) != 0 || msg.sender == provider, "provider should authorize to provide liquidation nUSD"); uint256 nusdAmount = assetAmount * assetPrice / 1e18; _repay(provider, debtor, nusdAmount); uint256 reducedAsset = assetAmount; //If collateralRatio is 100-110%, liquidator bonus is less than 10% if(debtorCollateralRatio > 100_00 && debtorCollateralRatio < 110_00) { reducedAsset = assetAmount * debtorCollateralRatio / 100_00; } //If collateralRatio is more than 110%, 10% liquidation bonus if(debtorCollateralRatio >= 110_00) { reducedAsset = assetAmount * 11 / 10; //10% bonus } depositedAsset[debtor] -= reducedAsset; uint256 rewardToKeeper; //Send keeper reward <- Which is taken from the liquidator payment. uint256 keeperReward = configurator.getKeeperReward(address(this)); if (msg.sender != provider && debtorCollateralRatio >= 100_00 + keeperReward) { rewardToKeeper = assetAmount * keeperReward / 100_00; collateralAsset.safeTransfer(msg.sender, rewardToKeeper); } collateralAsset.safeTransfer(provider, reducedAsset - rewardToKeeper); emit LiquidationRecord(provider, msg.sender, debtor, nusdAmount, reducedAsset, rewardToKeeper, false); } /** * @notice Choose a Redemption Provider, redeem `nusdAmount` of nUSD and get 1:1 value of collateral minus fees * Emits a `Redemption` event. * * *Requirements: * - `provider` must be a Redemption Provider * - `provider`debt must equal to or above`nusdAmount` */ function redemption(address provider, uint256 nusdAmount, uint256 minReceiveAmount) external updateReward(provider) virtual { require(provider != msg.sender, "no self redeem"); //TODO: is this necessary? (, , uint256 nusdToProtocol, uint256 nusdToRepay, , uint256 collateralReceived) = calculateRedemption(provider, nusdAmount); require(collateralReceived >= minReceiveAmount, "Collateral amount is less than minReceiveAmount"); if(nusdToProtocol > 0) { nUSD.transferFrom(msg.sender, address(configurator), nusdToProtocol); } _repay(msg.sender, provider, nusdToRepay); depositedAsset[provider] -= collateralReceived; collateralAsset.safeTransfer(msg.sender, collateralReceived); emit Redemption(msg.sender, provider, nusdToProtocol, nusdToRepay, collateralReceived); } /** * @notice Calculate redemption for a provider and nusdAmount */ function calculateRedemption(address provider, uint256 nusdAmount) public view returns (uint256 providerFee, uint256 protocolFee, uint256 nusdToProtocol, uint256 nusdToRepay, uint256 nusdToConvert, uint256 collateralReceived) { // providerFee, protocolFee and nusdToConvert are never used. require(nusdAmount > 0, "redemption should be > 0"); require(getBorrowedOf(provider) >= nusdAmount, "nusdAmount cannot surpass providers debt"); uint256 assetPrice = getAssetPrice(); uint256 providerCollateralRatio = (depositedAsset[provider] * assetPrice * 10_000) / getBorrowedOf(provider) / 1e18; (providerFee, protocolFee) = configurator.getRedemptionFee(address(this), providerCollateralRatio); nusdToProtocol = nusdAmount * protocolFee / 10_000; nusdToRepay = nusdAmount - nusdToProtocol; nusdToConvert = nusdToRepay * (10_000 - providerFee) / 10_000; collateralReceived = nusdToConvert * 1e18 / assetPrice; } /** * @notice Get the maximum amount of nUSD that can be redeemed from a specified provider */ function getRedeemableAmount(address provider) public view returns(uint256) { IConfigurator.RedemptionConfig memory config = configurator.getRedemptionConfig(address(this)); if(!config.enabled) return 0; if(getBorrowedOf(provider) == 0) return 0; if(getCollateralRatio(provider) > config.maxCollateralRatio || getCollateralRatio(provider) < 10_000) return 0; return getBorrowedOf(provider); } /** * @dev Refresh accrued interest fee before adding totalSupply. Check providers collateralRatio cannot below `safeCollateralRatio`after minting. Collect origination fee. */ function _mintnUSD(address _provider, address _onBehalfOf, uint256 _mintAmount) internal virtual { require(!isDepegged(), "Collateral is depegged, minting paused"); require(poolTotalCirculation + _mintAmount <= configurator.mintVaultMaxSupply(address(this)), "exceeds cap"); _updateFee(_provider); borrowed[_provider] += _mintAmount; uint256 originationFee = getOriginationFee(_mintAmount); nUSD.mint(address(configurator), originationFee); nUSD.mint(_onBehalfOf, _mintAmount - originationFee); poolTotalCirculation += _mintAmount; require(_checkHealth(_provider), "user is unhealthy after mint"); emit Mint(_provider, _onBehalfOf, _mintAmount, originationFee, block.timestamp); } /** * @dev Calculate origination fee based on pool utilization. */ function getOriginationFee(uint256 _mintAmount) public view returns(uint256) { (uint256 minOriginationFee, uint256 maxOriginationFee) = configurator.getOriginationFee(address(this)); uint256 poolUtilization = (poolTotalCirculation + _mintAmount) * 1e18 / configurator.mintVaultMaxSupply(address(this)); return (maxOriginationFee - minOriginationFee) * poolUtilization * _mintAmount / 1e18 / 10000; } /** * @notice Burn _provideramount nUSD to payback minted nUSD for _onBehalfOf. * @dev Refresh accrued interest fee before reducing nUSDCirculation. */ function _repay(address _provider, address _onBehalfOf, uint256 _amount) internal virtual { // _amount can be more than the amount owed, and the excess will be ignored. _updateFee(_onBehalfOf); uint256 _feeStored = feeStored[_onBehalfOf]; uint256 _toRepay = _min(borrowed[_onBehalfOf] + _feeStored, _amount); if(_toRepay > _feeStored) { if(_feeStored > 0) { nUSD.transferFrom(_provider, address(configurator), _feeStored); feeStored[_onBehalfOf] = 0; } // First we repay the fees, then principal with the rest nUSD.burn(_provider, _toRepay - _feeStored); borrowed[_onBehalfOf] -= _toRepay - _feeStored; poolTotalCirculation -= _toRepay - _feeStored; } else { // The user provided an amount to repay below the fees owed, so we only repay fees and no principal. nUSD.transferFrom(_provider, address(configurator), _toRepay); feeStored[_onBehalfOf] = _feeStored - _toRepay; } emit Burn(_provider, _onBehalfOf, _toRepay, block.timestamp); } function _withdraw(address _provider, address _onBehalfOf, uint256 _amount) internal virtual { require(depositedAsset[_provider] >= _amount, "Withdraw amount exceeds deposited amount."); depositedAsset[_provider] -= _amount; collateralAsset.safeTransfer(_onBehalfOf, _amount); if (getBorrowedOf(_provider) > 0) { require(_checkHealth(_provider), "User is unhealthy after withdraw"); } emit WithdrawAsset(_provider, address(collateralAsset), _onBehalfOf, _amount, block.timestamp); } /** * @param user The address of the user. * @dev Get USD value of current collateral asset and minted nUSD through price oracle / Collateral asset USD value must higher than safe Collateral Ratio. * @return true if the user is healthy, false otherwise. */ function _checkHealth(address user) internal view returns(bool) { uint256 price = getAssetPrice(); if (((depositedAsset[user] * price * 10_000) / getBorrowedOf(user)) < configurator.getSafeCollateralRatio(address(this))) { return false; } else { return true; } } function _updateFee(address user) internal { if (block.timestamp > feeUpdatedAt[user]) { feeStored[user] += _newFee(user); feeUpdatedAt[user] = block.timestamp; } } function _newFee(address user) internal view returns (uint256) { uint256 secondsInYear = 86_400 * 365; uint256 secondsSinceLastFee = block.timestamp - feeUpdatedAt[user]; return borrowed[user] * configurator.borrowApr(address(this)) * secondsSinceLastFee / secondsInYear / 10_000; } /** * @dev Return configured oracle address */ function getZkOracle() public view returns (address) { return configurator.zkOracleAddress(address(collateralAsset)); } /** * @dev Return rate of collateral asset in ETH terms through zkOracle. */ function getMarketRate() public view returns (uint256) { IZkOracle zkOracle = IZkOracle(getZkOracle()); return zkOracle.getMarketRate(); } /** * @dev Return redemption rate of collateral asset in ETH terms through zkOracle. */ function getRedemptionRate() public view returns (uint256) { IZkOracle zkOracle = IZkOracle(getZkOracle()); return zkOracle.getRedemptionRate(); } /** * @dev Return value of collateral asset in underlying terms through zkOracle. * @notice This will have a market rate and also redemption rate */ function getAssetToUnderlyingRate() public view returns (uint256) { uint256 redemptionRate = getRedemptionRate(); if(configurator.useMarketRate(address(this))) { uint256 marketRate = getMarketRate(); if(marketRate == 0) { return redemptionRate; //In case market price oracle is broken, default to redemptionRate } else { // If chainlink prices flash crash below minAnswer, you will get stale prices. I'm not sure you can do much about that. return _min(marketRate, redemptionRate); //even if marketRate is toggled, don't allow over-peg valuation } } else { return redemptionRate; } } /** * @dev Check if the collateral asset is depegged according to threshold set in configurator */ function isDepegged() public view returns (bool) { uint256 marketRate = getMarketRate(); if(marketRate == 0) { return false; //if market rate oracle is zero, presume market rate is not configured and take no action } uint256 redemptionRate = getRedemptionRate(); uint256 minMarketRate = redemptionRate * (10_000 - configurator.getDepegThreshold(address(this))) / 10_000; return marketRate < minMarketRate; } /** * @dev Return value of underlying asset in USD terms. * @notice This *should* only be market rate, returns chainlink ETH price as default */ function getUnderlyingToUsdPrice() public view returns (uint256) { (,int price, , , ) = AggregatorV3Interface(configurator.etherOracle()).latestRoundData(); return uint256(price) * 1e10; } /** * @dev Get USD value of collateral asset */ function getAssetPrice() public view returns (uint256) { return getAssetToUnderlyingRate() * getUnderlyingToUsdPrice() / 1e18; } /** * @dev Returns the current borrowing amount for the user, including borrowed shares and accumulated fees. * @param user The address of the user. * @return The total borrowing amount for the user. */ function getBorrowedOf(address user) public view returns (uint256) { return borrowed[user] + feeStored[user] + _newFee(user); } function getPoolTotalCirculation() public view returns (uint256) { return poolTotalCirculation; } function getAsset() external view returns (address) { return address(collateralAsset); } //View functions - frontend friendly function getCollateralRatio(address user) public view returns (uint256) { if (getBorrowedOf(user) == 0) return 10_000 * 1e18; //really big number return (depositedAsset[user] * getAssetPrice() * 10_000) / getBorrowedOf(user) / 1e18; } function getOverallCollateralRatio() public view returns (uint256) { return (totalDepositedAsset() * getAssetPrice() * 10_000) / poolTotalCirculation / 1e18; } function getLiquidateableAmount(address user) public view returns (uint256 collateralAmount, uint256 nUsdAmount) { if (getCollateralRatio(user) > configurator.getSafeCollateralRatio(address(this))) return (0, 0); collateralAmount = depositedAsset[user] / 2; nUsdAmount = collateralAmount * getAssetPrice() / 1e18; } function getLiquidateFund(address user) public view returns (uint256 nusdAmount) { InUSD token = InUSD(configurator.nUSD()); uint256 approval = token.allowance(user, address(this)); if (approval == 0) return 0; uint256 bal = token.balanceOf(user); nusdAmount = approval > bal ? bal : approval; // You have a _min function } function getWithdrawableAmount(address user) public view returns (uint256) { if (getBorrowedOf(user) == 0) return depositedAsset[user]; uint256 safeCollateralRatio = configurator.getSafeCollateralRatio(address(this)); if (getCollateralRatio(user) <= safeCollateralRatio) return 0; return depositedAsset[user] * (getCollateralRatio(user) - safeCollateralRatio) / getCollateralRatio(user); } function roomToCap() public view returns (uint256) { if(poolTotalCirculation >= configurator.mintVaultMaxSupply(address(this))) return 0; //deal with case where it's above cap return configurator.mintVaultMaxSupply(address(this)) - poolTotalCirculation; } function getMaxMintableAmountWithDeposit(address user, uint256 deposit) public view returns (uint256 nusdAmount) { uint256 newDepositedAmount = depositedAsset[user] + deposit; uint256 safeCollateralRatio = configurator.getSafeCollateralRatio(address(this)); uint256 userBorrow = getBorrowedOf(user); uint256 cap = configurator.mintVaultMaxSupply(address(this)); uint256 maxBorrowAtSafeRatio = newDepositedAmount * getAssetPrice() * 10_000 / safeCollateralRatio / 1e18; uint256 effectiveMax = _min(maxBorrowAtSafeRatio, cap); if(userBorrow >= effectiveMax) { return 0; //if user has already borrowed more than the max, then no mintable amount } else { uint256 mintMax = effectiveMax - userBorrow; return mintMax - getOriginationFee(mintMax); } } function getTVL() public view returns (uint256) { return totalDepositedAsset() * getAssetPrice(); } function _min(uint256 _a, uint256 _b) private pure returns (uint256) { return _a < _b ? _a : _b; } //MultiRewards farming functionality //Modified from https://github.com/curvefi/multi-rewards //staked asset is replaced with deposited collateral (depositedOf[user]) //access control is managed via rewardManager as specified in configurator //views for multirewards function lastTimeRewardApplicable(address _rewardsToken) public view returns (uint256) { return _min(block.timestamp, rewardData[_rewardsToken].periodFinish); } //total balance of collateral asset function _totalSupply() internal view returns(uint256) { return totalDepositedAsset(); } function rewardPerToken(address _rewardsToken) public view returns (uint256) { if (_totalSupply() == 0) { return rewardData[_rewardsToken].rewardPerTokenStored; } return rewardData[_rewardsToken].rewardPerTokenStored + (lastTimeRewardApplicable(_rewardsToken) - rewardData[_rewardsToken].lastUpdateTime) * rewardData[_rewardsToken].rewardRate * 1e18 / _totalSupply(); } function earned(address account, address _rewardsToken) public view returns (uint256) { return (depositedAsset[account] * (rewardPerToken(_rewardsToken) - userRewardPerTokenPaid[account][_rewardsToken])) / 1e18 + rewards[account][_rewardsToken]; } function getRewardForDuration(address _rewardsToken) external view returns (uint256) { return rewardData[_rewardsToken].rewardRate * rewardData[_rewardsToken].rewardsDuration; } //multiRewards restricted functions function addReward(address _rewardsToken, uint256 _rewardsDuration) public onlyRewardManager { require(_rewardsToken != address(collateralAsset) && _rewardsToken != address(nUSD), "Reward cannot be collateral asset or nUSD"); require(rewardData[_rewardsToken].rewardsDuration == 0, "Reward already exists"); rewardTokens.push(_rewardsToken); rewardData[_rewardsToken].rewardsDuration = _rewardsDuration; } function notifyRewardAmount(address _rewardsToken, uint256 reward) external onlyRewardManager updateReward(address(0)) { IERC20(_rewardsToken).safeTransferFrom(msg.sender, address(this), reward); if (block.timestamp >= rewardData[_rewardsToken].periodFinish) { rewardData[_rewardsToken].rewardRate = reward / rewardData[_rewardsToken].rewardsDuration; } else { uint256 remaining = rewardData[_rewardsToken].periodFinish - block.timestamp; uint256 leftover = remaining * rewardData[_rewardsToken].rewardRate; rewardData[_rewardsToken].rewardRate = (reward + leftover) / rewardData[_rewardsToken].rewardsDuration; } rewardData[_rewardsToken].lastUpdateTime = block.timestamp; rewardData[_rewardsToken].periodFinish = block.timestamp + rewardData[_rewardsToken].rewardsDuration; emit RewardAdded(reward); } function recoverERC20(address tokenAddress, uint256 tokenAmount) external onlyRewardManager { require(tokenAddress != address(collateralAsset) && tokenAddress != address(nUSD), "Cannot withdraw collateral asset or nUSD"); require(rewardData[tokenAddress].lastUpdateTime == 0, "Cannot withdraw reward token"); IERC20(tokenAddress).safeTransfer(msg.sender, tokenAmount); emit Recovered(tokenAddress, tokenAmount); } function setRewardsDuration(address _rewardsToken, uint256 _rewardsDuration) external onlyRewardManager { require(block.timestamp > rewardData[_rewardsToken].periodFinish, "Reward period still active"); require(_rewardsDuration > 0, "Reward duration must be non-zero"); rewardData[_rewardsToken].rewardsDuration = _rewardsDuration; emit RewardsDurationUpdated(_rewardsToken, rewardData[_rewardsToken].rewardsDuration); } //modifier modifier updateReward(address account) { for (uint256 i = 0; i < rewardTokens.length; ) { address token = rewardTokens[i]; rewardData[token].rewardPerTokenStored = rewardPerToken(token); rewardData[token].lastUpdateTime = lastTimeRewardApplicable(token); if (account != address(0)) { rewards[account][token] = earned(account, token); userRewardPerTokenPaid[account][token] = rewardData[token].rewardPerTokenStored; } unchecked {i = i+1;} } _; } modifier onlyRewardManager() { require(configurator.isRewardManager(msg.sender), "Not reward manager"); _; } //multirewards mutative functions function getReward() public nonReentrant updateReward(msg.sender) { for (uint256 i = 0; i < rewardTokens.length; ) { address _rewardsToken = rewardTokens[i]; uint256 reward = rewards[msg.sender][_rewardsToken]; if (reward > 0) { rewards[msg.sender][_rewardsToken] = 0; IERC20(_rewardsToken).safeTransfer(msg.sender, reward); emit RewardPaid(msg.sender, _rewardsToken, reward); } unchecked { i = i+1; } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../extensions/IERC20Permit.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; /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value)); } /** * @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value)); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0)); _callOptionalReturn(token, approvalCall); } } /** * @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`. * Revert on invalid signature. */ function safePermit( IERC20Permit token, address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) internal { uint256 nonceBefore = token.nonces(owner); token.permit(owner, spender, value, deadline, v, r, s); uint256 nonceAfter = token.nonces(owner); require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token)); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; interface InUSD { function totalSupply() external view returns (uint256); function balanceOf(address account) external view returns (uint256); function transfer(address to, uint256 amount) external returns (bool); function allowance(address owner, address spender) external view returns (uint256); function approve(address spender, uint256 amount) external returns (bool); function transferFrom(address from, address to, uint256 amount) external returns (bool); function mint( address to, uint256 amount ) external returns (bool); function burn( address account, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; interface IConfigurator { struct OriginationFeeConfig { uint16 minOriginationFee; // fee at 0% utilization uint16 maxOriginationFee; // fee at 100% utilization } struct RedemptionConfig { bool enabled; //whether a vault can redeem uint16 baseFee; // base fee for redemption uint16 maxMultiplier; // fee for redemption uint16 maxCollateralRatio; // collateral ratio for max fee multiplier uint16 providerShare; // share of redemption fee that goes to provider } function zkOracleAddress(address vault) external view returns(address); function vaultEnabled(address vault) external view returns(bool); function vaultMintPaused(address vault) external view returns(bool); function vaultBurnPaused(address vault) external view returns(bool); function mintVaultMaxSupply(address vault) external view returns(uint256); function getBadCollateralRatio(address vault) external view returns(uint256); function getSafeCollateralRatio(address vault) external view returns(uint256); function borrowApr(address vault) external view returns(uint256); function getKeeperReward(address vault) external view returns(uint256); function getOriginationFee(address vault) external view returns(uint256, uint256); function getRedemptionFee(address vault, uint256 collateralRatio) external view returns(uint256, uint256); function getRedemptionConfig(address vault) external view returns(RedemptionConfig memory); function getDepegThreshold(address vault) external view returns(uint256); function useMarketRate(address vault) external view returns(bool); function treasury() external view returns(address); function flashloanFee() external view returns(uint256); function owner() external view returns (address); function admin() external view returns(address); function nUSD() external view returns(address); function etherOracle() external view returns(address); function getAllVaults() external view returns(address[] memory); function getAllCollaterals() external view returns(address[] memory); function isRewardManager(address user) external view returns(bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.19; interface IZkOracle { //@notice returns the address of the asset function assetAddress() external view returns (address); //@notice returns the market rate of the collateral in terms of underlying function getMarketRate() external view returns (uint256); //@notice returns the backing or redemption rate of the collateral in terms of underlying function getRedemptionRate() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @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 { // 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; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20Permit { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * * Furthermore, `isContract` will also return true if the target contract within * the same transaction is already scheduled for destruction by `SELFDESTRUCT`, * which only has an effect at the end of a transaction. * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.0/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata, errorMessage); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract. * * _Available since v4.8._ */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata, string memory errorMessage ) internal view returns (bytes memory) { if (success) { if (returndata.length == 0) { // only check isContract if the call was successful and the return data is empty // otherwise we already know that it was a contract require(isContract(target), "Address: call to non-contract"); } return returndata; } else { _revert(returndata, errorMessage); } } /** * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason or using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { _revert(returndata, errorMessage); } } function _revert(bytes memory returndata, string memory errorMessage) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } }
{ "remappings": [ "@chainlink/=node_modules/@chainlink/", "@ensdomains/=node_modules/@ensdomains/", "@eth-optimism/=node_modules/@eth-optimism/", "@ethereum-waffle/=node_modules/@ethereum-waffle/", "@layerzerolabs/=node_modules/@layerzerolabs/", "@openzeppelin-3/=node_modules/@openzeppelin-3/", "@openzeppelin/=node_modules/@openzeppelin/", "@redstone-finance/=node_modules/@redstone-finance/", "@uniswap/=node_modules/@uniswap/", "erc721a/=node_modules/erc721a/", "eth-gas-reporter/=node_modules/eth-gas-reporter/", "forge-std/=lib/forge-std/src/", "hardhat-deploy/=node_modules/hardhat-deploy/", "hardhat/=node_modules/hardhat/" ], "optimizer": { "enabled": true, "runs": 9999 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_collateral","type":"address"},{"internalType":"address","name":"_configurator","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sponsor","type":"address"},{"indexed":true,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"DepositAsset","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint256","name":"etherAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"assetAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"DepositEther","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":true,"internalType":"address","name":"keeper","type":"address"},{"indexed":true,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"uint256","name":"nusdAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"LiquidateAssetAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"keeperReward","type":"uint256"},{"indexed":false,"internalType":"bool","name":"superLiquidation","type":"bool"}],"name":"LiquidationRecord","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sponsor","type":"address"},{"indexed":true,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"originationFee","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Recovered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"caller","type":"address"},{"indexed":true,"internalType":"address","name":"provider","type":"address"},{"indexed":false,"internalType":"uint256","name":"nusdToProtocol","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"nusdToRepay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"collateralReceived","type":"uint256"}],"name":"Redemption","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"rewardsToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"reward","type":"uint256"}],"name":"RewardPaid","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"newDuration","type":"uint256"}],"name":"RewardsDurationUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"sponsor","type":"address"},{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":true,"internalType":"address","name":"onBehalfOf","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"WithdrawAsset","type":"event"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"}],"name":"addReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"borrowed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"onBehalfOf","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"uint256","name":"nusdAmount","type":"uint256"}],"name":"calculateRedemption","outputs":[{"internalType":"uint256","name":"providerFee","type":"uint256"},{"internalType":"uint256","name":"protocolFee","type":"uint256"},{"internalType":"uint256","name":"nusdToProtocol","type":"uint256"},{"internalType":"uint256","name":"nusdToRepay","type":"uint256"},{"internalType":"uint256","name":"nusdToConvert","type":"uint256"},{"internalType":"uint256","name":"collateralReceived","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"collateralAsset","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"configurator","outputs":[{"internalType":"contract IConfigurator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"assetAmount","type":"uint256"},{"internalType":"uint256","name":"mintAmount","type":"uint256"}],"name":"depositAssetToMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"depositedAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"_rewardsToken","type":"address"}],"name":"earned","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"feeStored","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"feeUpdatedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAsset","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAssetPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAssetToUnderlyingRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getBorrowedOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getCollateralRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getLiquidateFund","outputs":[{"internalType":"uint256","name":"nusdAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getLiquidateableAmount","outputs":[{"internalType":"uint256","name":"collateralAmount","type":"uint256"},{"internalType":"uint256","name":"nUsdAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMarketRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"},{"internalType":"uint256","name":"deposit","type":"uint256"}],"name":"getMaxMintableAmountWithDeposit","outputs":[{"internalType":"uint256","name":"nusdAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"getOriginationFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOverallCollateralRatio","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPoolTotalCirculation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"}],"name":"getRedeemableAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRedemptionRate","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getReward","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"}],"name":"getRewardForDuration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTVL","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getUnderlyingToUsdPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getWithdrawableAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getZkOracle","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isDepegged","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"}],"name":"lastTimeRewardApplicable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"address","name":"debtor","type":"address"},{"internalType":"uint256","name":"assetAmount","type":"uint256"}],"name":"liquidation","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"onBehalfOf","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nUSD","outputs":[{"internalType":"contract InUSD","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"uint256","name":"reward","type":"uint256"}],"name":"notifyRewardAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"poolTotalCirculation","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"tokenAmount","type":"uint256"}],"name":"recoverERC20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"provider","type":"address"},{"internalType":"uint256","name":"nusdAmount","type":"uint256"},{"internalType":"uint256","name":"minReceiveAmount","type":"uint256"}],"name":"redemption","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"rewardData","outputs":[{"internalType":"uint256","name":"rewardsDuration","type":"uint256"},{"internalType":"uint256","name":"periodFinish","type":"uint256"},{"internalType":"uint256","name":"rewardRate","type":"uint256"},{"internalType":"uint256","name":"lastUpdateTime","type":"uint256"},{"internalType":"uint256","name":"rewardPerTokenStored","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"}],"name":"rewardPerToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rewardTokens","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"rewards","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"roomToCap","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_rewardsToken","type":"address"},{"internalType":"uint256","name":"_rewardsDuration","type":"uint256"}],"name":"setRewardsDuration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalDepositedAsset","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"userRewardPerTokenPaid","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"onBehalfOf","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60e06040523480156200001157600080fd5b5060405162004f6338038062004f638339810160408190526200003491620000e2565b60016000556001600160a01b0380831660a052811660c081905260408051633b970e1d60e01b81529051633b970e1d916004808201926020929091908290030181865afa1580156200008a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620000b091906200011a565b6001600160a01b0316608052506200013f9050565b80516001600160a01b0381168114620000dd57600080fd5b919050565b60008060408385031215620000f657600080fd5b6200010183620000c5565b91506200011160208401620000c5565b90509250929050565b6000602082840312156200012d57600080fd5b6200013882620000c5565b9392505050565b60805160a05160c051614c9d620002c6600039600081816104560152818161098001528181610b9801528181610cd101528181610e700152818161109d0152818161146c01528181611520015281816116870152818161175801528181611a1201528181611baf01528181611d950152818161212e015281816124c20152818161274c01528181612c1301528181612fba0152818161306c01528181613126015281816131ce015281816132b3015281816137580152818161389b01528181613b1001528181613c5101528181613f2b0152818161413a015261461101526000818161054c015281816106c001528181610b1b0152818161107201528181611af601528181611e5601528181612586015281816125c50152818161280d01528181612b1801528181612b8301528181614374015261440701526000818161047d01528181611a4101528181611e93015281816122ef0152818161284a01528181613c8301528181613cfd01528181613f5a01528181613fec01526141690152614c9d6000f3fe608060405234801561001057600080fd5b506004361061032b5760003560e01c806369d83b3c116101b2578063aabaecd6116100f9578063d5e8d0e5116100a2578063e70b9e271161007c578063e70b9e271461075a578063f122977714610785578063f3fef3a314610798578063f6777175146107ab57600080fd5b8063d5e8d0e51461072c578063d8f53d301461073f578063e54f08801461075257600080fd5b8063bcd11014116100d3578063bcd1101414610708578063c19b0f551461071b578063c45022d71461072357600080fd5b8063aabaecd6146106bb578063abbc4217146106e2578063b66503cf146106f557600080fd5b80638980f11f1161015b57806397b3fcaa1161013557806397b3fcaa1461068d5780639dc29fac146106955780639feb8f50146106a857600080fd5b80638980f11f1461065f57806396171e59146106725780639754d1dc1461068557600080fd5b80637035ab981161018c5780637035ab98146106195780637bb7bed114610644578063861a1cad1461065757600080fd5b806369d83b3c146105d15780636eff3e4d146105f15780636f65f362146105f957600080fd5b80633b970e1d116102765780635c222bad1161021f578063619cfc35116101f9578063619cfc351461058b578063638634ee1461059e5780636671ab6c146105b157600080fd5b80635c222bad1461054a5780635d2fbeb9146105705780635e0ff74e1461057857600080fd5b806348e5d9f81161025057806348e5d9f8146104ba5780634b0369c11461051f5780635a0332a41461053257600080fd5b80633b970e1d146104785780633d18b9121461049f57806340c10f19146104a757600080fd5b80631f83a516116102d857806328487a13116102b257806328487a13146104295780632b11551a146104495780632b507df81461045157600080fd5b80631f83a516146103d9578063211dc32d146104015780632378bea61461041457600080fd5b806315a3ba431161030957806315a3ba43146103b657806317d145a2146103c95780631cf58903146103d157600080fd5b806305ad8308146103305780630941cb3d146103565780630b9c74a614610376575b600080fd5b61034361033e366004614817565b6107be565b6040519081526020015b60405180910390f35b610343610364366004614817565b60036020526000908152604090205481565b610389610384366004614834565b610808565b604080519687526020870195909552938501929092526060840152608083015260a082015260c00161034d565b6103436103c4366004614817565b610a6a565b610343610aea565b610343610b93565b6103ec6103e7366004614817565b610c96565b6040805192835260208301919091520161034d565b61034361040f366004614860565b610daa565b610427610422366004614834565b610e42565b005b610431611042565b6040516001600160a01b03909116815260200161034d565b61034361110a565b6104317f000000000000000000000000000000000000000000000000000000000000000081565b6104317f000000000000000000000000000000000000000000000000000000000000000081565b610427611179565b6104276104b5366004614834565b611355565b6104f76104c8366004614817565b600660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a00161034d565b61034361052d366004614834565b61140a565b61053a611620565b604051901515815260200161034d565b7f0000000000000000000000000000000000000000000000000000000000000000610431565b61034361171c565b610427610586366004614899565b611800565b610343610599366004614817565b611b74565b6103436105ac366004614817565b611c83565b6103436105bf366004614817565b60046020526000908152604090205481565b6103436105df366004614817565b60026020526000908152604090205481565b610343611caa565b610343610607366004614817565b60056020526000908152604090205481565b610343610627366004614860565b600860209081526000928352604080842090915290825290205481565b6104316106523660046148ce565b611cf2565b610343611d1c565b61042761066d366004614834565b611d67565b6104276106803660046148e7565b611ff6565b600154610343565b610343612651565b6104276106a3366004614834565b61266d565b6104276106b6366004614834565b61271e565b6104317f000000000000000000000000000000000000000000000000000000000000000081565b6104276106f0366004614928565b6129cb565b610427610703366004614834565b612be5565b610343610716366004614817565b612f5f565b610343612f89565b61034360015481565b61034361073a3660046148ce565b6130e9565b61034361074d366004614817565b6132ae565b610343613474565b610343610768366004614860565b600960209081526000928352604080842090915290825290205481565b610343610793366004614817565b613499565b6104276107a6366004614834565b613553565b6103436107b9366004614817565b6136f9565b60006107c98261382f565b6001600160a01b0383166000908152600460209081526040808320546003909252909120546107f89190614979565b6108029190614979565b92915050565b600080600080600080600087116108665760405162461bcd60e51b815260206004820152601860248201527f726564656d7074696f6e2073686f756c64206265203e2030000000000000000060448201526064015b60405180910390fd5b86610870896107be565b10156108e45760405162461bcd60e51b815260206004820152602860248201527f6e757364416d6f756e742063616e6e6f7420737572706173732070726f76696460448201527f6572732064656274000000000000000000000000000000000000000000000000606482015260840161085d565b60006108ee613474565b90506000670de0b6b3a76400006109048b6107be565b6001600160a01b038c1660009081526002602052604090205461092890859061498c565b6109349061271061498c565b61093e91906149a3565b61094891906149a3565b6040517f1ee9211f000000000000000000000000000000000000000000000000000000008152306004820152602481018290529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690631ee9211f906044016040805180830381865afa1580156109ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f291906149de565b9098509650612710610a04888b61498c565b610a0e91906149a3565b9550610a1a868a614a02565b9450612710610a298982614a02565b610a33908761498c565b610a3d91906149a3565b935081610a5285670de0b6b3a764000061498c565b610a5c91906149a3565b925050509295509295509295565b6000610a75826107be565b600003610a8d575069021e19e0c9bab2400000919050565b670de0b6b3a7640000610a9f836107be565b610aa7613474565b6001600160a01b038516600090815260026020526040902054610aca919061498c565b610ad69061271061498c565b610ae091906149a3565b61080291906149a3565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a0823190602401602060405180830381865afa158015610b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8e9190614a15565b905090565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663e17bbe616040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c189190614a2e565b6001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c799190614a65565b505050915050806402540be400610c90919061498c565b91505090565b6040517fae91874900000000000000000000000000000000000000000000000000000000815230600482015260009081906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ae91874990602401602060405180830381865afa158015610d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3c9190614a15565b610d4584610a6a565b1115610d5657506000928392509050565b6001600160a01b038316600090815260026020819052604090912054610d7c91906149a3565b9150670de0b6b3a7640000610d8f613474565b610d99908461498c565b610da391906149a3565b9050915091565b6001600160a01b038083166000818152600960209081526040808320948616808452948252808320549383526008825280832094835293905291822054670de0b6b3a764000090610dfa85613499565b610e049190614a02565b6001600160a01b038616600090815260026020526040902054610e27919061498c565b610e3191906149a3565b610e3b9190614979565b9392505050565b6040517f4e83423c0000000000000000000000000000000000000000000000000000000081523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634e83423c90602401602060405180830381865afa158015610ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee39190614ac5565b610f2f5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420726577617264206d616e616765720000000000000000000000000000604482015260640161085d565b6001600160a01b0382166000908152600660205260409020600101544211610f995760405162461bcd60e51b815260206004820152601a60248201527f52657761726420706572696f64207374696c6c20616374697665000000000000604482015260640161085d565b60008111610fe95760405162461bcd60e51b815260206004820181905260248201527f526577617264206475726174696f6e206d757374206265206e6f6e2d7a65726f604482015260640161085d565b6001600160a01b038216600081815260066020908152604091829020849055815192835282018390527fad2f86b01ed93b4b3a150d448c61a4f5d8d38075d3c0c64cc0a26fd6e1f4954591015b60405180910390a15050565b6040517f3f5068340000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811660048301526000917f000000000000000000000000000000000000000000000000000000000000000090911690633f50683490602401602060405180830381865afa1580156110e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8e9190614a2e565b600080611115611042565b9050806001600160a01b0316632b11551a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611155573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c909190614a15565b611181613947565b3360005b600754811015611270576000600782815481106111a4576111a4614ae0565b6000918252602090912001546001600160a01b031690506111c481613499565b6001600160a01b0382166000908152600660205260409020600401556111e981611c83565b6001600160a01b038083166000908152600660205260409020600301919091558316156112675761121a8382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b50600101611185565b5060005b6007548110156113475760006007828154811061129357611293614ae0565b60009182526020808320909101543383526009825260408084206001600160a01b0390921680855291909252912054909150801561133d573360008181526009602090815260408083206001600160a01b03871680855292528220919091556112fc91836139a0565b6040518181526001600160a01b0383169033907f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e9060200160405180910390a35b5050600101611274565b50506113536001600055565b565b6001600160a01b0382166113ab5760405162461bcd60e51b815260206004820152600f60248201527f746f207a65726f20616464726573730000000000000000000000000000000000604482015260640161085d565b806000036113fb5760405162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015260640161085d565b611406338383613a67565b5050565b6001600160a01b0382166000908152600260205260408120548190611430908490614979565b6040517fae9187490000000000000000000000000000000000000000000000000000000081523060048201529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063ae91874990602401602060405180830381865afa1580156114b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d79190614a15565b905060006114e4866107be565b6040517fcc143a040000000000000000000000000000000000000000000000000000000081523060048201529091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cc143a0490602401602060405180830381865afa158015611567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158b9190614a15565b90506000670de0b6b3a7640000846115a1613474565b6115ab908861498c565b6115b79061271061498c565b6115c191906149a3565b6115cb91906149a3565b905060006115d98284613e88565b90508084106115f15760009650505050505050610802565b60006115fd8583614a02565b9050611608816130e9565b6116129082614a02565b975050505050505050610802565b60008061162b611d1c565b90508060000361163d57600091505090565b600061164761110a565b6040517fcea12844000000000000000000000000000000000000000000000000000000008152306004820152909150600090612710906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cea1284490602401602060405180830381865afa1580156116ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f29190614a15565b6116fe90612710614a02565b611708908461498c565b61171291906149a3565b9092109392505050565b60008061172761110a565b6040517f4b3fef610000000000000000000000000000000000000000000000000000000081523060048201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634b3fef6190602401602060405180830381865afa1580156117a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117cb9190614ac5565b156117fb5760006117da611d1c565b9050806000036117ea5750919050565b6117f48183613e88565b9250505090565b919050565b8260005b6007548110156118ef5760006007828154811061182357611823614ae0565b6000918252602090912001546001600160a01b0316905061184381613499565b6001600160a01b03821660009081526006602052604090206004015561186881611c83565b6001600160a01b038083166000908152600660205260409020600301919091558316156118e6576118998382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b50600101611804565b50336001600160a01b038516036119485760405162461bcd60e51b815260206004820152600e60248201527f6e6f2073656c662072656465656d000000000000000000000000000000000000604482015260640161085d565b60008060006119578787610808565b955050945094505050848110156119d65760405162461bcd60e51b815260206004820152602f60248201527f436f6c6c61746572616c20616d6f756e74206973206c657373207468616e206d60448201527f696e52656365697665416d6f756e740000000000000000000000000000000000606482015260840161085d565b8215611ab0576040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166024830152604482018590527f000000000000000000000000000000000000000000000000000000000000000016906323b872dd906064016020604051808303816000875af1158015611a8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aae9190614ac5565b505b611abb338884613e9e565b6001600160a01b03871660009081526002602052604081208054839290611ae3908490614a02565b90915550611b1d90506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633836139a0565b60408051848152602081018490529081018290526001600160a01b0388169033907f4f808f68134f8b72b842a276c2b37b03415d4992c65a94fcee50d33201915b999060600160405180910390a350505050505050565b6040517f81ddac3300000000000000000000000000000000000000000000000000000000815230600482015260009081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906381ddac339060240160a060405180830381865afa158015611bf6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1a9190614b21565b8051909150611c2c5750600092915050565b611c35836107be565b600003611c455750600092915050565b806060015161ffff16611c5784610a6a565b1180611c6c5750612710611c6a84610a6a565b105b15611c7a5750600092915050565b610e3b836107be565b6001600160a01b038116600090815260066020526040812060010154610802904290613e88565b6000670de0b6b3a7640000600154611cc0613474565b611cc8610aea565b611cd2919061498c565b611cde9061271061498c565b611ce891906149a3565b610b8e91906149a3565b60078181548110611d0257600080fd5b6000918252602090912001546001600160a01b0316905081565b600080611d27611042565b9050806001600160a01b031663861a1cad6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611155573d6000803e3d6000fd5b6040517f4e83423c0000000000000000000000000000000000000000000000000000000081523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634e83423c90602401602060405180830381865afa158015611de4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e089190614ac5565b611e545760405162461bcd60e51b815260206004820152601260248201527f4e6f7420726577617264206d616e616765720000000000000000000000000000604482015260640161085d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614158015611ec857507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b611f3a5760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f7420776974686472617720636f6c6c61746572616c20617373657460448201527f206f72206e555344000000000000000000000000000000000000000000000000606482015260840161085d565b6001600160a01b03821660009081526006602052604090206003015415611fa35760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f742077697468647261772072657761726420746f6b656e00000000604482015260640161085d565b611fb76001600160a01b03831633836139a0565b604080516001600160a01b0384168152602081018390527f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa289101611036565b8260005b6007548110156120e55760006007828154811061201957612019614ae0565b6000918252602090912001546001600160a01b0316905061203981613499565b6001600160a01b03821660009081526006602052604090206004015561205e81611c83565b6001600160a01b038083166000908152600660205260409020600301919091558316156120dc5761208f8382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b50600101611ffa565b5060006120f0613474565b905060006120fd85610a6a565b6040517fd54d832c0000000000000000000000000000000000000000000000000000000081523060048201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063d54d832c90602401602060405180830381865afa15801561217d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a19190614a15565b81106122155760405162461bcd60e51b815260206004820152603a60248201527f426f72726f7765727320636f6c6c61746572616c20726174696f2073686f756c60448201527f642062656c6f7720626164436f6c6c61746572616c526174696f000000000000606482015260840161085d565b6001600160a01b0385166000908152600260208190526040909120549061223d90869061498c565b11156122b15760405162461bcd60e51b815260206004820152602960248201527f61206d6178206f662035302520636f6c6c61746572616c2063616e206265206c60448201527f6971756964617465640000000000000000000000000000000000000000000000606482015260840161085d565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301523060248301527f0000000000000000000000000000000000000000000000000000000000000000169063dd62ed3e90604401602060405180830381865afa158015612336573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235a9190614a15565b15158061236f5750336001600160a01b038716145b6123e15760405162461bcd60e51b815260206004820152603560248201527f70726f76696465722073686f756c6420617574686f72697a6520746f2070726f60448201527f76696465206c69717569646174696f6e206e5553440000000000000000000000606482015260840161085d565b6000670de0b6b3a76400006123f6848761498c565b61240091906149a3565b905061240d878783613e9e565b84612710831180156124205750612af883105b1561243f57612710612432848861498c565b61243c91906149a3565b90505b612af8831061246257600a61245587600b61498c565b61245f91906149a3565b90505b6001600160a01b0387166000908152600260205260408120805483929061248a908490614a02565b90915550506040517fb0900b8700000000000000000000000000000000000000000000000000000000815230600482015260009081907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063b0900b8790602401602060405180830381865afa158015612511573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125359190614a15565b9050336001600160a01b038b161480159061255b575061255781612710614979565b8510155b156125ad5761271061256d828a61498c565b61257791906149a3565b91506125ad6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633846139a0565b6125ec8a6125bb8486614a02565b6001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691906139a0565b6040805185815260208101859052908101839052600060608201526001600160a01b03808b169133918d16907fbb234fdd76afd1f5d19ef00827e334a70087bce6bc089670253ffb48737592a09060800160405180910390a450505050505050505050565b600061265b613474565b612663610aea565b610b8e919061498c565b6001600160a01b0382166126c35760405162461bcd60e51b815260206004820152600f60248201527f746f207a65726f20616464726573730000000000000000000000000000000000604482015260640161085d565b806000036127135760405162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015260640161085d565b611406338383613e9e565b6040517f4e83423c0000000000000000000000000000000000000000000000000000000081523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634e83423c90602401602060405180830381865afa15801561279b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127bf9190614ac5565b61280b5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420726577617264206d616e616765720000000000000000000000000000604482015260640161085d565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b03161415801561287f57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614155b6128f15760405162461bcd60e51b815260206004820152602960248201527f5265776172642063616e6e6f7420626520636f6c6c61746572616c206173736560448201527f74206f72206e5553440000000000000000000000000000000000000000000000606482015260840161085d565b6001600160a01b038216600090815260066020526040902054156129575760405162461bcd60e51b815260206004820152601560248201527f52657761726420616c7265616479206578697374730000000000000000000000604482015260640161085d565b60078054600181019091557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b039093167fffffffffffffffffffffffff00000000000000000000000000000000000000009093168317905560009182526006602052604090912055565b3360005b600754811015612aba576000600782815481106129ee576129ee614ae0565b6000918252602090912001546001600160a01b03169050612a0e81613499565b6001600160a01b038216600090815260066020526040902060040155612a3381611c83565b6001600160a01b03808316600090815260066020526040902060030191909155831615612ab157612a648382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b506001016129cf565b5060008311612b0b5760405162461bcd60e51b815260206004820152601560248201527f4465706f7369742073686f756c64206265203e20300000000000000000000000604482015260640161085d565b612b406001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001633308661424a565b3360009081526002602052604081208054859290612b5f908490614979565b90915550508115612b7557612b75333384613a67565b604080516001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000168152602081018590524281830152905133917ff80e165f76857acc123ffe20b1116e9ec31ad7f2c4ecd6f379a9cc9151b50371919081900360600190a2505050565b6040517f4e83423c0000000000000000000000000000000000000000000000000000000081523360048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690634e83423c90602401602060405180830381865afa158015612c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c869190614ac5565b612cd25760405162461bcd60e51b815260206004820152601260248201527f4e6f7420726577617264206d616e616765720000000000000000000000000000604482015260640161085d565b6000805b600754811015612dc157600060078281548110612cf557612cf5614ae0565b6000918252602090912001546001600160a01b03169050612d1581613499565b6001600160a01b038216600090815260066020526040902060040155612d3a81611c83565b6001600160a01b03808316600090815260066020526040902060030191909155831615612db857612d6b8382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b50600101612cd6565b50612dd76001600160a01b03841633308561424a565b6001600160a01b0383166000908152600660205260409020600101544210612e3d576001600160a01b038316600090815260066020526040902054612e1c90836149a3565b6001600160a01b038416600090815260066020526040902060020155612edd565b6001600160a01b038316600090815260066020526040812060010154612e64904290614a02565b6001600160a01b03851660009081526006602052604081206002015491925090612e8e908361498c565b6001600160a01b038616600090815260066020526040902054909150612eb48286614979565b612ebe91906149a3565b6001600160a01b03861660009081526006602052604090206002015550505b6001600160a01b038316600090815260066020526040902042600382018190559054612f0891614979565b6001600160a01b03841660009081526006602090815260409182902060010192909255518381527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d910160405180910390a1505050565b6001600160a01b03811660009081526006602052604081208054600290910154610802919061498c565b6040517fcc143a040000000000000000000000000000000000000000000000000000000081523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063cc143a0490602401602060405180830381865afa158015613009573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061302d9190614a15565b6001541061303b5750600090565b6001546040517fcc143a040000000000000000000000000000000000000000000000000000000081523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063cc143a0490602401602060405180830381865afa1580156130bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130df9190614a15565b610b8e9190614a02565b6040517f27480e5e000000000000000000000000000000000000000000000000000000008152306004820152600090819081906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906327480e5e906024016040805180830381865afa15801561316c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061319091906149de565b6040517fcc143a0400000000000000000000000000000000000000000000000000000000815230600482015291935091506000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cc143a0490602401602060405180830381865afa158015613215573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132399190614a15565b856001546132479190614979565b61325990670de0b6b3a764000061498c565b61326391906149a3565b9050612710670de0b6b3a7640000868361327d8787614a02565b613287919061498c565b613291919061498c565b61329b91906149a3565b6132a591906149a3565b95945050505050565b6000807f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316633b970e1d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561330f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133339190614a2e565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015230602483015291925060009183169063dd62ed3e90604401602060405180830381865afa15801561339e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133c29190614a15565b9050806000036133d6575060009392505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152600091908416906370a0823190602401602060405180830381865afa158015613439573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061345d9190614a15565b905080821161346c57816132a5565b949350505050565b6000670de0b6b3a7640000613487610b93565b61348f61171c565b611ce8919061498c565b60006134a36142a1565b6000036134c957506001600160a01b031660009081526006602052604090206004015490565b6134d16142a1565b6001600160a01b038316600090815260066020526040902060028101546003909101546134fd85611c83565b6135079190614a02565b613511919061498c565b61352390670de0b6b3a764000061498c565b61352d91906149a3565b6001600160a01b0383166000908152600660205260409020600401546108029190614979565b3360005b6007548110156136425760006007828154811061357657613576614ae0565b6000918252602090912001546001600160a01b0316905061359681613499565b6001600160a01b0382166000908152600660205260409020600401556135bb81611c83565b6001600160a01b03808316600090815260066020526040902060030191909155831615613639576135ec8382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b50600101613557565b506001600160a01b0383166136995760405162461bcd60e51b815260206004820152600f60248201527f746f207a65726f20616464726573730000000000000000000000000000000000604482015260640161085d565b816000036136e95760405162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015260640161085d565b6136f43384846142ab565b505050565b6000613704826107be565b60000361372757506001600160a01b031660009081526002602052604090205490565b6040517fae9187490000000000000000000000000000000000000000000000000000000081523060048201526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ae91874990602401602060405180830381865afa1580156137a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137cb9190614a15565b9050806137d784610a6a565b116137e55750600092915050565b6137ee83610a6a565b816137f885610a6a565b6138029190614a02565b6001600160a01b038516600090815260026020526040902054613825919061498c565b610e3b91906149a3565b6001600160a01b0381166000908152600560205260408120546301e1338090829061385a9042614a02565b6040517f9fecc37d00000000000000000000000000000000000000000000000000000000815230600482015290915061271090839083906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690639fecc37d90602401602060405180830381865afa1580156138e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139069190614a15565b6001600160a01b038816600090815260036020526040902054613929919061498c565b613933919061498c565b61393d91906149a3565b61346c91906149a3565b6002600054036139995760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161085d565b6002600055565b6040516001600160a01b0383166024820152604481018290526136f49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152614478565b613a6f611620565b15613ae25760405162461bcd60e51b815260206004820152602660248201527f436f6c6c61746572616c2069732064657065676765642c206d696e74696e672060448201527f7061757365640000000000000000000000000000000000000000000000000000606482015260840161085d565b6040517fcc143a040000000000000000000000000000000000000000000000000000000081523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063cc143a0490602401602060405180830381865afa158015613b5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b839190614a15565b81600154613b919190614979565b1115613bdf5760405162461bcd60e51b815260206004820152600b60248201527f6578636565647320636170000000000000000000000000000000000000000000604482015260640161085d565b613be883614560565b6001600160a01b03831660009081526003602052604081208054839290613c10908490614979565b9091555060009050613c21826130e9565b6040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166004830152602482018390529192507f0000000000000000000000000000000000000000000000000000000000000000909116906340c10f19906044016020604051808303816000875af1158015613cce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cf29190614ac5565b506001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166340c10f1984613d2d8486614a02565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015613d90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613db49190614ac5565b508160016000828254613dc79190614979565b90915550613dd69050846145d5565b613e225760405162461bcd60e51b815260206004820152601c60248201527f7573657220697320756e6865616c746879206166746572206d696e7400000000604482015260640161085d565b826001600160a01b0316846001600160a01b03167f458f5fa412d0f69b08dd84872b0215675cc67bc1d5b6fd93300a1c3878b86196848442604051613e7a939291909283526020830191909152604082015260600190565b60405180910390a350505050565b6000818310613e975781610e3b565b5090919050565b613ea782614560565b6001600160a01b0382166000908152600460209081526040808320546003909252822054909190613ee390613edd908490614979565b84613e88565b905081811115614102578115613fe2576040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301527f000000000000000000000000000000000000000000000000000000000000000081166024830152604482018490527f000000000000000000000000000000000000000000000000000000000000000016906323b872dd906064016020604051808303816000875af1158015613fa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fc79190614ac5565b506001600160a01b0384166000908152600460205260408120555b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016639dc29fac8661401c8585614a02565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801561407f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140a39190614ac5565b506140ae8282614a02565b6001600160a01b038516600090815260036020526040812080549091906140d6908490614a02565b909155506140e690508282614a02565b600160008282546140f79190614a02565b909155506141fb9050565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301527f000000000000000000000000000000000000000000000000000000000000000081166024830152604482018390527f000000000000000000000000000000000000000000000000000000000000000016906323b872dd906064016020604051808303816000875af11580156141b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141d69190614ac5565b506141e18183614a02565b6001600160a01b0385166000908152600460205260409020555b604080518281524260208201526001600160a01b0380871692908816917f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2910160405180910390a35050505050565b6040516001600160a01b038085166024830152831660448201526064810182905261429b9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016139e5565b50505050565b6000610b8e610aea565b6001600160a01b0383166000908152600260205260409020548111156143395760405162461bcd60e51b815260206004820152602960248201527f576974686472617720616d6f756e742065786365656473206465706f7369746560448201527f6420616d6f756e742e0000000000000000000000000000000000000000000000606482015260840161085d565b6001600160a01b03831660009081526002602052604081208054839290614361908490614a02565b9091555061439b90506001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001683836139a0565b60006143a6846107be565b1115614401576143b5836145d5565b6144015760405162461bcd60e51b815260206004820181905260248201527f5573657220697320756e6865616c746879206166746572207769746864726177604482015260640161085d565b604080517f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811682526020820184905242828401529151848316928616917f31c6c2b083b6c6fb9c8345de5c29efda3ef312a42d1bc0d4a3029465080809c1919081900360600190a3505050565b60006144cd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166146df9092919063ffffffff16565b90508051600014806144ee5750808060200190518101906144ee9190614ac5565b6136f45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161085d565b6001600160a01b0381166000908152600560205260409020544211156145d2576145898161382f565b6001600160a01b038216600090815260046020526040812080549091906145b1908490614979565b90915550506001600160a01b03811660009081526005602052604090204290555b50565b6000806145e0613474565b6040517fae9187490000000000000000000000000000000000000000000000000000000081523060048201529091507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063ae91874990602401602060405180830381865afa158015614660573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146849190614a15565b61468d846107be565b6001600160a01b0385166000908152600260205260409020546146b190849061498c565b6146bd9061271061498c565b6146c791906149a3565b10156146d65750600092915050565b50600192915050565b606061346c848460008585600080866001600160a01b031685876040516147069190614bfa565b60006040518083038185875af1925050503d8060008114614743576040519150601f19603f3d011682016040523d82523d6000602084013e614748565b606091505b509150915061475987838387614764565b979650505050505050565b606083156147d35782516000036147cc576001600160a01b0385163b6147cc5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161085d565b508161346c565b61346c83838151156147e85781518083602001fd5b8060405162461bcd60e51b815260040161085d9190614c16565b6001600160a01b03811681146145d257600080fd5b60006020828403121561482957600080fd5b8135610e3b81614802565b6000806040838503121561484757600080fd5b823561485281614802565b946020939093013593505050565b6000806040838503121561487357600080fd5b823561487e81614802565b9150602083013561488e81614802565b809150509250929050565b6000806000606084860312156148ae57600080fd5b83356148b981614802565b95602085013595506040909401359392505050565b6000602082840312156148e057600080fd5b5035919050565b6000806000606084860312156148fc57600080fd5b833561490781614802565b9250602084013561491781614802565b929592945050506040919091013590565b6000806040838503121561493b57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156108025761080261494a565b80820281158282048414176108025761080261494a565b6000826149d9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600080604083850312156149f157600080fd5b505080516020909101519092909150565b818103818111156108025761080261494a565b600060208284031215614a2757600080fd5b5051919050565b600060208284031215614a4057600080fd5b8151610e3b81614802565b805169ffffffffffffffffffff811681146117fb57600080fd5b600080600080600060a08688031215614a7d57600080fd5b614a8686614a4b565b9450602086015193506040860151925060608601519150614aa960808701614a4b565b90509295509295909350565b805180151581146117fb57600080fd5b600060208284031215614ad757600080fd5b610e3b82614ab5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b805161ffff811681146117fb57600080fd5b600060a08284031215614b3357600080fd5b60405160a0810181811067ffffffffffffffff82111715614b7d577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052614b8983614ab5565b8152614b9760208401614b0f565b6020820152614ba860408401614b0f565b6040820152614bb960608401614b0f565b6060820152614bca60808401614b0f565b60808201529392505050565b60005b83811015614bf1578181015183820152602001614bd9565b50506000910152565b60008251614c0c818460208701614bd6565b9190910192915050565b6020815260008251806020840152614c35816040850160208701614bd6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220dd68debd4c0c970ea1793a7cf36b2f7f167ee8f5b436e187b795bdb35a09646664736f6c63430008130033000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a70000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c1513
Deployed Bytecode
0x608060405234801561001057600080fd5b506004361061032b5760003560e01c806369d83b3c116101b2578063aabaecd6116100f9578063d5e8d0e5116100a2578063e70b9e271161007c578063e70b9e271461075a578063f122977714610785578063f3fef3a314610798578063f6777175146107ab57600080fd5b8063d5e8d0e51461072c578063d8f53d301461073f578063e54f08801461075257600080fd5b8063bcd11014116100d3578063bcd1101414610708578063c19b0f551461071b578063c45022d71461072357600080fd5b8063aabaecd6146106bb578063abbc4217146106e2578063b66503cf146106f557600080fd5b80638980f11f1161015b57806397b3fcaa1161013557806397b3fcaa1461068d5780639dc29fac146106955780639feb8f50146106a857600080fd5b80638980f11f1461065f57806396171e59146106725780639754d1dc1461068557600080fd5b80637035ab981161018c5780637035ab98146106195780637bb7bed114610644578063861a1cad1461065757600080fd5b806369d83b3c146105d15780636eff3e4d146105f15780636f65f362146105f957600080fd5b80633b970e1d116102765780635c222bad1161021f578063619cfc35116101f9578063619cfc351461058b578063638634ee1461059e5780636671ab6c146105b157600080fd5b80635c222bad1461054a5780635d2fbeb9146105705780635e0ff74e1461057857600080fd5b806348e5d9f81161025057806348e5d9f8146104ba5780634b0369c11461051f5780635a0332a41461053257600080fd5b80633b970e1d146104785780633d18b9121461049f57806340c10f19146104a757600080fd5b80631f83a516116102d857806328487a13116102b257806328487a13146104295780632b11551a146104495780632b507df81461045157600080fd5b80631f83a516146103d9578063211dc32d146104015780632378bea61461041457600080fd5b806315a3ba431161030957806315a3ba43146103b657806317d145a2146103c95780631cf58903146103d157600080fd5b806305ad8308146103305780630941cb3d146103565780630b9c74a614610376575b600080fd5b61034361033e366004614817565b6107be565b6040519081526020015b60405180910390f35b610343610364366004614817565b60036020526000908152604090205481565b610389610384366004614834565b610808565b604080519687526020870195909552938501929092526060840152608083015260a082015260c00161034d565b6103436103c4366004614817565b610a6a565b610343610aea565b610343610b93565b6103ec6103e7366004614817565b610c96565b6040805192835260208301919091520161034d565b61034361040f366004614860565b610daa565b610427610422366004614834565b610e42565b005b610431611042565b6040516001600160a01b03909116815260200161034d565b61034361110a565b6104317f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c151381565b6104317f0000000000000000000000005aba34e0a32a7c7cef6e6765d478d90031b2338781565b610427611179565b6104276104b5366004614834565b611355565b6104f76104c8366004614817565b600660205260009081526040902080546001820154600283015460038401546004909401549293919290919085565b604080519586526020860194909452928401919091526060830152608082015260a00161034d565b61034361052d366004614834565b61140a565b61053a611620565b604051901515815260200161034d565b7f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a7610431565b61034361171c565b610427610586366004614899565b611800565b610343610599366004614817565b611b74565b6103436105ac366004614817565b611c83565b6103436105bf366004614817565b60046020526000908152604090205481565b6103436105df366004614817565b60026020526000908152604090205481565b610343611caa565b610343610607366004614817565b60056020526000908152604090205481565b610343610627366004614860565b600860209081526000928352604080842090915290825290205481565b6104316106523660046148ce565b611cf2565b610343611d1c565b61042761066d366004614834565b611d67565b6104276106803660046148e7565b611ff6565b600154610343565b610343612651565b6104276106a3366004614834565b61266d565b6104276106b6366004614834565b61271e565b6104317f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a781565b6104276106f0366004614928565b6129cb565b610427610703366004614834565b612be5565b610343610716366004614817565b612f5f565b610343612f89565b61034360015481565b61034361073a3660046148ce565b6130e9565b61034361074d366004614817565b6132ae565b610343613474565b610343610768366004614860565b600960209081526000928352604080842090915290825290205481565b610343610793366004614817565b613499565b6104276107a6366004614834565b613553565b6103436107b9366004614817565b6136f9565b60006107c98261382f565b6001600160a01b0383166000908152600460209081526040808320546003909252909120546107f89190614979565b6108029190614979565b92915050565b600080600080600080600087116108665760405162461bcd60e51b815260206004820152601860248201527f726564656d7074696f6e2073686f756c64206265203e2030000000000000000060448201526064015b60405180910390fd5b86610870896107be565b10156108e45760405162461bcd60e51b815260206004820152602860248201527f6e757364416d6f756e742063616e6e6f7420737572706173732070726f76696460448201527f6572732064656274000000000000000000000000000000000000000000000000606482015260840161085d565b60006108ee613474565b90506000670de0b6b3a76400006109048b6107be565b6001600160a01b038c1660009081526002602052604090205461092890859061498c565b6109349061271061498c565b61093e91906149a3565b61094891906149a3565b6040517f1ee9211f000000000000000000000000000000000000000000000000000000008152306004820152602481018290529091507f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b031690631ee9211f906044016040805180830381865afa1580156109ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109f291906149de565b9098509650612710610a04888b61498c565b610a0e91906149a3565b9550610a1a868a614a02565b9450612710610a298982614a02565b610a33908761498c565b610a3d91906149a3565b935081610a5285670de0b6b3a764000061498c565b610a5c91906149a3565b925050509295509295509295565b6000610a75826107be565b600003610a8d575069021e19e0c9bab2400000919050565b670de0b6b3a7640000610a9f836107be565b610aa7613474565b6001600160a01b038516600090815260026020526040902054610aca919061498c565b610ad69061271061498c565b610ae091906149a3565b61080291906149a3565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000907f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a76001600160a01b0316906370a0823190602401602060405180830381865afa158015610b6a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8e9190614a15565b905090565b6000807f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b031663e17bbe616040518163ffffffff1660e01b8152600401602060405180830381865afa158015610bf4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c189190614a2e565b6001600160a01b031663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c799190614a65565b505050915050806402540be400610c90919061498c565b91505090565b6040517fae91874900000000000000000000000000000000000000000000000000000000815230600482015260009081906001600160a01b037f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c1513169063ae91874990602401602060405180830381865afa158015610d18573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d3c9190614a15565b610d4584610a6a565b1115610d5657506000928392509050565b6001600160a01b038316600090815260026020819052604090912054610d7c91906149a3565b9150670de0b6b3a7640000610d8f613474565b610d99908461498c565b610da391906149a3565b9050915091565b6001600160a01b038083166000818152600960209081526040808320948616808452948252808320549383526008825280832094835293905291822054670de0b6b3a764000090610dfa85613499565b610e049190614a02565b6001600160a01b038616600090815260026020526040902054610e27919061498c565b610e3191906149a3565b610e3b9190614979565b9392505050565b6040517f4e83423c0000000000000000000000000000000000000000000000000000000081523360048201527f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b031690634e83423c90602401602060405180830381865afa158015610ebf573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee39190614ac5565b610f2f5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420726577617264206d616e616765720000000000000000000000000000604482015260640161085d565b6001600160a01b0382166000908152600660205260409020600101544211610f995760405162461bcd60e51b815260206004820152601a60248201527f52657761726420706572696f64207374696c6c20616374697665000000000000604482015260640161085d565b60008111610fe95760405162461bcd60e51b815260206004820181905260248201527f526577617264206475726174696f6e206d757374206265206e6f6e2d7a65726f604482015260640161085d565b6001600160a01b038216600081815260066020908152604091829020849055815192835282018390527fad2f86b01ed93b4b3a150d448c61a4f5d8d38075d3c0c64cc0a26fd6e1f4954591015b60405180910390a15050565b6040517f3f5068340000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a7811660048301526000917f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c151390911690633f50683490602401602060405180830381865afa1580156110e6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b8e9190614a2e565b600080611115611042565b9050806001600160a01b0316632b11551a6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611155573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c909190614a15565b611181613947565b3360005b600754811015611270576000600782815481106111a4576111a4614ae0565b6000918252602090912001546001600160a01b031690506111c481613499565b6001600160a01b0382166000908152600660205260409020600401556111e981611c83565b6001600160a01b038083166000908152600660205260409020600301919091558316156112675761121a8382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b50600101611185565b5060005b6007548110156113475760006007828154811061129357611293614ae0565b60009182526020808320909101543383526009825260408084206001600160a01b0390921680855291909252912054909150801561133d573360008181526009602090815260408083206001600160a01b03871680855292528220919091556112fc91836139a0565b6040518181526001600160a01b0383169033907f540798df468d7b23d11f156fdb954cb19ad414d150722a7b6d55ba369dea792e9060200160405180910390a35b5050600101611274565b50506113536001600055565b565b6001600160a01b0382166113ab5760405162461bcd60e51b815260206004820152600f60248201527f746f207a65726f20616464726573730000000000000000000000000000000000604482015260640161085d565b806000036113fb5760405162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015260640161085d565b611406338383613a67565b5050565b6001600160a01b0382166000908152600260205260408120548190611430908490614979565b6040517fae9187490000000000000000000000000000000000000000000000000000000081523060048201529091506000906001600160a01b037f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c1513169063ae91874990602401602060405180830381865afa1580156114b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114d79190614a15565b905060006114e4866107be565b6040517fcc143a040000000000000000000000000000000000000000000000000000000081523060048201529091506000906001600160a01b037f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c1513169063cc143a0490602401602060405180830381865afa158015611567573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061158b9190614a15565b90506000670de0b6b3a7640000846115a1613474565b6115ab908861498c565b6115b79061271061498c565b6115c191906149a3565b6115cb91906149a3565b905060006115d98284613e88565b90508084106115f15760009650505050505050610802565b60006115fd8583614a02565b9050611608816130e9565b6116129082614a02565b975050505050505050610802565b60008061162b611d1c565b90508060000361163d57600091505090565b600061164761110a565b6040517fcea12844000000000000000000000000000000000000000000000000000000008152306004820152909150600090612710906001600160a01b037f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c1513169063cea1284490602401602060405180830381865afa1580156116ce573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116f29190614a15565b6116fe90612710614a02565b611708908461498c565b61171291906149a3565b9092109392505050565b60008061172761110a565b6040517f4b3fef610000000000000000000000000000000000000000000000000000000081523060048201529091507f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b031690634b3fef6190602401602060405180830381865afa1580156117a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117cb9190614ac5565b156117fb5760006117da611d1c565b9050806000036117ea5750919050565b6117f48183613e88565b9250505090565b919050565b8260005b6007548110156118ef5760006007828154811061182357611823614ae0565b6000918252602090912001546001600160a01b0316905061184381613499565b6001600160a01b03821660009081526006602052604090206004015561186881611c83565b6001600160a01b038083166000908152600660205260409020600301919091558316156118e6576118998382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b50600101611804565b50336001600160a01b038516036119485760405162461bcd60e51b815260206004820152600e60248201527f6e6f2073656c662072656465656d000000000000000000000000000000000000604482015260640161085d565b60008060006119578787610808565b955050945094505050848110156119d65760405162461bcd60e51b815260206004820152602f60248201527f436f6c6c61746572616c20616d6f756e74206973206c657373207468616e206d60448201527f696e52656365697665416d6f756e740000000000000000000000000000000000606482015260840161085d565b8215611ab0576040517f23b872dd0000000000000000000000000000000000000000000000000000000081523360048201526001600160a01b037f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c151381166024830152604482018590527f0000000000000000000000005aba34e0a32a7c7cef6e6765d478d90031b2338716906323b872dd906064016020604051808303816000875af1158015611a8a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aae9190614ac5565b505b611abb338884613e9e565b6001600160a01b03871660009081526002602052604081208054839290611ae3908490614a02565b90915550611b1d90506001600160a01b037f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a71633836139a0565b60408051848152602081018490529081018290526001600160a01b0388169033907f4f808f68134f8b72b842a276c2b37b03415d4992c65a94fcee50d33201915b999060600160405180910390a350505050505050565b6040517f81ddac3300000000000000000000000000000000000000000000000000000000815230600482015260009081906001600160a01b037f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c151316906381ddac339060240160a060405180830381865afa158015611bf6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1a9190614b21565b8051909150611c2c5750600092915050565b611c35836107be565b600003611c455750600092915050565b806060015161ffff16611c5784610a6a565b1180611c6c5750612710611c6a84610a6a565b105b15611c7a5750600092915050565b610e3b836107be565b6001600160a01b038116600090815260066020526040812060010154610802904290613e88565b6000670de0b6b3a7640000600154611cc0613474565b611cc8610aea565b611cd2919061498c565b611cde9061271061498c565b611ce891906149a3565b610b8e91906149a3565b60078181548110611d0257600080fd5b6000918252602090912001546001600160a01b0316905081565b600080611d27611042565b9050806001600160a01b031663861a1cad6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611155573d6000803e3d6000fd5b6040517f4e83423c0000000000000000000000000000000000000000000000000000000081523360048201527f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b031690634e83423c90602401602060405180830381865afa158015611de4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e089190614ac5565b611e545760405162461bcd60e51b815260206004820152601260248201527f4e6f7420726577617264206d616e616765720000000000000000000000000000604482015260640161085d565b7f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a76001600160a01b0316826001600160a01b031614158015611ec857507f0000000000000000000000005aba34e0a32a7c7cef6e6765d478d90031b233876001600160a01b0316826001600160a01b031614155b611f3a5760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f7420776974686472617720636f6c6c61746572616c20617373657460448201527f206f72206e555344000000000000000000000000000000000000000000000000606482015260840161085d565b6001600160a01b03821660009081526006602052604090206003015415611fa35760405162461bcd60e51b815260206004820152601c60248201527f43616e6e6f742077697468647261772072657761726420746f6b656e00000000604482015260640161085d565b611fb76001600160a01b03831633836139a0565b604080516001600160a01b0384168152602081018390527f8c1256b8896378cd5044f80c202f9772b9d77dc85c8a6eb51967210b09bfaa289101611036565b8260005b6007548110156120e55760006007828154811061201957612019614ae0565b6000918252602090912001546001600160a01b0316905061203981613499565b6001600160a01b03821660009081526006602052604090206004015561205e81611c83565b6001600160a01b038083166000908152600660205260409020600301919091558316156120dc5761208f8382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b50600101611ffa565b5060006120f0613474565b905060006120fd85610a6a565b6040517fd54d832c0000000000000000000000000000000000000000000000000000000081523060048201529091507f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b03169063d54d832c90602401602060405180830381865afa15801561217d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121a19190614a15565b81106122155760405162461bcd60e51b815260206004820152603a60248201527f426f72726f7765727320636f6c6c61746572616c20726174696f2073686f756c60448201527f642062656c6f7720626164436f6c6c61746572616c526174696f000000000000606482015260840161085d565b6001600160a01b0385166000908152600260208190526040909120549061223d90869061498c565b11156122b15760405162461bcd60e51b815260206004820152602960248201527f61206d6178206f662035302520636f6c6c61746572616c2063616e206265206c60448201527f6971756964617465640000000000000000000000000000000000000000000000606482015260840161085d565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b0387811660048301523060248301527f0000000000000000000000005aba34e0a32a7c7cef6e6765d478d90031b23387169063dd62ed3e90604401602060405180830381865afa158015612336573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061235a9190614a15565b15158061236f5750336001600160a01b038716145b6123e15760405162461bcd60e51b815260206004820152603560248201527f70726f76696465722073686f756c6420617574686f72697a6520746f2070726f60448201527f76696465206c69717569646174696f6e206e5553440000000000000000000000606482015260840161085d565b6000670de0b6b3a76400006123f6848761498c565b61240091906149a3565b905061240d878783613e9e565b84612710831180156124205750612af883105b1561243f57612710612432848861498c565b61243c91906149a3565b90505b612af8831061246257600a61245587600b61498c565b61245f91906149a3565b90505b6001600160a01b0387166000908152600260205260408120805483929061248a908490614a02565b90915550506040517fb0900b8700000000000000000000000000000000000000000000000000000000815230600482015260009081907f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b03169063b0900b8790602401602060405180830381865afa158015612511573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125359190614a15565b9050336001600160a01b038b161480159061255b575061255781612710614979565b8510155b156125ad5761271061256d828a61498c565b61257791906149a3565b91506125ad6001600160a01b037f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a71633846139a0565b6125ec8a6125bb8486614a02565b6001600160a01b037f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a71691906139a0565b6040805185815260208101859052908101839052600060608201526001600160a01b03808b169133918d16907fbb234fdd76afd1f5d19ef00827e334a70087bce6bc089670253ffb48737592a09060800160405180910390a450505050505050505050565b600061265b613474565b612663610aea565b610b8e919061498c565b6001600160a01b0382166126c35760405162461bcd60e51b815260206004820152600f60248201527f746f207a65726f20616464726573730000000000000000000000000000000000604482015260640161085d565b806000036127135760405162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015260640161085d565b611406338383613e9e565b6040517f4e83423c0000000000000000000000000000000000000000000000000000000081523360048201527f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b031690634e83423c90602401602060405180830381865afa15801561279b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906127bf9190614ac5565b61280b5760405162461bcd60e51b815260206004820152601260248201527f4e6f7420726577617264206d616e616765720000000000000000000000000000604482015260640161085d565b7f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a76001600160a01b0316826001600160a01b03161415801561287f57507f0000000000000000000000005aba34e0a32a7c7cef6e6765d478d90031b233876001600160a01b0316826001600160a01b031614155b6128f15760405162461bcd60e51b815260206004820152602960248201527f5265776172642063616e6e6f7420626520636f6c6c61746572616c206173736560448201527f74206f72206e5553440000000000000000000000000000000000000000000000606482015260840161085d565b6001600160a01b038216600090815260066020526040902054156129575760405162461bcd60e51b815260206004820152601560248201527f52657761726420616c7265616479206578697374730000000000000000000000604482015260640161085d565b60078054600181019091557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c6880180546001600160a01b039093167fffffffffffffffffffffffff00000000000000000000000000000000000000009093168317905560009182526006602052604090912055565b3360005b600754811015612aba576000600782815481106129ee576129ee614ae0565b6000918252602090912001546001600160a01b03169050612a0e81613499565b6001600160a01b038216600090815260066020526040902060040155612a3381611c83565b6001600160a01b03808316600090815260066020526040902060030191909155831615612ab157612a648382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b506001016129cf565b5060008311612b0b5760405162461bcd60e51b815260206004820152601560248201527f4465706f7369742073686f756c64206265203e20300000000000000000000000604482015260640161085d565b612b406001600160a01b037f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a71633308661424a565b3360009081526002602052604081208054859290612b5f908490614979565b90915550508115612b7557612b75333384613a67565b604080516001600160a01b037f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a7168152602081018590524281830152905133917ff80e165f76857acc123ffe20b1116e9ec31ad7f2c4ecd6f379a9cc9151b50371919081900360600190a2505050565b6040517f4e83423c0000000000000000000000000000000000000000000000000000000081523360048201527f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b031690634e83423c90602401602060405180830381865afa158015612c62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c869190614ac5565b612cd25760405162461bcd60e51b815260206004820152601260248201527f4e6f7420726577617264206d616e616765720000000000000000000000000000604482015260640161085d565b6000805b600754811015612dc157600060078281548110612cf557612cf5614ae0565b6000918252602090912001546001600160a01b03169050612d1581613499565b6001600160a01b038216600090815260066020526040902060040155612d3a81611c83565b6001600160a01b03808316600090815260066020526040902060030191909155831615612db857612d6b8382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b50600101612cd6565b50612dd76001600160a01b03841633308561424a565b6001600160a01b0383166000908152600660205260409020600101544210612e3d576001600160a01b038316600090815260066020526040902054612e1c90836149a3565b6001600160a01b038416600090815260066020526040902060020155612edd565b6001600160a01b038316600090815260066020526040812060010154612e64904290614a02565b6001600160a01b03851660009081526006602052604081206002015491925090612e8e908361498c565b6001600160a01b038616600090815260066020526040902054909150612eb48286614979565b612ebe91906149a3565b6001600160a01b03861660009081526006602052604090206002015550505b6001600160a01b038316600090815260066020526040902042600382018190559054612f0891614979565b6001600160a01b03841660009081526006602090815260409182902060010192909255518381527fde88a922e0d3b88b24e9623efeb464919c6bf9f66857a65e2bfcf2ce87a9433d910160405180910390a1505050565b6001600160a01b03811660009081526006602052604081208054600290910154610802919061498c565b6040517fcc143a040000000000000000000000000000000000000000000000000000000081523060048201526000907f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b03169063cc143a0490602401602060405180830381865afa158015613009573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061302d9190614a15565b6001541061303b5750600090565b6001546040517fcc143a040000000000000000000000000000000000000000000000000000000081523060048201527f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b03169063cc143a0490602401602060405180830381865afa1580156130bb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130df9190614a15565b610b8e9190614a02565b6040517f27480e5e000000000000000000000000000000000000000000000000000000008152306004820152600090819081906001600160a01b037f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c151316906327480e5e906024016040805180830381865afa15801561316c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061319091906149de565b6040517fcc143a0400000000000000000000000000000000000000000000000000000000815230600482015291935091506000906001600160a01b037f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c1513169063cc143a0490602401602060405180830381865afa158015613215573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906132399190614a15565b856001546132479190614979565b61325990670de0b6b3a764000061498c565b61326391906149a3565b9050612710670de0b6b3a7640000868361327d8787614a02565b613287919061498c565b613291919061498c565b61329b91906149a3565b6132a591906149a3565b95945050505050565b6000807f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b0316633b970e1d6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561330f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133339190614a2e565b6040517fdd62ed3e0000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015230602483015291925060009183169063dd62ed3e90604401602060405180830381865afa15801561339e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133c29190614a15565b9050806000036133d6575060009392505050565b6040517f70a082310000000000000000000000000000000000000000000000000000000081526001600160a01b038581166004830152600091908416906370a0823190602401602060405180830381865afa158015613439573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061345d9190614a15565b905080821161346c57816132a5565b949350505050565b6000670de0b6b3a7640000613487610b93565b61348f61171c565b611ce8919061498c565b60006134a36142a1565b6000036134c957506001600160a01b031660009081526006602052604090206004015490565b6134d16142a1565b6001600160a01b038316600090815260066020526040902060028101546003909101546134fd85611c83565b6135079190614a02565b613511919061498c565b61352390670de0b6b3a764000061498c565b61352d91906149a3565b6001600160a01b0383166000908152600660205260409020600401546108029190614979565b3360005b6007548110156136425760006007828154811061357657613576614ae0565b6000918252602090912001546001600160a01b0316905061359681613499565b6001600160a01b0382166000908152600660205260409020600401556135bb81611c83565b6001600160a01b03808316600090815260066020526040902060030191909155831615613639576135ec8382610daa565b6001600160a01b0380851660008181526009602090815260408083209487168084529482528083209590955560068152848220600401549282526008815284822093825292909252919020555b50600101613557565b506001600160a01b0383166136995760405162461bcd60e51b815260206004820152600f60248201527f746f207a65726f20616464726573730000000000000000000000000000000000604482015260640161085d565b816000036136e95760405162461bcd60e51b815260206004820152600b60248201527f7a65726f20616d6f756e74000000000000000000000000000000000000000000604482015260640161085d565b6136f43384846142ab565b505050565b6000613704826107be565b60000361372757506001600160a01b031660009081526002602052604090205490565b6040517fae9187490000000000000000000000000000000000000000000000000000000081523060048201526000907f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b03169063ae91874990602401602060405180830381865afa1580156137a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137cb9190614a15565b9050806137d784610a6a565b116137e55750600092915050565b6137ee83610a6a565b816137f885610a6a565b6138029190614a02565b6001600160a01b038516600090815260026020526040902054613825919061498c565b610e3b91906149a3565b6001600160a01b0381166000908152600560205260408120546301e1338090829061385a9042614a02565b6040517f9fecc37d00000000000000000000000000000000000000000000000000000000815230600482015290915061271090839083906001600160a01b037f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15131690639fecc37d90602401602060405180830381865afa1580156138e2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139069190614a15565b6001600160a01b038816600090815260036020526040902054613929919061498c565b613933919061498c565b61393d91906149a3565b61346c91906149a3565b6002600054036139995760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640161085d565b6002600055565b6040516001600160a01b0383166024820152604481018290526136f49084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152614478565b613a6f611620565b15613ae25760405162461bcd60e51b815260206004820152602660248201527f436f6c6c61746572616c2069732064657065676765642c206d696e74696e672060448201527f7061757365640000000000000000000000000000000000000000000000000000606482015260840161085d565b6040517fcc143a040000000000000000000000000000000000000000000000000000000081523060048201527f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b03169063cc143a0490602401602060405180830381865afa158015613b5f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b839190614a15565b81600154613b919190614979565b1115613bdf5760405162461bcd60e51b815260206004820152600b60248201527f6578636565647320636170000000000000000000000000000000000000000000604482015260640161085d565b613be883614560565b6001600160a01b03831660009081526003602052604081208054839290613c10908490614979565b9091555060009050613c21826130e9565b6040517f40c10f190000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c151381166004830152602482018390529192507f0000000000000000000000005aba34e0a32a7c7cef6e6765d478d90031b23387909116906340c10f19906044016020604051808303816000875af1158015613cce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613cf29190614ac5565b506001600160a01b037f0000000000000000000000005aba34e0a32a7c7cef6e6765d478d90031b23387166340c10f1984613d2d8486614a02565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af1158015613d90573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613db49190614ac5565b508160016000828254613dc79190614979565b90915550613dd69050846145d5565b613e225760405162461bcd60e51b815260206004820152601c60248201527f7573657220697320756e6865616c746879206166746572206d696e7400000000604482015260640161085d565b826001600160a01b0316846001600160a01b03167f458f5fa412d0f69b08dd84872b0215675cc67bc1d5b6fd93300a1c3878b86196848442604051613e7a939291909283526020830191909152604082015260600190565b60405180910390a350505050565b6000818310613e975781610e3b565b5090919050565b613ea782614560565b6001600160a01b0382166000908152600460209081526040808320546003909252822054909190613ee390613edd908490614979565b84613e88565b905081811115614102578115613fe2576040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301527f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c151381166024830152604482018490527f0000000000000000000000005aba34e0a32a7c7cef6e6765d478d90031b2338716906323b872dd906064016020604051808303816000875af1158015613fa3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613fc79190614ac5565b506001600160a01b0384166000908152600460205260408120555b6001600160a01b037f0000000000000000000000005aba34e0a32a7c7cef6e6765d478d90031b2338716639dc29fac8661401c8585614a02565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e085901b1681526001600160a01b03909216600483015260248201526044016020604051808303816000875af115801561407f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140a39190614ac5565b506140ae8282614a02565b6001600160a01b038516600090815260036020526040812080549091906140d6908490614a02565b909155506140e690508282614a02565b600160008282546140f79190614a02565b909155506141fb9050565b6040517f23b872dd0000000000000000000000000000000000000000000000000000000081526001600160a01b0386811660048301527f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c151381166024830152604482018390527f0000000000000000000000005aba34e0a32a7c7cef6e6765d478d90031b2338716906323b872dd906064016020604051808303816000875af11580156141b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906141d69190614ac5565b506141e18183614a02565b6001600160a01b0385166000908152600460205260409020555b604080518281524260208201526001600160a01b0380871692908816917f5d624aa9c148153ab3446c1b154f660ee7701e549fe9b62dab7171b1c80e6fa2910160405180910390a35050505050565b6040516001600160a01b038085166024830152831660448201526064810182905261429b9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016139e5565b50505050565b6000610b8e610aea565b6001600160a01b0383166000908152600260205260409020548111156143395760405162461bcd60e51b815260206004820152602960248201527f576974686472617720616d6f756e742065786365656473206465706f7369746560448201527f6420616d6f756e742e0000000000000000000000000000000000000000000000606482015260840161085d565b6001600160a01b03831660009081526002602052604081208054839290614361908490614a02565b9091555061439b90506001600160a01b037f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a71683836139a0565b60006143a6846107be565b1115614401576143b5836145d5565b6144015760405162461bcd60e51b815260206004820181905260248201527f5573657220697320756e6865616c746879206166746572207769746864726177604482015260640161085d565b604080517f000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a76001600160a01b0390811682526020820184905242828401529151848316928616917f31c6c2b083b6c6fb9c8345de5c29efda3ef312a42d1bc0d4a3029465080809c1919081900360600190a3505050565b60006144cd826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166146df9092919063ffffffff16565b90508051600014806144ee5750808060200190518101906144ee9190614ac5565b6136f45760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840161085d565b6001600160a01b0381166000908152600560205260409020544211156145d2576145898161382f565b6001600160a01b038216600090815260046020526040812080549091906145b1908490614979565b90915550506001600160a01b03811660009081526005602052604090204290555b50565b6000806145e0613474565b6040517fae9187490000000000000000000000000000000000000000000000000000000081523060048201529091507f0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c15136001600160a01b03169063ae91874990602401602060405180830381865afa158015614660573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906146849190614a15565b61468d846107be565b6001600160a01b0385166000908152600260205260409020546146b190849061498c565b6146bd9061271061498c565b6146c791906149a3565b10156146d65750600092915050565b50600192915050565b606061346c848460008585600080866001600160a01b031685876040516147069190614bfa565b60006040518083038185875af1925050503d8060008114614743576040519150601f19603f3d011682016040523d82523d6000602084013e614748565b606091505b509150915061475987838387614764565b979650505050505050565b606083156147d35782516000036147cc576001600160a01b0385163b6147cc5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161085d565b508161346c565b61346c83838151156147e85781518083602001fd5b8060405162461bcd60e51b815260040161085d9190614c16565b6001600160a01b03811681146145d257600080fd5b60006020828403121561482957600080fd5b8135610e3b81614802565b6000806040838503121561484757600080fd5b823561485281614802565b946020939093013593505050565b6000806040838503121561487357600080fd5b823561487e81614802565b9150602083013561488e81614802565b809150509250929050565b6000806000606084860312156148ae57600080fd5b83356148b981614802565b95602085013595506040909401359392505050565b6000602082840312156148e057600080fd5b5035919050565b6000806000606084860312156148fc57600080fd5b833561490781614802565b9250602084013561491781614802565b929592945050506040919091013590565b6000806040838503121561493b57600080fd5b50508035926020909101359150565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156108025761080261494a565b80820281158282048414176108025761080261494a565b6000826149d9577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600080604083850312156149f157600080fd5b505080516020909101519092909150565b818103818111156108025761080261494a565b600060208284031215614a2757600080fd5b5051919050565b600060208284031215614a4057600080fd5b8151610e3b81614802565b805169ffffffffffffffffffff811681146117fb57600080fd5b600080600080600060a08688031215614a7d57600080fd5b614a8686614a4b565b9450602086015193506040860151925060608601519150614aa960808701614a4b565b90509295509295909350565b805180151581146117fb57600080fd5b600060208284031215614ad757600080fd5b610e3b82614ab5565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b805161ffff811681146117fb57600080fd5b600060a08284031215614b3357600080fd5b60405160a0810181811067ffffffffffffffff82111715614b7d577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604052614b8983614ab5565b8152614b9760208401614b0f565b6020820152614ba860408401614b0f565b6040820152614bb960608401614b0f565b6060820152614bca60808401614b0f565b60808201529392505050565b60005b83811015614bf1578181015183820152602001614bd9565b50506000910152565b60008251614c0c818460208701614bd6565b9190910192915050565b6020815260008251806020840152614c35816040850160208701614bd6565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fea2646970667358221220dd68debd4c0c970ea1793a7cf36b2f7f167ee8f5b436e187b795bdb35a09646664736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a70000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c1513
-----Decoded View---------------
Arg [0] : _collateral (address): 0xA1290d69c65A6Fe4DF752f95823fae25cB99e5A7
Arg [1] : _configurator (address): 0x8a65c07f438A631D4209CFBFC680a596BB0c1513
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000a1290d69c65a6fe4df752f95823fae25cb99e5a7
Arg [1] : 0000000000000000000000008a65c07f438a631d4209cfbfc680a596bb0c1513
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 26 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.