More Info
Private Name Tags
ContractCreator
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0xf93ac304840fc80bf97f6b37c3626900edac2aefeeb5b56e6d397727be0395be | Withdraw | (pending) | 2 days ago | IN | 0 ETH | (Pending) | |||
Update Protocol ... | 22268227 | 18 hrs ago | IN | 0 ETH | 0.00036379 | ||||
Update Protocol ... | 22264266 | 31 hrs ago | IN | 0 ETH | 0.00015528 | ||||
Update Protocol ... | 22262800 | 36 hrs ago | IN | 0 ETH | 0.00016356 | ||||
Update Protocol ... | 22257809 | 2 days ago | IN | 0 ETH | 0.00014717 | ||||
Update Protocol ... | 22255838 | 2 days ago | IN | 0 ETH | 0.0001502 | ||||
Update Protocol ... | 22253267 | 2 days ago | IN | 0 ETH | 0.00016529 | ||||
Update Protocol ... | 22244394 | 4 days ago | IN | 0 ETH | 0.00015578 | ||||
Update Protocol ... | 22242032 | 4 days ago | IN | 0 ETH | 0.00014529 | ||||
Update Protocol ... | 22239534 | 4 days ago | IN | 0 ETH | 0.00074394 | ||||
Update Protocol ... | 22238904 | 4 days ago | IN | 0 ETH | 0.00119822 | ||||
Update Protocol ... | 22235765 | 5 days ago | IN | 0 ETH | 0.00014764 | ||||
Update Protocol ... | 22233074 | 5 days ago | IN | 0 ETH | 0.00216008 | ||||
Update Protocol ... | 22232839 | 5 days ago | IN | 0 ETH | 0.00032753 | ||||
Update Protocol ... | 22232825 | 5 days ago | IN | 0 ETH | 0.00015303 | ||||
Update Protocol ... | 22229877 | 6 days ago | IN | 0 ETH | 0.00015522 | ||||
Update Protocol ... | 22228261 | 6 days ago | IN | 0 ETH | 0.00016896 | ||||
Update Protocol ... | 22228036 | 6 days ago | IN | 0 ETH | 0.00019339 | ||||
Update Protocol ... | 22227136 | 6 days ago | IN | 0 ETH | 0.00015017 | ||||
Update Protocol ... | 22225433 | 6 days ago | IN | 0 ETH | 0.00015272 | ||||
Update Protocol ... | 22222801 | 7 days ago | IN | 0 ETH | 0.00015115 | ||||
Update Protocol ... | 22221118 | 7 days ago | IN | 0 ETH | 0.00018107 | ||||
Update Protocol ... | 22217602 | 7 days ago | IN | 0 ETH | 0.00176732 | ||||
Update Protocol ... | 22217573 | 7 days ago | IN | 0 ETH | 0.00115277 | ||||
Update Protocol ... | 22217540 | 7 days ago | IN | 0 ETH | 0.00068138 |
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
RelayerV2
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; // Core import {QuarantineList} from "./core/QuarantineList.sol"; // Structs import {UserRequest, RequestData, ProcessParam, AssetInfo} from "./core/Structs.sol"; // Utils import {Ownable} from "./utils/Ownable.sol"; import {PercentageMath} from "./utils/PercentageMath.sol"; import {SafeERC20} from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol"; // Interfaces import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol"; import {IFyde} from "./interfaces/IFyde.sol"; import {IGovernanceModule} from "./interfaces/IGovernanceModule.sol"; import {IOracle} from "./interfaces/IOracle.sol"; import {ITaxModule} from "./interfaces/ITaxModule.sol"; ///@title RelayerV2 ///@notice The relayer is the entry point contract for users to interact with the protocol. /// The relayer is monitored by an off-chain keeper that will update the protocol AUM. contract RelayerV2 is QuarantineList { using SafeERC20 for IERC20; /*////////////////////////////////////////////////////////////// STORAGE //////////////////////////////////////////////////////////////*/ ///@notice Fyde contract IFyde public fyde; ///@notice OracleModule contract IOracle public oracleModule; //@notice GovernanceModule contract IGovernanceModule public immutable GOVERNANCE_MODULE; //@notice calculates the tax for protocol actions ITaxModule public taxModule; ///@dev Only used for tracking events offchain uint32 public nonce; ///@notice Threshold of deviation for updating AUM uint16 public deviationThreshold; ///@notice State of the protocol bool public paused; //@notice Swap state bool public swapPaused; /*////////////////////////////////////////////////////////////// ERROR //////////////////////////////////////////////////////////////*/ error ValueOutOfBounds(); error ActionPaused(); error SlippageExceed(); error SwapDisabled(address asset); error AssetNotAllowedInGovernancePool(address asset); error DuplicatesAssets(); /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Pause(uint256 timestamp); event Unpause(uint256 timestamp); event Deposit(uint32 requestId, RequestData request); event Withdraw(uint32 requestId, RequestData request); event Swap(uint32 requestId, RequestData request); /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(address _oracleModule, address _govModule, uint8 _deviationThreshold) Ownable(msg.sender) { oracleModule = IOracle(_oracleModule); GOVERNANCE_MODULE = IGovernanceModule(_govModule); updateDeviationThreshold(_deviationThreshold); } /*////////////////////////////////////////////////////////////// GUARD //////////////////////////////////////////////////////////////*/ ///@notice Pause the protocol function pauseProtocol() public onlyGuard { paused = true; emit Pause(block.timestamp); } ///@notice Pause the swaps function pauseSwap() external onlyGuard { swapPaused = true; emit Pause(block.timestamp); } /*////////////////////////////////////////////////////////////// OWNER //////////////////////////////////////////////////////////////*/ ///@notice sets the addres of fyde contract ///@param _fyde address of fyde function setFyde(address _fyde) external onlyOwner { fyde = IFyde(_fyde); } ///@notice Set the oracle module function setOracleModule(address _oracleModule) external onlyOwner { oracleModule = IOracle(_oracleModule); } ///@notice Set the tax module function setTaxModule(address _taxModule) external onlyOwner { taxModule = ITaxModule(_taxModule); } ///@notice Change the deviation threshold ///@dev 50 = 0.5 % of deviation function updateDeviationThreshold(uint16 _threshold) public onlyOwner { // We bound the threshold between 0.1 % to 10% if (_threshold < 10 || _threshold > 1000) revert ValueOutOfBounds(); deviationThreshold = _threshold; } ///@notice Approve Fyde to transfer token from relayer, should be called once per asset function approveFyde(address[] calldata _assets) external onlyOwner { for (uint256 i; i < _assets.length; ++i) { IERC20(_assets[i]).safeApprove(address(fyde), type(uint256).max); } } ///@notice Collect and send token fees (from tax fees) to an external address ///@param _asset Address to send fees to ///@param _recipient Address to send fees to ///@param _amount Amount to send function collectFees(address _asset, address _recipient, uint256 _amount) external onlyOwner { IERC20(_asset).safeTransfer(_recipient, _amount); } ///@notice Unpause the protocol function unpauseProtocol() external onlyOwner { paused = false; emit Unpause(block.timestamp); } ///@notice Unpause the swaps function unpauseSwap() external onlyOwner { swapPaused = false; emit Unpause(block.timestamp); } /*////////////////////////////////////////////////////////////// EXT USER ENTRY POINT //////////////////////////////////////////////////////////////*/ ///@notice Entry function for depositing, can be a standard deposit or a governance /// deposit ///@param _userRequest struct containing data ///@param _keepGovRights If true make a governance ///@param _minTRSYExpected Slippage parameter ensuring minimum amout of TRSY to be received function deposit( UserRequest[] calldata _userRequest, bool _keepGovRights, uint256 _minTRSYExpected ) external whenNotPaused onlyUser { address[] memory assetIn = new address[](_userRequest.length); uint256[] memory amountIn = new uint256[](_userRequest.length); for (uint256 i; i < _userRequest.length; ++i) { // Unpack data assetIn[i] = _userRequest[i].asset; amountIn[i] = _userRequest[i].amount; } _checkForDuplicates(assetIn); if (_keepGovRights) _checkIsAllowedInGov(assetIn); RequestData memory req = RequestData({ id: nonce, requestor: address(this), assetIn: assetIn, amountIn: amountIn, assetOut: new address[](0), amountOut: new uint256[](0), keepGovRights: _keepGovRights, slippageChecker: _minTRSYExpected }); nonce++; uint256 currentAUM = fyde.getProtocolAUM(); // Cache prices in oracle (gas savings when fyde reads prices) _enableOracleCache(assetIn); // get params for tax calculation from tax module (ProcessParam[] memory processParam, uint256 sharesToMint,,) = taxModule.getProcessParamDeposit(req, currentAUM); // Slippage checker if (req.slippageChecker > sharesToMint) revert SlippageExceed(); // Transfer assets to Relayer for (uint256 i; i < req.assetIn.length; ++i) { IERC20(req.assetIn[i]).safeTransferFrom(msg.sender, address(this), req.amountIn[i]); } // Deposit fyde.processDeposit(currentAUM, req); if (_keepGovRights) { for (uint256 i; i < processParam.length; ++i) { // send staked trsy to the user address sTrsy = GOVERNANCE_MODULE.assetToStrsy(req.assetIn[i]); uint256 strsyBal = IERC20(sTrsy).balanceOf(address(this)); uint256 toTransfer = strsyBal >= processParam[i].sharesAfterTax ? processParam[i].sharesAfterTax : strsyBal; IERC20(sTrsy).transfer(msg.sender, toTransfer); // unstake tax amount to get standard trsy uint256 taxTrsy = strsyBal - toTransfer; if (taxTrsy != 0) GOVERNANCE_MODULE.unstakeGov(taxTrsy, req.assetIn[i]); } } else { // send trsy to user IERC20(address(fyde)).transfer(msg.sender, sharesToMint); } _disableOracleCache(); emit Deposit(req.id, req); } ///@notice Entry function for withdrawing ///@param _userRequest struct containing data ///@param _maxTRSYToPay Slippage parameter ensure maximum amout of TRSY willing to pay function withdraw(UserRequest[] calldata _userRequest, uint256 _maxTRSYToPay) external whenNotPaused onlyUser { address[] memory assetOut = new address[](_userRequest.length); uint256[] memory amountOut = new uint256[](_userRequest.length); for (uint256 i; i < _userRequest.length; i++) { assetOut[i] = _userRequest[i].asset; amountOut[i] = _userRequest[i].amount; } _checkForDuplicates(assetOut); RequestData memory req = RequestData({ id: nonce, requestor: address(this), assetIn: new address[](0), amountIn: new uint256[](0), assetOut: assetOut, amountOut: amountOut, keepGovRights: false, slippageChecker: _maxTRSYToPay }); nonce++; uint256 currentAUM = fyde.getProtocolAUM(); _enableOracleCache(assetOut); // get params for tax calculation from tax module (, uint256 totalSharesToBurn,,,) = taxModule.getProcessParamWithdraw(req, currentAUM); if (totalSharesToBurn > req.slippageChecker) revert SlippageExceed(); // Transfer TRSY to Relayer IERC20(address(fyde)).transferFrom(msg.sender, address(this), totalSharesToBurn); // Withdraw fyde.processWithdraw(currentAUM, req); // Transfer assets to user for (uint256 i; i < req.assetOut.length; ++i) { IERC20(req.assetOut[i]).safeTransfer(msg.sender, req.amountOut[i]); } _disableOracleCache(); emit Withdraw(req.id, req); } ///@notice Function used by user to make a (single-token) withdrawal from their governance proxy ///@param _userRequest struct containing data ///@param _user address of user who makes the withdraw ///@param _maxTRSYToPay maximum amout of stTRSY willing to pay, otherwise withdraw reverts ///@dev owner of fyde can force withdraw for other users function governanceWithdraw(UserRequest memory _userRequest, address _user, uint256 _maxTRSYToPay) external whenNotPaused onlyUser { if (msg.sender != _user && msg.sender != owner) revert Unauthorized(); address[] memory assetOut = new address[](1); uint256[] memory amountOut = new uint256[](1); assetOut[0] = _userRequest.asset; amountOut[0] = _userRequest.amount; // for withdraw, assetIn and amountIn are set to empty array RequestData memory request = RequestData({ id: nonce, requestor: _user, assetIn: new address[](0), amountIn: new uint256[](0), assetOut: assetOut, amountOut: amountOut, keepGovRights: true, slippageChecker: _maxTRSYToPay }); nonce++; uint256 currentAUM = fyde.getProtocolAUM(); fyde.processWithdraw(currentAUM, request); emit Withdraw(request.id, request); } /*////////////////////////////////////////////////////////////// SWAP //////////////////////////////////////////////////////////////*/ function swap(address _assetIn, uint256 _amountIn, address _assetOut, uint256 _minAmountOut) external whenSwapNotPaused onlySwapper { address[] memory assetIn = new address[](1); uint256[] memory amountIn = new uint256[](1); address[] memory assetOut = new address[](1); uint256[] memory amountOut = new uint256[](1); assetIn[0] = _assetIn; amountIn[0] = _amountIn; assetOut[0] = _assetOut; RequestData memory req = RequestData({ id: nonce, requestor: address(this), assetIn: assetIn, amountIn: amountIn, assetOut: assetOut, amountOut: amountOut, keepGovRights: false, slippageChecker: _minAmountOut }); nonce++; uint256 currentAUM = fyde.getProtocolAUM(); address[] memory assetsSwap = new address[](2); assetsSwap[0] = _assetIn; assetsSwap[1] = _assetOut; _enableOracleCache(assetsSwap); // get params for tax calculation from taxModule (uint256 amountOutTaxed,) = taxModule.getSwapAmountOut(req.assetIn[0], req.amountIn[0], req.assetOut[0], currentAUM); // Transfer asset to Relayer IERC20(req.assetIn[0]).safeTransferFrom(msg.sender, address(this), req.amountIn[0]); fyde.processSwap(currentAUM, req); uint256 tokenBalance = IERC20(assetOut[0]).balanceOf(address(this)); amountOutTaxed = amountOutTaxed > tokenBalance ? tokenBalance : amountOutTaxed; if (amountOutTaxed < req.slippageChecker) revert SlippageExceed(); // Transfer assets to swapper IERC20(req.assetOut[0]).safeTransfer(msg.sender, amountOutTaxed); emit Swap(req.id, req); // deposit tax to receive trsy amountIn[0] = tokenBalance - amountOutTaxed; if (amountIn[0] > 0) { req = RequestData({ id: nonce, requestor: address(this), assetIn: assetOut, amountIn: amountIn, assetOut: new address[](0), amountOut: new uint256[](0), keepGovRights: false, slippageChecker: 0 }); nonce++; currentAUM = fyde.getProtocolAUM(); fyde.processDeposit(currentAUM, req); } _disableOracleCache(); } /*////////////////////////////////////////////////////////////// Keeper FUNCTIONS //////////////////////////////////////////////////////////////*/ ///@notice Offchain checker for AUM deviation function checkUpkeep(bytes calldata checkData) external view returns (bool upkeepNeeded, bytes memory performData) { (uint256 updateFactor, uint256 pauseFactor, bool isChainlink) = abi.decode(checkData, (uint256, uint256, bool)); uint256 aum = fyde.getProtocolAUM(); uint256 nAum = fyde.computeProtocolAUM(); // AUM in range of deviation threshold times update factor do nothing if (PercentageMath._isInRange(aum, nAum, updateFactor * deviationThreshold / 100)) { return (false, "AUM is in range"); } // if stored AUM exceeds the maximum deviation threshold by the pause factor // something is wrong and we stop the protocol if (!PercentageMath._isInRange(aum, nAum, pauseFactor * deviationThreshold / 100) && !paused) { if (isChainlink) return (true, abi.encode(false, 0)); return (true, abi.encodeCall(this.performUpkeep, (abi.encode(false, 0)))); } // if not in range and not outside the wider range, update AUM int256 diffAUM = int256(nAum) - int256(aum); if (isChainlink) return (true, abi.encode(true, diffAUM)); return (true, abi.encodeCall(this.performUpkeep, (abi.encode(true, diffAUM)))); } function performUpkeep(bytes calldata performData) external { (bool updateAum, int256 diffAUM) = abi.decode(performData, (bool, int256)); if (!updateAum) { pauseProtocol(); } else { uint256 nAum = uint256(int256(fyde.getProtocolAUM()) + diffAUM); updateProtocolAUM(nAum); } } ///@notice Update the protocol AUM, called by Keeper function updateProtocolAUM(uint256 nAum) public onlyKeeper { fyde.updateProtocolAUM(nAum); } /*////////////////////////////////////////////////////////////// INTERNAL //////////////////////////////////////////////////////////////*/ function _enableOracleCache(address[] memory assets) internal { AssetInfo[] memory assetInfos = new AssetInfo[](assets.length); for (uint256 i; i < assets.length; ++i) { assetInfos[i] = fyde.assetInfo(assets[i]); } oracleModule.useCache(assets, assetInfos); } function _disableOracleCache() internal { oracleModule.disableCache(); } function _checkIsAllowedInGov(address[] memory _assets) internal view { address notAllowedInGovAsset = GOVERNANCE_MODULE.isAnyNotOnGovWhitelist(_assets); if (notAllowedInGovAsset != address(0x0)) { revert AssetNotAllowedInGovernancePool(notAllowedInGovAsset); } } function _checkForDuplicates(address[] memory _assetList) internal pure { for (uint256 idx; idx < _assetList.length - 1; idx++) { for (uint256 idx2 = idx + 1; idx2 < _assetList.length; idx2++) { if (_assetList[idx] == _assetList[idx2]) revert DuplicatesAssets(); } } } function _uint2str(uint256 _i) internal pure returns (string memory) { if (_i == 0) return "0"; uint256 j = _i; uint256 len; while (j != 0) { len++; j /= 10; } bytes memory bstr = new bytes(len); uint256 k = len; while (_i != 0) { k = k - 1; uint8 temp = (48 + uint8(_i - (_i / 10) * 10)); bytes1 b1 = bytes1(temp); bstr[k] = b1; _i /= 10; } return string(bstr); } modifier whenNotPaused() { if (paused) revert ActionPaused(); _; } modifier whenSwapNotPaused() { if (swapPaused) revert ActionPaused(); _; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; import {AccessControl} from "./AccessControl.sol"; ///@title QuarantineList contract ///@notice Handle the logic for the quarantine list abstract contract QuarantineList is AccessControl { /// ----------------------------- /// Storage /// ----------------------------- uint256 public min_quarantine_duration = 1 days; mapping(address => uint128) public quarantineList; /// ----------------------------- /// Events /// ----------------------------- event AddedToQuarantine(address asset, uint128 expirationTime); event RemovedFromQuarantine(address asset); /// ----------------------------- /// Errors /// ----------------------------- error AssetIsQuarantined(address asset); error AssetIsNotQuarantined(address asset); error ShortenedExpiration(uint128 currentExpiration, uint128 expiration); error ShortQurantineDuration(uint128 duration); /// ----------------------------- /// Admin external /// ----------------------------- ///@notice Set the minimum quarantine duration ///@param _min_quarantine_duration the new minimum quarantine duration function set_min_quarantine_duration(uint256 _min_quarantine_duration) external onlyOwner { min_quarantine_duration = _min_quarantine_duration; } ///@notice Add an asset to the quarantine list ///@param _asset the address of the assset to be added to the quarantine list ///@param _duration the time (in seconds) that the asset should stay in quarantine function addToQuarantine(address _asset, uint128 _duration) external onlyGuard { if (_duration < min_quarantine_duration) revert ShortQurantineDuration(_duration); // gas savings uint128 expiration = uint128(block.timestamp) + _duration; uint128 currentExpiration = quarantineList[_asset]; // the new expiration cannot be before the curent one i.e. expiration cannot be reduced, just // extended if (expiration <= currentExpiration) revert ShortenedExpiration(currentExpiration, expiration); quarantineList[_asset] = expiration; emit AddedToQuarantine(_asset, expiration); } ///@notice Remove an asset from the quarantine list ///@param _asset the address of the assset to be removed from the quarantine list function removeFromQuarantine(address _asset) external onlyGuard { // If the asset has nto been quarantined or the duarion period has expired then revert if (quarantineList[_asset] < uint128(block.timestamp)) revert AssetIsNotQuarantined(_asset); // just set the duration to zero to remove from quarantine quarantineList[_asset] = 0; emit RemovedFromQuarantine(_asset); } /// ----------------------------- /// External view functions /// ----------------------------- ///@notice Check if an asset is quarantined ///@param _asset the address of the assset to be checked function isQuarantined(address _asset) public view returns (bool) { return quarantineList[_asset] >= uint128(block.timestamp); } ///@notice Check if any asset from a given list is quarantined ///@param _assets an array of asset addresses that need to be checked ///@return address of first quarantined asset or address(0x0) if none quarantined function isAnyQuarantined(address[] memory _assets) public view returns (address) { for (uint256 i = 0; i < _assets.length;) { if (isQuarantined(_assets[i])) return _assets[i]; unchecked { ++i; } } return address(0x0); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; struct AssetInfo { uint72 targetConcentration; address uniswapPool; int72 incentiveFactor; uint8 assetDecimals; uint8 quoteTokenDecimals; address uniswapQuoteToken; bool isSupported; } struct ProtocolData { ///@notice Protocol AUM in USD uint256 aum; ///@notice multiplicator for the tax equation, 100% = 100e18 uint72 taxFactor; ///@notice Max deviation allowed between AUM from keeper and registry uint16 maxAumDeviationAllowed; // Default val 200 == 2 % ///@notice block number where AUM was last updated uint48 lastAUMUpdateBlock; ///@notice annual fee on AUM, in % per year 100% = 100e18 uint72 managementFee; ///@notice last block.timestamp when fee was collected uint48 lastFeeCollectionTime; } struct UserRequest { address asset; uint256 amount; } struct RequestData { uint32 id; address requestor; address[] assetIn; uint256[] amountIn; address[] assetOut; uint256[] amountOut; bool keepGovRights; uint256 slippageChecker; } struct RequestQ { uint64 start; uint64 end; mapping(uint64 => RequestData) requestData; } struct ProcessParam { uint256 targetConc; uint256 currentConc; uint256 usdValue; uint256 taxableAmount; uint256 taxInUSD; uint256 sharesBeforeTax; uint256 sharesAfterTax; } struct RebalanceParam { address asset; uint256 assetTotalAmount; uint256 assetProxyAmount; uint256 assetPrice; uint256 sTrsyTotalSupply; uint256 trsyPrice; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.19; ///@title Ownable contract /// @notice Simple 2step owner authorization combining solmate and OZ implementation abstract contract Ownable { /*////////////////////////////////////////////////////////////// STORAGE //////////////////////////////////////////////////////////////*/ ///@notice Address of the owner address public owner; ///@notice Address of the pending owner address public pendingOwner; /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event OwnershipTransferred(address indexed user, address indexed newOner); event OwnershipTransferStarted(address indexed user, address indexed newOwner); event OwnershipTransferCanceled(address indexed pendingOwner); /*////////////////////////////////////////////////////////////// ERROR //////////////////////////////////////////////////////////////*/ error Unauthorized(); /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(address _owner) { owner = _owner; emit OwnershipTransferred(address(0), _owner); } /*////////////////////////////////////////////////////////////// OWNERSHIP LOGIC //////////////////////////////////////////////////////////////*/ ///@notice Transfer ownership to a new address ///@param newOwner address of the new owner ///@dev newOwner have to acceptOwnership function transferOwnership(address newOwner) external onlyOwner { pendingOwner = newOwner; emit OwnershipTransferStarted(msg.sender, pendingOwner); } ///@notice NewOwner accept the ownership, it transfer the ownership to newOwner function acceptOwnership() external { if (msg.sender != pendingOwner) revert Unauthorized(); address oldOwner = owner; owner = pendingOwner; delete pendingOwner; emit OwnershipTransferred(oldOwner, owner); } ///@notice Cancel the ownership transfer function cancelTransferOwnership() external onlyOwner { emit OwnershipTransferCanceled(pendingOwner); delete pendingOwner; } modifier onlyOwner() { if (msg.sender != owner) revert Unauthorized(); _; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; library PercentageMath { /// CONSTANTS /// uint256 internal constant PERCENTAGE_FACTOR = 1e4; // 100.00% uint256 internal constant HALF_PERCENTAGE_FACTOR = 0.5e4; // 50.00% uint256 internal constant MAX_UINT256 = 2 ** 256 - 1; uint256 internal constant MAX_UINT256_MINUS_HALF_PERCENTAGE = 2 ** 256 - 1 - 0.5e4; /// INTERNAL /// ///@notice Check if value are within the range function _isInRange(uint256 valA, uint256 valB, uint256 deviationThreshold) internal pure returns (bool) { uint256 lowerBound = percentSub(valA, deviationThreshold); uint256 upperBound = percentAdd(valA, deviationThreshold); if (valB < lowerBound || valB > upperBound) return false; else return true; } /// @notice Executes a percentage addition (x * (1 + p)), rounded up. /// @param x The value to which to add the percentage. /// @param percentage The percentage of the value to add. /// @return y The result of the addition. function percentAdd(uint256 x, uint256 percentage) internal pure returns (uint256 y) { // Must revert if // PERCENTAGE_FACTOR + percentage > type(uint256).max // or x * (PERCENTAGE_FACTOR + percentage) + HALF_PERCENTAGE_FACTOR > type(uint256).max // <=> percentage > type(uint256).max - PERCENTAGE_FACTOR // or x > (type(uint256).max - HALF_PERCENTAGE_FACTOR) / (PERCENTAGE_FACTOR + percentage) // Note: PERCENTAGE_FACTOR + percentage >= PERCENTAGE_FACTOR > 0 assembly { y := add(PERCENTAGE_FACTOR, percentage) // Temporary assignment to save gas. if or( gt(percentage, sub(MAX_UINT256, PERCENTAGE_FACTOR)), gt(x, div(MAX_UINT256_MINUS_HALF_PERCENTAGE, y)) ) { revert(0, 0) } y := div(add(mul(x, y), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR) } } /// @notice Executes a percentage subtraction (x * (1 - p)), rounded up. /// @param x The value to which to subtract the percentage. /// @param percentage The percentage of the value to subtract. /// @return y The result of the subtraction. function percentSub(uint256 x, uint256 percentage) internal pure returns (uint256 y) { // Must revert if // percentage > PERCENTAGE_FACTOR // or x * (PERCENTAGE_FACTOR - percentage) + HALF_PERCENTAGE_FACTOR > type(uint256).max // <=> percentage > PERCENTAGE_FACTOR // or ((PERCENTAGE_FACTOR - percentage) > 0 and x > (type(uint256).max - // HALF_PERCENTAGE_FACTOR) / (PERCENTAGE_FACTOR - percentage)) assembly { y := sub(PERCENTAGE_FACTOR, percentage) // Temporary assignment to save gas. if or( gt(percentage, PERCENTAGE_FACTOR), mul(y, gt(x, div(MAX_UINT256_MINUS_HALF_PERCENTAGE, y))) ) { revert(0, 0) } y := div(add(mul(x, y), HALF_PERCENTAGE_FACTOR), PERCENTAGE_FACTOR) } } }
// 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 // 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: UNLICENSED pragma solidity 0.8.19; import {RequestData, RebalanceParam, ProcessParam, AssetInfo} from "src/core/Structs.sol"; interface IFyde { function protocolData() external view returns (uint256, uint72, uint16, uint48, uint72, uint48); function assetInfo(address) external view returns (AssetInfo memory); function isAnyNotSupported(address[] calldata _assets) external view returns (address); function isSwapAllowed(address[] calldata _assets) external view returns (address); function computeProtocolAUM() external view returns (uint256); function getProtocolAUM() external view returns (uint256); function updateProtocolAUM(uint256) external; function processDeposit(uint256, RequestData calldata) external returns (uint256); function processWithdraw(uint256, RequestData calldata) external returns (uint256); function totalSupply() external view returns (uint256); function setOracleModule(address _oracle) external; function oracleModule() external view returns (address); function setRelayer(address _relayer) external; function RELAYER() external view returns (address); function totalAssetAccounting(address) external view returns (uint256); function proxyAssetAccounting(address) external view returns (uint256); function standardAssetAccounting(address) external view returns (uint256); function getQuote(address, uint256) external view returns (uint256); function getAssetDecimals(address) external view returns (uint8); function collectManagementFee() external; function getAssetsListLength() external view returns (uint256); function assetsList(uint256 index) external view returns (address); function processSwap(uint256, RequestData calldata) external returns (int256); function owner() external view returns (address); function getProcessParamDeposit(RequestData memory _req, uint256 _protocolAUM) external view returns ( ProcessParam[] memory processParam, uint256 sharesToMint, uint256 taxInTRSY, uint256 totalUsdDeposit ); function getProcessParamWithdraw(RequestData calldata _req, uint256 _protocolAUM) external view returns ( ProcessParam[] memory processParam, uint256 totalSharesToBurn, uint256 sharesToBurnBeforeTax, uint256 taxInTRSY, uint256 totalUsdWithdraw ); function acceptOwnership() external; // GOVERNANCE ACCESS FUNCTIONS function transferAsset(address _asset, address _recipient, uint256 _amount) external; function getRebalanceParams(address _asset) external view returns (RebalanceParam memory); function updateAssetProxyAmount(address _asset, uint256 _amount) external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.19; interface IGovernanceModule { function fyde() external view returns (address); function proxyImplementation() external view returns (address); function proxyBalance(address proxy, address asset) external view returns (uint256); function strsyBalance(address _user, address _govToken) external view returns (uint256 balance); function assetToStrsy(address _asset) external view returns (address); function userToProxy(address _user) external view returns (address); function proxyToUser(address _proxy) external view returns (address); function isOnGovernanceWhitelist(address _asset) external view returns (bool); function getAllGovUsers() external view returns (address[] memory); function isAnyNotOnGovWhitelist(address[] calldata _assets) external view returns (address); function getUserGTAllowance(uint256 _TRSYAmount, address _token) external view returns (uint256); function govDeposit( address _depositor, address[] calldata _govToken, uint256[] calldata _amount, uint256[] calldata _amountTRSY, uint256 _totalTRSY ) external returns (address proxy); function govWithdraw( address _user, address _asset, uint256 _amountToWithdraw, uint256 _trsyToBurn ) external; function onStrsyTransfer(address sender, address _recipient) external; function unstakeGov(uint256 _amount, address _asset) external; function rebalanceProxy(address _proxy, address _asset, address[] memory _usersToRebalance) external; function acceptOwnership() external; }
//SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.19; import {AssetInfo} from "../core/Structs.sol"; interface IOracle { function getPriceInUSD(address, AssetInfo calldata) external view returns (uint256); function getGweiPrice() external view returns (uint256); function useCache(address[] calldata addr, AssetInfo[] calldata assetInfo) external; function disableCache() external; }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.19; import {RequestData, ProcessParam} from "src/core/Structs.sol"; interface ITaxModule { function getProcessParamDeposit(RequestData memory _req, uint256 _protocolAUM) external view returns ( ProcessParam[] memory processParam, uint256 sharesToMint, uint256 taxInTRSY, uint256 totalUsdDeposit ); function getProcessParamWithdraw(RequestData calldata _req, uint256 _protocolAUM) external view returns ( ProcessParam[] memory processParam, uint256 totalSharesToBurn, uint256 sharesToBurnBeforeTax, uint256 taxInTRSY, uint256 totalUsdWithdraw ); function getSwapAmountOut( address _assetIn, uint256 _amountIn, address _assetOut, uint256 _protocolAUM ) external view returns (uint256, int256); }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; import {Ownable} from "src/utils/Ownable.sol"; ///@title AccessControl /// @notice Handles the different access authorizations for the relayer abstract contract AccessControl is Ownable { /*////////////////////////////////////////////////////////////// STORAGE //////////////////////////////////////////////////////////////*/ ///@notice exclusive user - when != address(0x0), other users are removed from whitelist /// intended for short term use during incidence response, escrow, migration address public exclusiveUser; ///@notice guard authorization mapping(address => bool) public isGuard; ///@notice keeper authorization mapping(address => bool) public isKeeper; ///@notice user authorization, can use deposit, withdraw mapping(address => bool) public isUser; ///@notice swapper authorization, can use swap mapping(address => bool) public isSwapper; ///@notice incentive manager authorization, can set incentives for swaps on Fyde mapping(address => bool) public isIncentiveManager; /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event ExclusiveUserSet(address indexed); event GuardAdded(address indexed); event GuardRemoved(address indexed); event KeeperAdded(address indexed); event KeeperRemoved(address indexed); event UserAdded(address indexed); event UserRemoved(address indexed); event IncentiveManagerAdded(address indexed); event IncentiveManagerRemoved(address indexed); event SwapperAdded(address indexed); event SwapperRemoved(address indexed); /*////////////////////////////////////////////////////////////// SETTER //////////////////////////////////////////////////////////////*/ function setExclusiveUser(address _exclusiveUser) external onlyOwner { exclusiveUser = _exclusiveUser; emit ExclusiveUserSet(_exclusiveUser); } function addGuard(address _guard) external onlyOwner { isGuard[_guard] = true; emit GuardAdded(_guard); } function removeGuard(address _guard) external onlyOwner { isGuard[_guard] = false; emit GuardRemoved(_guard); } function addKeeper(address _keeper) external onlyOwner { isKeeper[_keeper] = true; emit KeeperAdded(_keeper); } function removeKeeper(address _keeper) external onlyOwner { isKeeper[_keeper] = false; emit KeeperRemoved(_keeper); } function addUser(address[] calldata _user) external onlyOwner { for (uint256 i; i < _user.length; ++i) { isUser[_user[i]] = true; emit UserAdded(_user[i]); } } function removeUser(address[] calldata _user) external onlyOwner { for (uint256 i; i < _user.length; ++i) { isUser[_user[i]] = false; emit UserRemoved(_user[i]); } } function addIncentiveManager(address _incentiveManager) external onlyOwner { isIncentiveManager[_incentiveManager] = true; emit IncentiveManagerAdded(_incentiveManager); } function removeIncentiveManager(address _incentiveManager) external onlyOwner { isIncentiveManager[_incentiveManager] = false; emit IncentiveManagerRemoved(_incentiveManager); } function addSwapper(address _swapper) external onlyOwner { isSwapper[_swapper] = true; emit SwapperAdded(_swapper); } function removeSwapper(address _swapper) external onlyOwner { isSwapper[_swapper] = false; emit SwapperRemoved(_swapper); } /*////////////////////////////////////////////////////////////// MODIFIER //////////////////////////////////////////////////////////////*/ ///@notice only a registered keeper can access modifier onlyKeeper() { if (!isKeeper[msg.sender]) revert Unauthorized(); _; } ///@notice only a registered guard can access modifier onlyGuard() { if (!isGuard[msg.sender]) revert Unauthorized(); _; } ///@dev whitelisting address(0x0) disables whitelist -> full permissionless access ///@dev setting exclusiveUser to != address(0x0) blocks everyone else /// - intended for escrow, incidence response and migration modifier onlyUser() { // if whitelist is not disabeld and user not whitelisted -> no access if (!isUser[address(0x0)] && !isUser[msg.sender]) revert Unauthorized(); // if exclusive user exists and is not user -> no accesss if (exclusiveUser != address(0x0) && exclusiveUser != msg.sender) revert Unauthorized(); _; } ///@dev whitelisting address(0x0) disables whitelist -> full permissionless access ///@dev setting exclusiveUser to != address(0x0) blocks everyone else /// - intended for escrow, incidence response and migration modifier onlySwapper() { if (!isSwapper[address(0x0)] && !isSwapper[msg.sender]) revert Unauthorized(); if (exclusiveUser != address(0x0) && exclusiveUser != msg.sender) revert Unauthorized(); _; } }
// 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": [ "@uniswap/v3-core/=lib/v3-core/", "@uniswap/v3-periphery/=lib/v3-periphery/", "openzeppelin-contracts/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts-upgradeable/=lib/openzeppelin-contracts-upgradeable/", "openzeppelin/=lib/openzeppelin-contracts/contracts/", "solmate/=lib/solmate/src/", "synthetix-v3/=lib/synthetix-v3/", "v3-core/=lib/v3-core/contracts/", "v3-periphery/=lib/v3-periphery/contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "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
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_oracleModule","type":"address"},{"internalType":"address","name":"_govModule","type":"address"},{"internalType":"uint8","name":"_deviationThreshold","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ActionPaused","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetIsNotQuarantined","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetIsQuarantined","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetNotAllowedInGovernancePool","type":"error"},{"inputs":[],"name":"DuplicatesAssets","type":"error"},{"inputs":[{"internalType":"uint128","name":"duration","type":"uint128"}],"name":"ShortQurantineDuration","type":"error"},{"inputs":[{"internalType":"uint128","name":"currentExpiration","type":"uint128"},{"internalType":"uint128","name":"expiration","type":"uint128"}],"name":"ShortenedExpiration","type":"error"},{"inputs":[],"name":"SlippageExceed","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"SwapDisabled","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ValueOutOfBounds","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"uint128","name":"expirationTime","type":"uint128"}],"name":"AddedToQuarantine","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"requestId","type":"uint32"},{"components":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"requestor","type":"address"},{"internalType":"address[]","name":"assetIn","type":"address[]"},{"internalType":"uint256[]","name":"amountIn","type":"uint256[]"},{"internalType":"address[]","name":"assetOut","type":"address[]"},{"internalType":"uint256[]","name":"amountOut","type":"uint256[]"},{"internalType":"bool","name":"keepGovRights","type":"bool"},{"internalType":"uint256","name":"slippageChecker","type":"uint256"}],"indexed":false,"internalType":"struct RequestData","name":"request","type":"tuple"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"}],"name":"ExclusiveUserSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"}],"name":"GuardAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"}],"name":"GuardRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"}],"name":"IncentiveManagerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"}],"name":"IncentiveManagerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"}],"name":"KeeperAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"}],"name":"KeeperRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pendingOwner","type":"address"}],"name":"OwnershipTransferCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Pause","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"asset","type":"address"}],"name":"RemovedFromQuarantine","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"requestId","type":"uint32"},{"components":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"requestor","type":"address"},{"internalType":"address[]","name":"assetIn","type":"address[]"},{"internalType":"uint256[]","name":"amountIn","type":"uint256[]"},{"internalType":"address[]","name":"assetOut","type":"address[]"},{"internalType":"uint256[]","name":"amountOut","type":"uint256[]"},{"internalType":"bool","name":"keepGovRights","type":"bool"},{"internalType":"uint256","name":"slippageChecker","type":"uint256"}],"indexed":false,"internalType":"struct RequestData","name":"request","type":"tuple"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"}],"name":"SwapperAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"}],"name":"SwapperRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"timestamp","type":"uint256"}],"name":"Unpause","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"}],"name":"UserAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"","type":"address"}],"name":"UserRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"requestId","type":"uint32"},{"components":[{"internalType":"uint32","name":"id","type":"uint32"},{"internalType":"address","name":"requestor","type":"address"},{"internalType":"address[]","name":"assetIn","type":"address[]"},{"internalType":"uint256[]","name":"amountIn","type":"uint256[]"},{"internalType":"address[]","name":"assetOut","type":"address[]"},{"internalType":"uint256[]","name":"amountOut","type":"uint256[]"},{"internalType":"bool","name":"keepGovRights","type":"bool"},{"internalType":"uint256","name":"slippageChecker","type":"uint256"}],"indexed":false,"internalType":"struct RequestData","name":"request","type":"tuple"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"GOVERNANCE_MODULE","outputs":[{"internalType":"contract IGovernanceModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_guard","type":"address"}],"name":"addGuard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_incentiveManager","type":"address"}],"name":"addIncentiveManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_keeper","type":"address"}],"name":"addKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_swapper","type":"address"}],"name":"addSwapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint128","name":"_duration","type":"uint128"}],"name":"addToQuarantine","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_user","type":"address[]"}],"name":"addUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assets","type":"address[]"}],"name":"approveFyde","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cancelTransferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"checkData","type":"bytes"}],"name":"checkUpkeep","outputs":[{"internalType":"bool","name":"upkeepNeeded","type":"bool"},{"internalType":"bytes","name":"performData","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"collectFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct UserRequest[]","name":"_userRequest","type":"tuple[]"},{"internalType":"bool","name":"_keepGovRights","type":"bool"},{"internalType":"uint256","name":"_minTRSYExpected","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"deviationThreshold","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"exclusiveUser","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fyde","outputs":[{"internalType":"contract IFyde","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct UserRequest","name":"_userRequest","type":"tuple"},{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_maxTRSYToPay","type":"uint256"}],"name":"governanceWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assets","type":"address[]"}],"name":"isAnyQuarantined","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isGuard","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isIncentiveManager","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isKeeper","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"isQuarantined","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isSwapper","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isUser","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"min_quarantine_duration","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nonce","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oracleModule","outputs":[{"internalType":"contract IOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseProtocol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"pauseSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"performData","type":"bytes"}],"name":"performUpkeep","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"quarantineList","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"removeFromQuarantine","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_guard","type":"address"}],"name":"removeGuard","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_incentiveManager","type":"address"}],"name":"removeIncentiveManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_keeper","type":"address"}],"name":"removeKeeper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_swapper","type":"address"}],"name":"removeSwapper","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_user","type":"address[]"}],"name":"removeUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_exclusiveUser","type":"address"}],"name":"setExclusiveUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_fyde","type":"address"}],"name":"setFyde","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracleModule","type":"address"}],"name":"setOracleModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_taxModule","type":"address"}],"name":"setTaxModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_min_quarantine_duration","type":"uint256"}],"name":"set_min_quarantine_duration","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_assetIn","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"address","name":"_assetOut","type":"address"},{"internalType":"uint256","name":"_minAmountOut","type":"uint256"}],"name":"swap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"swapPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"taxModule","outputs":[{"internalType":"contract ITaxModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpauseProtocol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpauseSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_threshold","type":"uint16"}],"name":"updateDeviationThreshold","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"nAum","type":"uint256"}],"name":"updateProtocolAUM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"internalType":"struct UserRequest[]","name":"_userRequest","type":"tuple[]"},{"internalType":"uint256","name":"_maxTRSYToPay","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60a0604052620151806008553480156200001857600080fd5b5060405162004c6338038062004c638339810160408190526200003b916200015a565b600080546001600160a01b031916339081178255604051909182917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600b80546001600160a01b0319166001600160a01b03858116919091179091558216608052620000af60ff8216620000b8565b505050620001ad565b6000546001600160a01b03163314620000e3576040516282b42960e81b815260040160405180910390fd5b600a8161ffff161080620000fc57506103e88161ffff16115b156200011b57604051636d4d4a6760e11b815260040160405180910390fd5b600c805461ffff909216600160c01b0261ffff60c01b19909216919091179055565b80516001600160a01b03811681146200015557600080fd5b919050565b6000806000606084860312156200017057600080fd5b6200017b846200013d565b92506200018b602085016200013d565b9150604084015160ff81168114620001a257600080fd5b809150509250925092565b608051614a85620001de6000396000818161037401528181610ddf01528181610fdd01526136b10152614a856000f3fe608060405234801561001057600080fd5b50600436106103425760003560e01c806398fbfbea116101b8578063cdfca7f211610104578063e787caa4116100a2578063ed6b5ad51161007c578063ed6b5ad5146107f9578063f2fde38b14610801578063f80c6d9c14610814578063f93b6be51461082757600080fd5b8063e787caa4146107c0578063e838d0a9146107d3578063ec2a0992146107e657600080fd5b8063dbf62489116100de578063dbf624891461077f578063ddb015c814610787578063e00efe4a1461079a578063e30c3978146107ad57600080fd5b8063cdfca7f21461072d578063d307983d14610740578063d94ad8371461075757600080fd5b8063b623501611610171578063bae2be561161014b578063bae2be56146106e1578063c073fd74146106f4578063c87eed4614610707578063cc88688b1461071a57600080fd5b8063b623501614610698578063b64230ba146106ab578063b813a8df146106ce57600080fd5b806398fbfbea146105fd5780639938500614610610578063a8ad7a0314610623578063affed0e014610636578063b0bdafbe14610662578063b588c10b1461067557600080fd5b8063489c120211610292578063769315a4116102305780638a0ccd561161020a5780638a0ccd56146105bc5780638da5cb5b146105cf57806392fede00146105e257806393263b8a146105ea57600080fd5b8063769315a41461058e57806379ba5097146105a15780637cb1d3df146105a957600080fd5b80636913a63c1161026c5780636913a63c146105245780636ba42aaa146105375780636d9b83ec1461055a5780636e04ff0d1461056d57600080fd5b8063489c1202146104da5780634fd8cb94146104fd5780635c975abb1461051057600080fd5b80633b42d038116102ff5780634209fff1116102d95780634209fff1146104595780634585e33b1461047c578063485d6ef81461048f5780634866788b146104c757600080fd5b80633b42d038146104205780633f2d4131146104335780634032b72b1461044657600080fd5b806314ae9f2e1461034757806316805c811461035c5780631a366bb71461036f57806320157d0a146103b3578063245a4e72146103bb57806339663ef2146103df575b600080fd5b61035a610355366004613e4a565b61082f565b005b61035a61036a366004613eb9565b6108a2565b6103967f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020015b60405180910390f35b61035a61116b565b600c546103cf90600160d81b900460ff1681565b60405190151581526020016103aa565b6104086103ed366004613e4a565b6009602052600090815260409020546001600160801b031681565b6040516001600160801b0390911681526020016103aa565b61035a61042e366004613f15565b6111d8565b61035a610441366004613e4a565b61126c565b61035a610454366004613e4a565b6112df565b6103cf610467366004613e4a565b60056020526000908152604090205460ff1681565b61035a61048a366004613f89565b611355565b6103cf61049d366004613e4a565b6001600160a01b03166000908152600960205260409020546001600160801b034281169116101590565b61035a6104d5366004614056565b611411565b6103cf6104e8366004613e4a565b60036020526000908152604090205460ff1681565b600a54610396906001600160a01b031681565b600c546103cf90600160d01b900460ff1681565b61035a610532366004613e4a565b611807565b6103cf610545366004613e4a565b60046020526000908152604090205460ff1681565b61035a6105683660046140d8565b61187d565b61058061057b366004613f89565b6118ac565b6040516103aa929190614141565b61035a61059c366004613f15565b611bd8565b61035a611cce565b61035a6105b736600461415c565b611d52565b61035a6105ca366004614180565b611dd4565b600054610396906001600160a01b031681565b61035a612652565b600254610396906001600160a01b031681565b61035a61060b366004613e4a565b6126c6565b61035a61061e366004613e4a565b61273c565b61035a6106313660046141c8565b6127b2565b600c5461064d90600160a01b900463ffffffff1681565b60405163ffffffff90911681526020016103aa565b61035a610670366004613e4a565b612d6c565b6103cf610683366004613e4a565b60076020526000908152604090205460ff1681565b61035a6106a6366004613e4a565b612db8565b6103cf6106b9366004613e4a565b60066020526000908152604090205460ff1681565b61035a6106dc366004614213565b612e2b565b61035a6106ef366004613e4a565b612f70565b61035a610702366004613e4a565b61304c565b61035a610715366004613e4a565b613098565b600b54610396906001600160a01b031681565b61035a61073b366004613f15565b61310b565b61074960085481565b6040519081526020016103aa565b600c5461076c90600160c01b900461ffff1681565b60405161ffff90911681526020016103aa565b61035a613201565b61035a610795366004613e4a565b613275565b61035a6107a8366004614258565b6132e9565b600154610396906001600160a01b031681565b61035a6107ce3660046140d8565b613327565b600c54610396906001600160a01b031681565b61035a6107f4366004613e4a565b6133b0565b61035a6133fc565b61035a61080f366004613e4a565b613470565b6103966108223660046142bc565b6134e6565b61035a613572565b6000546001600160a01b03163314610859576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260046020526040808220805460ff19169055517fa7a775c2c8141f7985c111748ec31c11e5e44b83528e105c8d1d4e8e6b81cf809190a250565b600c54600160d01b900460ff16156108cd576040516318c0a57b60e31b815260040160405180910390fd5b6000805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc5460ff1615801561091857503360009081526005602052604090205460ff16155b15610935576040516282b42960e81b815260040160405180910390fd5b6002546001600160a01b03161580159061095a57506002546001600160a01b03163314155b15610977576040516282b42960e81b815260040160405180910390fd5b6000836001600160401b0381111561099157610991613fe8565b6040519080825280602002602001820160405280156109ba578160200160208202803683370190505b5090506000846001600160401b038111156109d7576109d7613fe8565b604051908082528060200260200182016040528015610a00578160200160208202803683370190505b50905060005b85811015610ab157868682818110610a2057610a2061434f565b610a369260206040909202019081019150613e4a565b838281518110610a4857610a4861434f565b60200260200101906001600160a01b031690816001600160a01b031681525050868682818110610a7a57610a7a61434f565b90506040020160200135828281518110610a9657610a9661434f565b6020908102919091010152610aaa8161437b565b9050610a06565b50610abb826135d9565b8315610aca57610aca82613697565b6040805161010081018252600c54600160a01b900463ffffffff168152306020820152908101839052606081018290526000906080810182604051908082528060200260200182016040528015610b2b578160200160208202803683370190505b5081526020016000604051908082528060200260200182016040528015610b5c578160200160208202803683370190505b5081528615156020820152604001859052600c8054919250600160a01b90910463ffffffff16906014610b8e83614394565b91906101000a81548163ffffffff021916908363ffffffff160217905550506000600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2691906143b7565b9050610c318461375c565b600c54604051630552ed0f60e21b815260009182916001600160a01b039091169063154bb43c90610c6890879087906004016144fe565b600060405180830381865afa158015610c85573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cad91908101906145dc565b505091509150808460e001511115610cd857604051635b688e4760e01b815260040160405180910390fd5b60005b846040015151811015610d5257610d42333087606001518481518110610d0357610d0361434f565b602002602001015188604001518581518110610d2157610d2161434f565b60200260200101516001600160a01b0316613921909392919063ffffffff16565b610d4b8161437b565b9050610cdb565b50600a54604051632d58fd7560e01b81526001600160a01b0390911690632d58fd7590610d859086908890600401614633565b6020604051808303816000875af1158015610da4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc891906143b7565b5087156110a65760005b82518110156110a05760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316630e99550e87604001518481518110610e2257610e2261434f565b60200260200101516040518263ffffffff1660e01b8152600401610e5591906001600160a01b0391909116815260200190565b602060405180830381865afa158015610e72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e96919061465c565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610ee0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0491906143b7565b90506000858481518110610f1a57610f1a61434f565b602002602001015160c00151821015610f335781610f52565b858481518110610f4557610f4561434f565b602002602001015160c001515b60405163a9059cbb60e01b8152336004820152602481018290529091506001600160a01b0384169063a9059cbb906044016020604051808303816000875af1158015610fa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc69190614684565b506000610fd382846146a1565b9050801561108b577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166329f9b686828b6040015188815181106110215761102161434f565b60200260200101516040518363ffffffff1660e01b81526004016110589291909182526001600160a01b0316602082015260400190565b600060405180830381600087803b15801561107257600080fd5b505af1158015611086573d6000803e3d6000fd5b505050505b50505050806110999061437b565b9050610dd2565b5061111d565b600a5460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303816000875af11580156110f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111b9190614684565b505b61112561398c565b83516040517f566cb6be00efdb1d5df0cf7dc225dfa95b7293197e28c815e9a9ef8a3624a9b0916111579187906146ba565b60405180910390a150505050505050505050565b6000546001600160a01b03163314611195576040516282b42960e81b815260040160405180910390fd5b600c805460ff60d81b191690556040514281527faaa520fdd7d2c83061d632fa017b0432407e798818af63ea908589fceda39ab7906020015b60405180910390a1565b6000546001600160a01b03163314611202576040516282b42960e81b815260040160405180910390fd5b60005b8181101561126757600a54611257906001600160a01b03166000198585858181106112325761123261434f565b90506020020160208101906112479190613e4a565b6001600160a01b031691906139f0565b6112608161437b565b9050611205565b505050565b6000546001600160a01b03163314611296576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260066020526040808220805460ff19169055517f1bdacea439f3d52c1495fc881858088a33f2ad0cc4a6a1a08780ca96eb6b702d9190a250565b6000546001600160a01b03163314611309576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260046020526040808220805460ff19166001179055517f1584773458d98c71b34a270ee1100b3a42889bf91e3b7a858563b684c24d838e9190a250565b600080611364838501856146d9565b915091508161137a57611375613201565b61140b565b600081600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f491906143b7565b6113fe9190614705565b905061140981613327565b505b50505050565b600c54600160d01b900460ff161561143c576040516318c0a57b60e31b815260040160405180910390fd5b6000805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc5460ff1615801561148757503360009081526005602052604090205460ff16155b156114a4576040516282b42960e81b815260040160405180910390fd5b6002546001600160a01b0316158015906114c957506002546001600160a01b03163314155b156114e6576040516282b42960e81b815260040160405180910390fd5b336001600160a01b0383161480159061150a57506000546001600160a01b03163314155b15611527576040516282b42960e81b815260040160405180910390fd5b6040805160018082528183019092526000916020808301908036833750506040805160018082528183019092529293506000929150602080830190803683370190505090508460000151826000815181106115845761158461434f565b60200260200101906001600160a01b031690816001600160a01b0316815250508460200151816000815181106115bc576115bc61434f565b6020026020010181815250506000604051806101000160405280600c60149054906101000a900463ffffffff1663ffffffff168152602001866001600160a01b0316815260200160006001600160401b0381111561161c5761161c613fe8565b604051908082528060200260200182016040528015611645578160200160208202803683370190505b5081526020016000604051908082528060200260200182016040528015611676578160200160208202803683370190505b508152602081018590526040810184905260016060820152608001859052600c8054919250600160a01b90910463ffffffff169060146116b583614394565b91906101000a81548163ffffffff021916908363ffffffff160217905550506000600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611729573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174d91906143b7565b600a54604051633ea1a23f60e11b81529192506001600160a01b031690637d43447e906117809084908690600401614633565b6020604051808303816000875af115801561179f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c391906143b7565b5081516040517fbd24668b5d3b2d8e900a72a66a182591f8c9dd2c8b0493785b5f6e385eb964a9916117f69185906146ba565b60405180910390a150505050505050565b6000546001600160a01b03163314611831576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260036020526040808220805460ff19166001179055517f93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f599190a250565b6000546001600160a01b031633146118a7576040516282b42960e81b815260040160405180910390fd5b600855565b600060608180806118bf8688018861472d565b9250925092506000600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561191a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193e91906143b7565b90506000600a60009054906101000a90046001600160a01b03166001600160a01b03166383307f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015611995573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b991906143b7565b600c549091506119ee90839083906064906119df90600160c01b900461ffff168a614766565b6119e9919061477d565b613b05565b15611a2b5760006040518060400160405280600f81526020016e41554d20697320696e2072616e676560881b815250965096505050505050611bd1565b600c54611a4e90839083906064906119df90600160c01b900461ffff1689614766565b158015611a655750600c54600160d01b900460ff16155b15611b16578215611aa357505060408051600060208201819052818301528151808203830181526060909101909152600195509350611bd192505050565b6040805160006020820181905281830152815180820383018152606082019092526001913091634585e33b91611adb9160840161479f565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050965096505050505050611bd1565b6000611b2283836147b2565b90508315611b5e576040805160016020820181905291810183905260600160405160208183030381529060405297509750505050505050611bd1565b604080516001602082018190529181018390523090634585e33b9060600160408051601f1981840301815290829052611b999160240161479f565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050975097505050505050505b9250929050565b6000546001600160a01b03163314611c02576040516282b42960e81b815260040160405180910390fd5b60005b8181101561126757600060056000858585818110611c2557611c2561434f565b9050602002016020810190611c3a9190613e4a565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055828282818110611c7457611c7461434f565b9050602002016020810190611c899190613e4a565b6001600160a01b03167fe9dce8c992623ce791725b21e857e33248d1f190a25b5168313420eebdaae99d60405160405180910390a2611cc78161437b565b9050611c05565b6001546001600160a01b03163314611cf8576040516282b42960e81b815260040160405180910390fd5b60008054600180546001600160a01b038082166001600160a01b031980861682178755909216909255604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6000546001600160a01b03163314611d7c576040516282b42960e81b815260040160405180910390fd5b600a8161ffff161080611d9457506103e88161ffff16115b15611db257604051636d4d4a6760e11b815260040160405180910390fd5b600c805461ffff909216600160c01b0261ffff60c01b19909216919091179055565b600c54600160d81b900460ff1615611dff576040516318c0a57b60e31b815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff16158015611e4a57503360009081526006602052604090205460ff16155b15611e67576040516282b42960e81b815260040160405180910390fd5b6002546001600160a01b031615801590611e8c57506002546001600160a01b03163314155b15611ea9576040516282b42960e81b815260040160405180910390fd5b604080516001808252818301909252600091602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337505060408051600180825281830190925292935060009291506020808301908036833750506040805160018082528183019092529293506000929150602080830190803683370190505090508784600081518110611f4857611f4861434f565b60200260200101906001600160a01b031690816001600160a01b0316815250508683600081518110611f7c57611f7c61434f565b6020026020010181815250508582600081518110611f9c57611f9c61434f565b6001600160a01b039092166020928302919091018201526040805161010081018252600c805463ffffffff600160a01b909104168083523094830194909452918101879052606081018690526080810185905260a08101849052600060c082015260e081018890529190601461201183614394565b91906101000a81548163ffffffff021916908363ffffffff160217905550506000600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612085573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a991906143b7565b60408051600280825260608201835292935060009290916020830190803683370190505090508a816000815181106120e3576120e361434f565b60200260200101906001600160a01b031690816001600160a01b03168152505088816001815181106121175761211761434f565b60200260200101906001600160a01b031690816001600160a01b0316815250506121408161375c565b600c54604084015180516000926001600160a01b03169163f58f951091849061216b5761216b61434f565b6020026020010151866060015160008151811061218a5761218a61434f565b602002602001015187608001516000815181106121a9576121a961434f565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201526024810192909252919091166044820152606481018690526084016040805180830381865afa15801561220f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223391906147d9565b509050612271333086606001516000815181106122525761225261434f565b60200260200101518760400151600081518110610d2157610d2161434f565b600a54604051633d655c3760e11b81526001600160a01b0390911690637acab86e906122a39086908890600401614633565b6020604051808303816000875af11580156122c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e691906143b7565b506000866000815181106122fc576122fc61434f565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561234c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237091906143b7565b905080821161237f5781612381565b805b91508460e001518210156123a857604051635b688e4760e01b815260040160405180910390fd5b6123e4338387608001516000815181106123c4576123c461434f565b60200260200101516001600160a01b0316613b4d9092919063ffffffff16565b84516040517fabbffc9fb8ca979e43d12dbd0d18675156cfa9a4e18e808eeb893fa05e46f5a1916124169188906146ba565b60405180910390a161242882826146a1565b8860008151811061243b5761243b61434f565b60200260200101818152505060008860008151811061245c5761245c61434f565b6020026020010151111561263b576040805161010081018252600c54600160a01b900463ffffffff168152306020820152908101889052606081018990526080810160006040519080825280602002602001820160405280156124c9578160200160208202803683370190505b50815260200160006040519080825280602002602001820160405280156124fa578160200160208202803683370190505b508152600060208201819052604090910152600c8054919650600160a01b90910463ffffffff1690601461252d83614394565b91906101000a81548163ffffffff021916908363ffffffff16021790555050600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561259f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c391906143b7565b600a54604051632d58fd7560e01b81529195506001600160a01b031690632d58fd75906125f69087908990600401614633565b6020604051808303816000875af1158015612615573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061263991906143b7565b505b61264361398c565b50505050505050505050505050565b6000546001600160a01b0316331461267c576040516282b42960e81b815260040160405180910390fd5b6001546040516001600160a01b03909116907f6ecd4842251bedd053b09547c0fabaab9ec98506ebf24469e8dd5560412ed37f90600090a2600180546001600160a01b0319169055565b6000546001600160a01b031633146126f0576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260076020526040808220805460ff19166001179055517ff7de8a78655219727a7c0d0db42a97c024f91cb131c5713063c555ce7d7c56529190a250565b6000546001600160a01b03163314612766576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260066020526040808220805460ff19166001179055517f459edbd4f641bfd6cb8eba5ac1b9e7a4629853efd00cc505d055fd3b051867e09190a250565b600c54600160d01b900460ff16156127dd576040516318c0a57b60e31b815260040160405180910390fd5b6000805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc5460ff1615801561282857503360009081526005602052604090205460ff16155b15612845576040516282b42960e81b815260040160405180910390fd5b6002546001600160a01b03161580159061286a57506002546001600160a01b03163314155b15612887576040516282b42960e81b815260040160405180910390fd5b6000826001600160401b038111156128a1576128a1613fe8565b6040519080825280602002602001820160405280156128ca578160200160208202803683370190505b5090506000836001600160401b038111156128e7576128e7613fe8565b604051908082528060200260200182016040528015612910578160200160208202803683370190505b50905060005b848110156129c3578585828181106129305761293061434f565b6129469260206040909202019081019150613e4a565b8382815181106129585761295861434f565b60200260200101906001600160a01b031690816001600160a01b03168152505085858281811061298a5761298a61434f565b905060400201602001358282815181106129a6576129a661434f565b6020908102919091010152806129bb8161437b565b915050612916565b506129cd826135d9565b6040805161010081018252600c54600160a01b900463ffffffff168152306020820152600091810182604051908082528060200260200182016040528015612a1f578160200160208202803683370190505b5081526020016000604051908082528060200260200182016040528015612a50578160200160208202803683370190505b508152602081018590526040810184905260006060820152608001859052600c8054919250600160a01b90910463ffffffff16906014612a8f83614394565b91906101000a81548163ffffffff021916908363ffffffff160217905550506000600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2791906143b7565b9050612b328461375c565b600c54604051634b1163ab60e11b81526000916001600160a01b031690639622c75690612b6590869086906004016144fe565b600060405180830381865afa158015612b82573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612baa91908101906147fd565b5050509150508260e00151811115612bd557604051635b688e4760e01b815260040160405180910390fd5b600a546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015612c2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c509190614684565b50600a54604051633ea1a23f60e11b81526001600160a01b0390911690637d43447e90612c839085908790600401614633565b6020604051808303816000875af1158015612ca2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc691906143b7565b5060005b836080015151811015612d1f57612d0f338560a001518381518110612cf157612cf161434f565b6020026020010151866080015184815181106123c4576123c461434f565b612d188161437b565b9050612cca565b50612d2861398c565b82516040517fbd24668b5d3b2d8e900a72a66a182591f8c9dd2c8b0493785b5f6e385eb964a991612d5a9186906146ba565b60405180910390a15050505050505050565b6000546001600160a01b03163314612d96576040516282b42960e81b815260040160405180910390fd5b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314612de2576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260036020526040808220805460ff19169055517f59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d0489190a250565b3360009081526003602052604090205460ff16612e5a576040516282b42960e81b815260040160405180910390fd5b600854816001600160801b03161015612e9657604051632797027760e01b81526001600160801b03821660048201526024015b60405180910390fd5b6000612ea2824261485e565b6001600160a01b0384166000908152600960205260409020549091506001600160801b039081169082168110612efe57604051630a4dc5d360e31b81526001600160801b03808316600483015283166024820152604401612e8d565b6001600160a01b03841660008181526009602090815260409182902080546001600160801b0319166001600160801b0387169081179091558251938452908301527f6a8b3a105d0f4bca0c6d25f6f59282c2cac3e2acdd3f3466dabe9725f3299703910160405180910390a150505050565b3360009081526003602052604090205460ff16612f9f576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381166000908152600960205260409020546001600160801b0342811691161015612fef57604051637407be0b60e11b81526001600160a01b0382166004820152602401612e8d565b6001600160a01b03811660008181526009602090815260409182902080546001600160801b031916905590519182527f975fea2c466fdf1d3e8dd9969713fbfde0822e5b3921c18c0003e033f216bf5a910160405180910390a150565b6000546001600160a01b03163314613076576040516282b42960e81b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146130c2576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260076020526040808220805460ff19169055517f4d6789b83afc897fab8472d33d3f7cc1fba254215a1cd007ce51f3c5bf6f57729190a250565b6000546001600160a01b03163314613135576040516282b42960e81b815260040160405180910390fd5b60005b81811015611267576001600560008585858181106131585761315861434f565b905060200201602081019061316d9190613e4a565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558282828181106131a7576131a761434f565b90506020020160208101906131bc9190613e4a565b6001600160a01b03167f19ef9a4877199f89440a26acb26895ec02ed86f2df1aeaa90dc18041b892f71f60405160405180910390a26131fa8161437b565b9050613138565b3360009081526003602052604090205460ff16613230576040516282b42960e81b815260040160405180910390fd5b600c805460ff60d01b1916600160d01b1790556040517f68b095021b1f40fe513109f513c66692f0b3219aee674a69f4efc57badb8201d906111ce9042815260200190565b6000546001600160a01b0316331461329f576040516282b42960e81b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517fc720a84179457777bd6ab883473f5ae8b0d37c9d100fd66f070ddcbd35af020f90600090a250565b6000546001600160a01b03163314613313576040516282b42960e81b815260040160405180910390fd5b6112676001600160a01b0384168383613b4d565b3360009081526004602052604090205460ff16613356576040516282b42960e81b815260040160405180910390fd5b600a546040516339e1f2a960e21b8152600481018390526001600160a01b039091169063e787caa490602401600060405180830381600087803b15801561339c57600080fd5b505af1158015611409573d6000803e3d6000fd5b6000546001600160a01b031633146133da576040516282b42960e81b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b3360009081526003602052604090205460ff1661342b576040516282b42960e81b815260040160405180910390fd5b600c805460ff60d81b1916600160d81b1790556040517f68b095021b1f40fe513109f513c66692f0b3219aee674a69f4efc57badb8201d906111ce9042815260200190565b6000546001600160a01b0316331461349a576040516282b42960e81b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03831690811790915560405133907f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270090600090a350565b6000805b82518110156135695761353a8382815181106135085761350861434f565b60200260200101516001600160a01b03166000908152600960205260409020546001600160801b034281169116101590565b15613561578281815181106135515761355161434f565b6020026020010151915050919050565b6001016134ea565b50600092915050565b6000546001600160a01b0316331461359c576040516282b42960e81b815260040160405180910390fd5b600c805460ff60d01b191690556040514281527faaa520fdd7d2c83061d632fa017b0432407e798818af63ea908589fceda39ab7906020016111ce565b60005b600182516135ea91906146a1565b8110156136935760006135fe82600161487e565b90505b82518110156136805782818151811061361c5761361c61434f565b60200260200101516001600160a01b031683838151811061363f5761363f61434f565b60200260200101516001600160a01b03160361366e57604051630df7483960e41b815260040160405180910390fd5b806136788161437b565b915050613601565b508061368b8161437b565b9150506135dc565b5050565b60405163eb2fea2d60e01b81526000906001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063eb2fea2d906136e6908590600401614891565b602060405180830381865afa158015613703573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613727919061465c565b90506001600160a01b038116156136935760405163b3ef117360e01b81526001600160a01b0382166004820152602401612e8d565b600081516001600160401b0381111561377757613777613fe8565b6040519080825280602002602001820160405280156137de57816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282526000199092019101816137955790505b50905060005b82518110156138b857600a5483516001600160a01b0390911690638b0dcb4e908590849081106138165761381661434f565b60200260200101516040518263ffffffff1660e01b815260040161384991906001600160a01b0391909116815260200190565b60e060405180830381865afa158015613866573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061388a91906148c7565b82828151811061389c5761389c61434f565b6020026020010181905250806138b19061437b565b90506137e4565b50600b54604051637c9bd2a160e01b81526001600160a01b0390911690637c9bd2a1906138eb9085908590600401614969565b600060405180830381600087803b15801561390557600080fd5b505af1158015613919573d6000803e3d6000fd5b505050505050565b6040516001600160a01b038085166024830152831660448201526064810182905261140b9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613b7d565b600b60009054906101000a90046001600160a01b03166001600160a01b03166305778fdf6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156139dc57600080fd5b505af115801561140b573d6000803e3d6000fd5b801580613a6a5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015613a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a6891906143b7565b155b613ad55760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401612e8d565b6040516001600160a01b03831660248201526044810182905261126790849063095ea7b360e01b90606401613955565b600080613b128584613c52565b90506000613b208685613c83565b905081851080613b2f57508085115b15613b3f57600092505050613b46565b6001925050505b9392505050565b6040516001600160a01b03831660248201526044810182905261126790849063a9059cbb60e01b90606401613955565b6000613bd2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613ca29092919063ffffffff16565b9050805160001480613bf3575080806020019051810190613bf39190614684565b6112675760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401612e8d565b61271081810390821161138819829004841182021715613c7157600080fd5b61271092026113880191909104919050565b61271081016127101982116113881982900484111715613c7157600080fd5b6060613cb18484600085613cb9565b949350505050565b606082471015613d1a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401612e8d565b600080866001600160a01b03168587604051613d369190614a33565b60006040518083038185875af1925050503d8060008114613d73576040519150601f19603f3d011682016040523d82523d6000602084013e613d78565b606091505b5091509150613d8987838387613d94565b979650505050505050565b60608315613e03578251600003613dfc576001600160a01b0385163b613dfc5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612e8d565b5081613cb1565b613cb18383815115613e185781518083602001fd5b8060405162461bcd60e51b8152600401612e8d919061479f565b6001600160a01b0381168114613e4757600080fd5b50565b600060208284031215613e5c57600080fd5b8135613b4681613e32565b60008083601f840112613e7957600080fd5b5081356001600160401b03811115613e9057600080fd5b6020830191508360208260061b8501011115611bd157600080fd5b8015158114613e4757600080fd5b60008060008060608587031215613ecf57600080fd5b84356001600160401b03811115613ee557600080fd5b613ef187828801613e67565b9095509350506020850135613f0581613eab565b9396929550929360400135925050565b60008060208385031215613f2857600080fd5b82356001600160401b0380821115613f3f57600080fd5b818501915085601f830112613f5357600080fd5b813581811115613f6257600080fd5b8660208260051b8501011115613f7757600080fd5b60209290920196919550909350505050565b60008060208385031215613f9c57600080fd5b82356001600160401b0380821115613fb357600080fd5b818501915085601f830112613fc757600080fd5b813581811115613fd657600080fd5b866020828501011115613f7757600080fd5b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b038111828210171561402057614020613fe8565b60405290565b604051601f8201601f191681016001600160401b038111828210171561404e5761404e613fe8565b604052919050565b6000806000838503608081121561406c57600080fd5b604081121561407a57600080fd5b50604051604081018181106001600160401b038211171561409d5761409d613fe8565b60405284356140ab81613e32565b815260208581013590820152925060408401356140c781613e32565b929592945050506060919091013590565b6000602082840312156140ea57600080fd5b5035919050565b60005b8381101561410c5781810151838201526020016140f4565b50506000910152565b6000815180845261412d8160208601602086016140f1565b601f01601f19169290920160200192915050565b8215158152604060208201526000613cb16040830184614115565b60006020828403121561416e57600080fd5b813561ffff81168114613b4657600080fd5b6000806000806080858703121561419657600080fd5b84356141a181613e32565b93506020850135925060408501356141b881613e32565b9396929550929360600135925050565b6000806000604084860312156141dd57600080fd5b83356001600160401b038111156141f357600080fd5b6141ff86828701613e67565b909790965060209590950135949350505050565b6000806040838503121561422657600080fd5b823561423181613e32565b915060208301356001600160801b038116811461424d57600080fd5b809150509250929050565b60008060006060848603121561426d57600080fd5b833561427881613e32565b9250602084013561428881613e32565b929592945050506040919091013590565b60006001600160401b038211156142b2576142b2613fe8565b5060051b60200190565b600060208083850312156142cf57600080fd5b82356001600160401b038111156142e557600080fd5b8301601f810185136142f657600080fd5b803561430961430482614299565b614026565b81815260059190911b8201830190838101908783111561432857600080fd5b928401925b82841015613d8957833561434081613e32565b8252928401929084019061432d565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161438d5761438d614365565b5060010190565b600063ffffffff8083168181036143ad576143ad614365565b6001019392505050565b6000602082840312156143c957600080fd5b5051919050565b600081518084526020808501945080840160005b838110156144095781516001600160a01b0316875295820195908201906001016143e4565b509495945050505050565b600081518084526020808501945080840160005b8381101561440957815187529582019590820190600101614428565b805163ffffffff1682526000610100602083015161446d60208601826001600160a01b03169052565b506040830151816040860152614485828601826143d0565b9150506060830151848203606086015261449f8282614414565b915050608083015184820360808601526144b982826143d0565b91505060a083015184820360a08601526144d38282614414565b91505060c08301516144e960c086018215159052565b5060e083015160e08501528091505092915050565b6040815260006145116040830185614444565b90508260208301529392505050565b600082601f83011261453157600080fd5b8151602061454161430483614299565b82815260e0928302850182019282820191908785111561456057600080fd5b8387015b858110156145cf5781818a03121561457c5760008081fd5b614584613ffe565b81518152858201518682015260408083015190820152606080830151908201526080808301519082015260a0808301519082015260c080830151908201528452928401928101614564565b5090979650505050505050565b600080600080608085870312156145f257600080fd5b84516001600160401b0381111561460857600080fd5b61461487828801614520565b6020870151604088015160609098015191999098509095509350505050565b828152604060208201526000613cb16040830184614444565b805161465781613e32565b919050565b60006020828403121561466e57600080fd5b8151613b4681613e32565b805161465781613eab565b60006020828403121561469657600080fd5b8151613b4681613eab565b818103818111156146b4576146b4614365565b92915050565b63ffffffff83168152604060208201526000613cb16040830184614444565b600080604083850312156146ec57600080fd5b82356146f781613eab565b946020939093013593505050565b808201828112600083128015821682158216171561472557614725614365565b505092915050565b60008060006060848603121561474257600080fd5b8335925060208401359150604084013561475b81613eab565b809150509250925092565b80820281158282048414176146b4576146b4614365565b60008261479a57634e487b7160e01b600052601260045260246000fd5b500490565b602081526000613b466020830184614115565b81810360008312801583831316838312821617156147d2576147d2614365565b5092915050565b600080604083850312156147ec57600080fd5b505080516020909101519092909150565b600080600080600060a0868803121561481557600080fd5b85516001600160401b0381111561482b57600080fd5b61483788828901614520565b6020880151604089015160608a01516080909a0151929b919a509897509095509350505050565b6001600160801b038181168382160190808211156147d2576147d2614365565b808201808211156146b4576146b4614365565b602081526000613b4660208301846143d0565b8051600881900b811461465757600080fd5b805160ff8116811461465757600080fd5b600060e082840312156148d957600080fd5b6148e1613ffe565b825168ffffffffffffffffff811681146148fa57600080fd5b81526149086020840161464c565b6020820152614919604084016148a4565b604082015261492a606084016148b6565b606082015261493b608084016148b6565b608082015261494c60a0840161464c565b60a082015261495d60c08401614679565b60c08201529392505050565b6000604080835261497c818401866143d0565b83810360208581019190915285518083528682019282019060005b81811015614a25578451805168ffffffffffffffffff168452848101516001600160a01b0316858501528681015160080b8785015260608082015160ff908116918601919091526080808301519091169085015260a080820151614a05828701826001600160a01b03169052565b505060c0908101511515908401529383019360e090920191600101614997565b509098975050505050505050565b60008251614a458184602087016140f1565b919091019291505056fea2646970667358221220c87174f0c894151860a1e227ff037e959d1c5d845988d8e5d63c758ec670d13264736f6c63430008130033000000000000000000000000e8e40fd4ddab26b44b1fb2d6d73833cb0a33b736000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e10000000000000000000000000000000000000000000000000000000000000064
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103425760003560e01c806398fbfbea116101b8578063cdfca7f211610104578063e787caa4116100a2578063ed6b5ad51161007c578063ed6b5ad5146107f9578063f2fde38b14610801578063f80c6d9c14610814578063f93b6be51461082757600080fd5b8063e787caa4146107c0578063e838d0a9146107d3578063ec2a0992146107e657600080fd5b8063dbf62489116100de578063dbf624891461077f578063ddb015c814610787578063e00efe4a1461079a578063e30c3978146107ad57600080fd5b8063cdfca7f21461072d578063d307983d14610740578063d94ad8371461075757600080fd5b8063b623501611610171578063bae2be561161014b578063bae2be56146106e1578063c073fd74146106f4578063c87eed4614610707578063cc88688b1461071a57600080fd5b8063b623501614610698578063b64230ba146106ab578063b813a8df146106ce57600080fd5b806398fbfbea146105fd5780639938500614610610578063a8ad7a0314610623578063affed0e014610636578063b0bdafbe14610662578063b588c10b1461067557600080fd5b8063489c120211610292578063769315a4116102305780638a0ccd561161020a5780638a0ccd56146105bc5780638da5cb5b146105cf57806392fede00146105e257806393263b8a146105ea57600080fd5b8063769315a41461058e57806379ba5097146105a15780637cb1d3df146105a957600080fd5b80636913a63c1161026c5780636913a63c146105245780636ba42aaa146105375780636d9b83ec1461055a5780636e04ff0d1461056d57600080fd5b8063489c1202146104da5780634fd8cb94146104fd5780635c975abb1461051057600080fd5b80633b42d038116102ff5780634209fff1116102d95780634209fff1146104595780634585e33b1461047c578063485d6ef81461048f5780634866788b146104c757600080fd5b80633b42d038146104205780633f2d4131146104335780634032b72b1461044657600080fd5b806314ae9f2e1461034757806316805c811461035c5780631a366bb71461036f57806320157d0a146103b3578063245a4e72146103bb57806339663ef2146103df575b600080fd5b61035a610355366004613e4a565b61082f565b005b61035a61036a366004613eb9565b6108a2565b6103967f000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e181565b6040516001600160a01b0390911681526020015b60405180910390f35b61035a61116b565b600c546103cf90600160d81b900460ff1681565b60405190151581526020016103aa565b6104086103ed366004613e4a565b6009602052600090815260409020546001600160801b031681565b6040516001600160801b0390911681526020016103aa565b61035a61042e366004613f15565b6111d8565b61035a610441366004613e4a565b61126c565b61035a610454366004613e4a565b6112df565b6103cf610467366004613e4a565b60056020526000908152604090205460ff1681565b61035a61048a366004613f89565b611355565b6103cf61049d366004613e4a565b6001600160a01b03166000908152600960205260409020546001600160801b034281169116101590565b61035a6104d5366004614056565b611411565b6103cf6104e8366004613e4a565b60036020526000908152604090205460ff1681565b600a54610396906001600160a01b031681565b600c546103cf90600160d01b900460ff1681565b61035a610532366004613e4a565b611807565b6103cf610545366004613e4a565b60046020526000908152604090205460ff1681565b61035a6105683660046140d8565b61187d565b61058061057b366004613f89565b6118ac565b6040516103aa929190614141565b61035a61059c366004613f15565b611bd8565b61035a611cce565b61035a6105b736600461415c565b611d52565b61035a6105ca366004614180565b611dd4565b600054610396906001600160a01b031681565b61035a612652565b600254610396906001600160a01b031681565b61035a61060b366004613e4a565b6126c6565b61035a61061e366004613e4a565b61273c565b61035a6106313660046141c8565b6127b2565b600c5461064d90600160a01b900463ffffffff1681565b60405163ffffffff90911681526020016103aa565b61035a610670366004613e4a565b612d6c565b6103cf610683366004613e4a565b60076020526000908152604090205460ff1681565b61035a6106a6366004613e4a565b612db8565b6103cf6106b9366004613e4a565b60066020526000908152604090205460ff1681565b61035a6106dc366004614213565b612e2b565b61035a6106ef366004613e4a565b612f70565b61035a610702366004613e4a565b61304c565b61035a610715366004613e4a565b613098565b600b54610396906001600160a01b031681565b61035a61073b366004613f15565b61310b565b61074960085481565b6040519081526020016103aa565b600c5461076c90600160c01b900461ffff1681565b60405161ffff90911681526020016103aa565b61035a613201565b61035a610795366004613e4a565b613275565b61035a6107a8366004614258565b6132e9565b600154610396906001600160a01b031681565b61035a6107ce3660046140d8565b613327565b600c54610396906001600160a01b031681565b61035a6107f4366004613e4a565b6133b0565b61035a6133fc565b61035a61080f366004613e4a565b613470565b6103966108223660046142bc565b6134e6565b61035a613572565b6000546001600160a01b03163314610859576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260046020526040808220805460ff19169055517fa7a775c2c8141f7985c111748ec31c11e5e44b83528e105c8d1d4e8e6b81cf809190a250565b600c54600160d01b900460ff16156108cd576040516318c0a57b60e31b815260040160405180910390fd5b6000805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc5460ff1615801561091857503360009081526005602052604090205460ff16155b15610935576040516282b42960e81b815260040160405180910390fd5b6002546001600160a01b03161580159061095a57506002546001600160a01b03163314155b15610977576040516282b42960e81b815260040160405180910390fd5b6000836001600160401b0381111561099157610991613fe8565b6040519080825280602002602001820160405280156109ba578160200160208202803683370190505b5090506000846001600160401b038111156109d7576109d7613fe8565b604051908082528060200260200182016040528015610a00578160200160208202803683370190505b50905060005b85811015610ab157868682818110610a2057610a2061434f565b610a369260206040909202019081019150613e4a565b838281518110610a4857610a4861434f565b60200260200101906001600160a01b031690816001600160a01b031681525050868682818110610a7a57610a7a61434f565b90506040020160200135828281518110610a9657610a9661434f565b6020908102919091010152610aaa8161437b565b9050610a06565b50610abb826135d9565b8315610aca57610aca82613697565b6040805161010081018252600c54600160a01b900463ffffffff168152306020820152908101839052606081018290526000906080810182604051908082528060200260200182016040528015610b2b578160200160208202803683370190505b5081526020016000604051908082528060200260200182016040528015610b5c578160200160208202803683370190505b5081528615156020820152604001859052600c8054919250600160a01b90910463ffffffff16906014610b8e83614394565b91906101000a81548163ffffffff021916908363ffffffff160217905550506000600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610c02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2691906143b7565b9050610c318461375c565b600c54604051630552ed0f60e21b815260009182916001600160a01b039091169063154bb43c90610c6890879087906004016144fe565b600060405180830381865afa158015610c85573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610cad91908101906145dc565b505091509150808460e001511115610cd857604051635b688e4760e01b815260040160405180910390fd5b60005b846040015151811015610d5257610d42333087606001518481518110610d0357610d0361434f565b602002602001015188604001518581518110610d2157610d2161434f565b60200260200101516001600160a01b0316613921909392919063ffffffff16565b610d4b8161437b565b9050610cdb565b50600a54604051632d58fd7560e01b81526001600160a01b0390911690632d58fd7590610d859086908890600401614633565b6020604051808303816000875af1158015610da4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc891906143b7565b5087156110a65760005b82518110156110a05760007f000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e16001600160a01b0316630e99550e87604001518481518110610e2257610e2261434f565b60200260200101516040518263ffffffff1660e01b8152600401610e5591906001600160a01b0391909116815260200190565b602060405180830381865afa158015610e72573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e96919061465c565b6040516370a0823160e01b81523060048201529091506000906001600160a01b038316906370a0823190602401602060405180830381865afa158015610ee0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610f0491906143b7565b90506000858481518110610f1a57610f1a61434f565b602002602001015160c00151821015610f335781610f52565b858481518110610f4557610f4561434f565b602002602001015160c001515b60405163a9059cbb60e01b8152336004820152602481018290529091506001600160a01b0384169063a9059cbb906044016020604051808303816000875af1158015610fa2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fc69190614684565b506000610fd382846146a1565b9050801561108b577f000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e16001600160a01b03166329f9b686828b6040015188815181106110215761102161434f565b60200260200101516040518363ffffffff1660e01b81526004016110589291909182526001600160a01b0316602082015260400190565b600060405180830381600087803b15801561107257600080fd5b505af1158015611086573d6000803e3d6000fd5b505050505b50505050806110999061437b565b9050610dd2565b5061111d565b600a5460405163a9059cbb60e01b8152336004820152602481018390526001600160a01b039091169063a9059cbb906044016020604051808303816000875af11580156110f7573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061111b9190614684565b505b61112561398c565b83516040517f566cb6be00efdb1d5df0cf7dc225dfa95b7293197e28c815e9a9ef8a3624a9b0916111579187906146ba565b60405180910390a150505050505050505050565b6000546001600160a01b03163314611195576040516282b42960e81b815260040160405180910390fd5b600c805460ff60d81b191690556040514281527faaa520fdd7d2c83061d632fa017b0432407e798818af63ea908589fceda39ab7906020015b60405180910390a1565b6000546001600160a01b03163314611202576040516282b42960e81b815260040160405180910390fd5b60005b8181101561126757600a54611257906001600160a01b03166000198585858181106112325761123261434f565b90506020020160208101906112479190613e4a565b6001600160a01b031691906139f0565b6112608161437b565b9050611205565b505050565b6000546001600160a01b03163314611296576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260066020526040808220805460ff19169055517f1bdacea439f3d52c1495fc881858088a33f2ad0cc4a6a1a08780ca96eb6b702d9190a250565b6000546001600160a01b03163314611309576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260046020526040808220805460ff19166001179055517f1584773458d98c71b34a270ee1100b3a42889bf91e3b7a858563b684c24d838e9190a250565b600080611364838501856146d9565b915091508161137a57611375613201565b61140b565b600081600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113d0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113f491906143b7565b6113fe9190614705565b905061140981613327565b505b50505050565b600c54600160d01b900460ff161561143c576040516318c0a57b60e31b815260040160405180910390fd5b6000805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc5460ff1615801561148757503360009081526005602052604090205460ff16155b156114a4576040516282b42960e81b815260040160405180910390fd5b6002546001600160a01b0316158015906114c957506002546001600160a01b03163314155b156114e6576040516282b42960e81b815260040160405180910390fd5b336001600160a01b0383161480159061150a57506000546001600160a01b03163314155b15611527576040516282b42960e81b815260040160405180910390fd5b6040805160018082528183019092526000916020808301908036833750506040805160018082528183019092529293506000929150602080830190803683370190505090508460000151826000815181106115845761158461434f565b60200260200101906001600160a01b031690816001600160a01b0316815250508460200151816000815181106115bc576115bc61434f565b6020026020010181815250506000604051806101000160405280600c60149054906101000a900463ffffffff1663ffffffff168152602001866001600160a01b0316815260200160006001600160401b0381111561161c5761161c613fe8565b604051908082528060200260200182016040528015611645578160200160208202803683370190505b5081526020016000604051908082528060200260200182016040528015611676578160200160208202803683370190505b508152602081018590526040810184905260016060820152608001859052600c8054919250600160a01b90910463ffffffff169060146116b583614394565b91906101000a81548163ffffffff021916908363ffffffff160217905550506000600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611729573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061174d91906143b7565b600a54604051633ea1a23f60e11b81529192506001600160a01b031690637d43447e906117809084908690600401614633565b6020604051808303816000875af115801561179f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c391906143b7565b5081516040517fbd24668b5d3b2d8e900a72a66a182591f8c9dd2c8b0493785b5f6e385eb964a9916117f69185906146ba565b60405180910390a150505050505050565b6000546001600160a01b03163314611831576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260036020526040808220805460ff19166001179055517f93405f05cd04f0d1bd875f2de00f1f3890484ffd0589248953bdfd29ba7f2f599190a250565b6000546001600160a01b031633146118a7576040516282b42960e81b815260040160405180910390fd5b600855565b600060608180806118bf8688018861472d565b9250925092506000600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561191a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061193e91906143b7565b90506000600a60009054906101000a90046001600160a01b03166001600160a01b03166383307f436040518163ffffffff1660e01b8152600401602060405180830381865afa158015611995573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119b991906143b7565b600c549091506119ee90839083906064906119df90600160c01b900461ffff168a614766565b6119e9919061477d565b613b05565b15611a2b5760006040518060400160405280600f81526020016e41554d20697320696e2072616e676560881b815250965096505050505050611bd1565b600c54611a4e90839083906064906119df90600160c01b900461ffff1689614766565b158015611a655750600c54600160d01b900460ff16155b15611b16578215611aa357505060408051600060208201819052818301528151808203830181526060909101909152600195509350611bd192505050565b6040805160006020820181905281830152815180820383018152606082019092526001913091634585e33b91611adb9160840161479f565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050965096505050505050611bd1565b6000611b2283836147b2565b90508315611b5e576040805160016020820181905291810183905260600160405160208183030381529060405297509750505050505050611bd1565b604080516001602082018190529181018390523090634585e33b9060600160408051601f1981840301815290829052611b999160240161479f565b604051602081830303815290604052915060e01b6020820180516001600160e01b038381831617835250505050975097505050505050505b9250929050565b6000546001600160a01b03163314611c02576040516282b42960e81b815260040160405180910390fd5b60005b8181101561126757600060056000858585818110611c2557611c2561434f565b9050602002016020810190611c3a9190613e4a565b6001600160a01b031681526020810191909152604001600020805460ff1916911515919091179055828282818110611c7457611c7461434f565b9050602002016020810190611c899190613e4a565b6001600160a01b03167fe9dce8c992623ce791725b21e857e33248d1f190a25b5168313420eebdaae99d60405160405180910390a2611cc78161437b565b9050611c05565b6001546001600160a01b03163314611cf8576040516282b42960e81b815260040160405180910390fd5b60008054600180546001600160a01b038082166001600160a01b031980861682178755909216909255604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b6000546001600160a01b03163314611d7c576040516282b42960e81b815260040160405180910390fd5b600a8161ffff161080611d9457506103e88161ffff16115b15611db257604051636d4d4a6760e11b815260040160405180910390fd5b600c805461ffff909216600160c01b0261ffff60c01b19909216919091179055565b600c54600160d81b900460ff1615611dff576040516318c0a57b60e31b815260040160405180910390fd5b6000805260066020527f54cdd369e4e8a8515e52ca72ec816c2101831ad1f18bf44102ed171459c9b4f85460ff16158015611e4a57503360009081526006602052604090205460ff16155b15611e67576040516282b42960e81b815260040160405180910390fd5b6002546001600160a01b031615801590611e8c57506002546001600160a01b03163314155b15611ea9576040516282b42960e81b815260040160405180910390fd5b604080516001808252818301909252600091602080830190803683375050604080516001808252818301909252929350600092915060208083019080368337505060408051600180825281830190925292935060009291506020808301908036833750506040805160018082528183019092529293506000929150602080830190803683370190505090508784600081518110611f4857611f4861434f565b60200260200101906001600160a01b031690816001600160a01b0316815250508683600081518110611f7c57611f7c61434f565b6020026020010181815250508582600081518110611f9c57611f9c61434f565b6001600160a01b039092166020928302919091018201526040805161010081018252600c805463ffffffff600160a01b909104168083523094830194909452918101879052606081018690526080810185905260a08101849052600060c082015260e081018890529190601461201183614394565b91906101000a81548163ffffffff021916908363ffffffff160217905550506000600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612085573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a991906143b7565b60408051600280825260608201835292935060009290916020830190803683370190505090508a816000815181106120e3576120e361434f565b60200260200101906001600160a01b031690816001600160a01b03168152505088816001815181106121175761211761434f565b60200260200101906001600160a01b031690816001600160a01b0316815250506121408161375c565b600c54604084015180516000926001600160a01b03169163f58f951091849061216b5761216b61434f565b6020026020010151866060015160008151811061218a5761218a61434f565b602002602001015187608001516000815181106121a9576121a961434f565b60209081029190910101516040516001600160e01b031960e086901b1681526001600160a01b0393841660048201526024810192909252919091166044820152606481018690526084016040805180830381865afa15801561220f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061223391906147d9565b509050612271333086606001516000815181106122525761225261434f565b60200260200101518760400151600081518110610d2157610d2161434f565b600a54604051633d655c3760e11b81526001600160a01b0390911690637acab86e906122a39086908890600401614633565b6020604051808303816000875af11580156122c2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e691906143b7565b506000866000815181106122fc576122fc61434f565b60209081029190910101516040516370a0823160e01b81523060048201526001600160a01b03909116906370a0823190602401602060405180830381865afa15801561234c573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061237091906143b7565b905080821161237f5781612381565b805b91508460e001518210156123a857604051635b688e4760e01b815260040160405180910390fd5b6123e4338387608001516000815181106123c4576123c461434f565b60200260200101516001600160a01b0316613b4d9092919063ffffffff16565b84516040517fabbffc9fb8ca979e43d12dbd0d18675156cfa9a4e18e808eeb893fa05e46f5a1916124169188906146ba565b60405180910390a161242882826146a1565b8860008151811061243b5761243b61434f565b60200260200101818152505060008860008151811061245c5761245c61434f565b6020026020010151111561263b576040805161010081018252600c54600160a01b900463ffffffff168152306020820152908101889052606081018990526080810160006040519080825280602002602001820160405280156124c9578160200160208202803683370190505b50815260200160006040519080825280602002602001820160405280156124fa578160200160208202803683370190505b508152600060208201819052604090910152600c8054919650600160a01b90910463ffffffff1690601461252d83614394565b91906101000a81548163ffffffff021916908363ffffffff16021790555050600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561259f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125c391906143b7565b600a54604051632d58fd7560e01b81529195506001600160a01b031690632d58fd75906125f69087908990600401614633565b6020604051808303816000875af1158015612615573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061263991906143b7565b505b61264361398c565b50505050505050505050505050565b6000546001600160a01b0316331461267c576040516282b42960e81b815260040160405180910390fd5b6001546040516001600160a01b03909116907f6ecd4842251bedd053b09547c0fabaab9ec98506ebf24469e8dd5560412ed37f90600090a2600180546001600160a01b0319169055565b6000546001600160a01b031633146126f0576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260076020526040808220805460ff19166001179055517ff7de8a78655219727a7c0d0db42a97c024f91cb131c5713063c555ce7d7c56529190a250565b6000546001600160a01b03163314612766576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260066020526040808220805460ff19166001179055517f459edbd4f641bfd6cb8eba5ac1b9e7a4629853efd00cc505d055fd3b051867e09190a250565b600c54600160d01b900460ff16156127dd576040516318c0a57b60e31b815260040160405180910390fd5b6000805260056020527f05b8ccbb9d4d8fb16ea74ce3c29a41f1b461fbdaff4714a0d9a8eb05499746bc5460ff1615801561282857503360009081526005602052604090205460ff16155b15612845576040516282b42960e81b815260040160405180910390fd5b6002546001600160a01b03161580159061286a57506002546001600160a01b03163314155b15612887576040516282b42960e81b815260040160405180910390fd5b6000826001600160401b038111156128a1576128a1613fe8565b6040519080825280602002602001820160405280156128ca578160200160208202803683370190505b5090506000836001600160401b038111156128e7576128e7613fe8565b604051908082528060200260200182016040528015612910578160200160208202803683370190505b50905060005b848110156129c3578585828181106129305761293061434f565b6129469260206040909202019081019150613e4a565b8382815181106129585761295861434f565b60200260200101906001600160a01b031690816001600160a01b03168152505085858281811061298a5761298a61434f565b905060400201602001358282815181106129a6576129a661434f565b6020908102919091010152806129bb8161437b565b915050612916565b506129cd826135d9565b6040805161010081018252600c54600160a01b900463ffffffff168152306020820152600091810182604051908082528060200260200182016040528015612a1f578160200160208202803683370190505b5081526020016000604051908082528060200260200182016040528015612a50578160200160208202803683370190505b508152602081018590526040810184905260006060820152608001859052600c8054919250600160a01b90910463ffffffff16906014612a8f83614394565b91906101000a81548163ffffffff021916908363ffffffff160217905550506000600a60009054906101000a90046001600160a01b03166001600160a01b0316638be859ec6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612b03573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b2791906143b7565b9050612b328461375c565b600c54604051634b1163ab60e11b81526000916001600160a01b031690639622c75690612b6590869086906004016144fe565b600060405180830381865afa158015612b82573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612baa91908101906147fd565b5050509150508260e00151811115612bd557604051635b688e4760e01b815260040160405180910390fd5b600a546040516323b872dd60e01b8152336004820152306024820152604481018390526001600160a01b03909116906323b872dd906064016020604051808303816000875af1158015612c2c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c509190614684565b50600a54604051633ea1a23f60e11b81526001600160a01b0390911690637d43447e90612c839085908790600401614633565b6020604051808303816000875af1158015612ca2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cc691906143b7565b5060005b836080015151811015612d1f57612d0f338560a001518381518110612cf157612cf161434f565b6020026020010151866080015184815181106123c4576123c461434f565b612d188161437b565b9050612cca565b50612d2861398c565b82516040517fbd24668b5d3b2d8e900a72a66a182591f8c9dd2c8b0493785b5f6e385eb964a991612d5a9186906146ba565b60405180910390a15050505050505050565b6000546001600160a01b03163314612d96576040516282b42960e81b815260040160405180910390fd5b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b03163314612de2576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260036020526040808220805460ff19169055517f59926e0a78d12238b668b31c8e3f6ece235a59a00ede111d883e255b68c4d0489190a250565b3360009081526003602052604090205460ff16612e5a576040516282b42960e81b815260040160405180910390fd5b600854816001600160801b03161015612e9657604051632797027760e01b81526001600160801b03821660048201526024015b60405180910390fd5b6000612ea2824261485e565b6001600160a01b0384166000908152600960205260409020549091506001600160801b039081169082168110612efe57604051630a4dc5d360e31b81526001600160801b03808316600483015283166024820152604401612e8d565b6001600160a01b03841660008181526009602090815260409182902080546001600160801b0319166001600160801b0387169081179091558251938452908301527f6a8b3a105d0f4bca0c6d25f6f59282c2cac3e2acdd3f3466dabe9725f3299703910160405180910390a150505050565b3360009081526003602052604090205460ff16612f9f576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381166000908152600960205260409020546001600160801b0342811691161015612fef57604051637407be0b60e11b81526001600160a01b0382166004820152602401612e8d565b6001600160a01b03811660008181526009602090815260409182902080546001600160801b031916905590519182527f975fea2c466fdf1d3e8dd9969713fbfde0822e5b3921c18c0003e033f216bf5a910160405180910390a150565b6000546001600160a01b03163314613076576040516282b42960e81b815260040160405180910390fd5b600a80546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b031633146130c2576040516282b42960e81b815260040160405180910390fd5b6001600160a01b038116600081815260076020526040808220805460ff19169055517f4d6789b83afc897fab8472d33d3f7cc1fba254215a1cd007ce51f3c5bf6f57729190a250565b6000546001600160a01b03163314613135576040516282b42960e81b815260040160405180910390fd5b60005b81811015611267576001600560008585858181106131585761315861434f565b905060200201602081019061316d9190613e4a565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558282828181106131a7576131a761434f565b90506020020160208101906131bc9190613e4a565b6001600160a01b03167f19ef9a4877199f89440a26acb26895ec02ed86f2df1aeaa90dc18041b892f71f60405160405180910390a26131fa8161437b565b9050613138565b3360009081526003602052604090205460ff16613230576040516282b42960e81b815260040160405180910390fd5b600c805460ff60d01b1916600160d01b1790556040517f68b095021b1f40fe513109f513c66692f0b3219aee674a69f4efc57badb8201d906111ce9042815260200190565b6000546001600160a01b0316331461329f576040516282b42960e81b815260040160405180910390fd5b600280546001600160a01b0319166001600160a01b0383169081179091556040517fc720a84179457777bd6ab883473f5ae8b0d37c9d100fd66f070ddcbd35af020f90600090a250565b6000546001600160a01b03163314613313576040516282b42960e81b815260040160405180910390fd5b6112676001600160a01b0384168383613b4d565b3360009081526004602052604090205460ff16613356576040516282b42960e81b815260040160405180910390fd5b600a546040516339e1f2a960e21b8152600481018390526001600160a01b039091169063e787caa490602401600060405180830381600087803b15801561339c57600080fd5b505af1158015611409573d6000803e3d6000fd5b6000546001600160a01b031633146133da576040516282b42960e81b815260040160405180910390fd5b600b80546001600160a01b0319166001600160a01b0392909216919091179055565b3360009081526003602052604090205460ff1661342b576040516282b42960e81b815260040160405180910390fd5b600c805460ff60d81b1916600160d81b1790556040517f68b095021b1f40fe513109f513c66692f0b3219aee674a69f4efc57badb8201d906111ce9042815260200190565b6000546001600160a01b0316331461349a576040516282b42960e81b815260040160405180910390fd5b600180546001600160a01b0319166001600160a01b03831690811790915560405133907f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270090600090a350565b6000805b82518110156135695761353a8382815181106135085761350861434f565b60200260200101516001600160a01b03166000908152600960205260409020546001600160801b034281169116101590565b15613561578281815181106135515761355161434f565b6020026020010151915050919050565b6001016134ea565b50600092915050565b6000546001600160a01b0316331461359c576040516282b42960e81b815260040160405180910390fd5b600c805460ff60d01b191690556040514281527faaa520fdd7d2c83061d632fa017b0432407e798818af63ea908589fceda39ab7906020016111ce565b60005b600182516135ea91906146a1565b8110156136935760006135fe82600161487e565b90505b82518110156136805782818151811061361c5761361c61434f565b60200260200101516001600160a01b031683838151811061363f5761363f61434f565b60200260200101516001600160a01b03160361366e57604051630df7483960e41b815260040160405180910390fd5b806136788161437b565b915050613601565b508061368b8161437b565b9150506135dc565b5050565b60405163eb2fea2d60e01b81526000906001600160a01b037f000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e1169063eb2fea2d906136e6908590600401614891565b602060405180830381865afa158015613703573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613727919061465c565b90506001600160a01b038116156136935760405163b3ef117360e01b81526001600160a01b0382166004820152602401612e8d565b600081516001600160401b0381111561377757613777613fe8565b6040519080825280602002602001820160405280156137de57816020015b6040805160e08101825260008082526020808301829052928201819052606082018190526080820181905260a0820181905260c082015282526000199092019101816137955790505b50905060005b82518110156138b857600a5483516001600160a01b0390911690638b0dcb4e908590849081106138165761381661434f565b60200260200101516040518263ffffffff1660e01b815260040161384991906001600160a01b0391909116815260200190565b60e060405180830381865afa158015613866573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061388a91906148c7565b82828151811061389c5761389c61434f565b6020026020010181905250806138b19061437b565b90506137e4565b50600b54604051637c9bd2a160e01b81526001600160a01b0390911690637c9bd2a1906138eb9085908590600401614969565b600060405180830381600087803b15801561390557600080fd5b505af1158015613919573d6000803e3d6000fd5b505050505050565b6040516001600160a01b038085166024830152831660448201526064810182905261140b9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152613b7d565b600b60009054906101000a90046001600160a01b03166001600160a01b03166305778fdf6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156139dc57600080fd5b505af115801561140b573d6000803e3d6000fd5b801580613a6a5750604051636eb1769f60e11b81523060048201526001600160a01b03838116602483015284169063dd62ed3e90604401602060405180830381865afa158015613a44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613a6891906143b7565b155b613ad55760405162461bcd60e51b815260206004820152603660248201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60448201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b6064820152608401612e8d565b6040516001600160a01b03831660248201526044810182905261126790849063095ea7b360e01b90606401613955565b600080613b128584613c52565b90506000613b208685613c83565b905081851080613b2f57508085115b15613b3f57600092505050613b46565b6001925050505b9392505050565b6040516001600160a01b03831660248201526044810182905261126790849063a9059cbb60e01b90606401613955565b6000613bd2826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316613ca29092919063ffffffff16565b9050805160001480613bf3575080806020019051810190613bf39190614684565b6112675760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401612e8d565b61271081810390821161138819829004841182021715613c7157600080fd5b61271092026113880191909104919050565b61271081016127101982116113881982900484111715613c7157600080fd5b6060613cb18484600085613cb9565b949350505050565b606082471015613d1a5760405162461bcd60e51b815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6044820152651c8818d85b1b60d21b6064820152608401612e8d565b600080866001600160a01b03168587604051613d369190614a33565b60006040518083038185875af1925050503d8060008114613d73576040519150601f19603f3d011682016040523d82523d6000602084013e613d78565b606091505b5091509150613d8987838387613d94565b979650505050505050565b60608315613e03578251600003613dfc576001600160a01b0385163b613dfc5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612e8d565b5081613cb1565b613cb18383815115613e185781518083602001fd5b8060405162461bcd60e51b8152600401612e8d919061479f565b6001600160a01b0381168114613e4757600080fd5b50565b600060208284031215613e5c57600080fd5b8135613b4681613e32565b60008083601f840112613e7957600080fd5b5081356001600160401b03811115613e9057600080fd5b6020830191508360208260061b8501011115611bd157600080fd5b8015158114613e4757600080fd5b60008060008060608587031215613ecf57600080fd5b84356001600160401b03811115613ee557600080fd5b613ef187828801613e67565b9095509350506020850135613f0581613eab565b9396929550929360400135925050565b60008060208385031215613f2857600080fd5b82356001600160401b0380821115613f3f57600080fd5b818501915085601f830112613f5357600080fd5b813581811115613f6257600080fd5b8660208260051b8501011115613f7757600080fd5b60209290920196919550909350505050565b60008060208385031215613f9c57600080fd5b82356001600160401b0380821115613fb357600080fd5b818501915085601f830112613fc757600080fd5b813581811115613fd657600080fd5b866020828501011115613f7757600080fd5b634e487b7160e01b600052604160045260246000fd5b60405160e081016001600160401b038111828210171561402057614020613fe8565b60405290565b604051601f8201601f191681016001600160401b038111828210171561404e5761404e613fe8565b604052919050565b6000806000838503608081121561406c57600080fd5b604081121561407a57600080fd5b50604051604081018181106001600160401b038211171561409d5761409d613fe8565b60405284356140ab81613e32565b815260208581013590820152925060408401356140c781613e32565b929592945050506060919091013590565b6000602082840312156140ea57600080fd5b5035919050565b60005b8381101561410c5781810151838201526020016140f4565b50506000910152565b6000815180845261412d8160208601602086016140f1565b601f01601f19169290920160200192915050565b8215158152604060208201526000613cb16040830184614115565b60006020828403121561416e57600080fd5b813561ffff81168114613b4657600080fd5b6000806000806080858703121561419657600080fd5b84356141a181613e32565b93506020850135925060408501356141b881613e32565b9396929550929360600135925050565b6000806000604084860312156141dd57600080fd5b83356001600160401b038111156141f357600080fd5b6141ff86828701613e67565b909790965060209590950135949350505050565b6000806040838503121561422657600080fd5b823561423181613e32565b915060208301356001600160801b038116811461424d57600080fd5b809150509250929050565b60008060006060848603121561426d57600080fd5b833561427881613e32565b9250602084013561428881613e32565b929592945050506040919091013590565b60006001600160401b038211156142b2576142b2613fe8565b5060051b60200190565b600060208083850312156142cf57600080fd5b82356001600160401b038111156142e557600080fd5b8301601f810185136142f657600080fd5b803561430961430482614299565b614026565b81815260059190911b8201830190838101908783111561432857600080fd5b928401925b82841015613d8957833561434081613e32565b8252928401929084019061432d565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820161438d5761438d614365565b5060010190565b600063ffffffff8083168181036143ad576143ad614365565b6001019392505050565b6000602082840312156143c957600080fd5b5051919050565b600081518084526020808501945080840160005b838110156144095781516001600160a01b0316875295820195908201906001016143e4565b509495945050505050565b600081518084526020808501945080840160005b8381101561440957815187529582019590820190600101614428565b805163ffffffff1682526000610100602083015161446d60208601826001600160a01b03169052565b506040830151816040860152614485828601826143d0565b9150506060830151848203606086015261449f8282614414565b915050608083015184820360808601526144b982826143d0565b91505060a083015184820360a08601526144d38282614414565b91505060c08301516144e960c086018215159052565b5060e083015160e08501528091505092915050565b6040815260006145116040830185614444565b90508260208301529392505050565b600082601f83011261453157600080fd5b8151602061454161430483614299565b82815260e0928302850182019282820191908785111561456057600080fd5b8387015b858110156145cf5781818a03121561457c5760008081fd5b614584613ffe565b81518152858201518682015260408083015190820152606080830151908201526080808301519082015260a0808301519082015260c080830151908201528452928401928101614564565b5090979650505050505050565b600080600080608085870312156145f257600080fd5b84516001600160401b0381111561460857600080fd5b61461487828801614520565b6020870151604088015160609098015191999098509095509350505050565b828152604060208201526000613cb16040830184614444565b805161465781613e32565b919050565b60006020828403121561466e57600080fd5b8151613b4681613e32565b805161465781613eab565b60006020828403121561469657600080fd5b8151613b4681613eab565b818103818111156146b4576146b4614365565b92915050565b63ffffffff83168152604060208201526000613cb16040830184614444565b600080604083850312156146ec57600080fd5b82356146f781613eab565b946020939093013593505050565b808201828112600083128015821682158216171561472557614725614365565b505092915050565b60008060006060848603121561474257600080fd5b8335925060208401359150604084013561475b81613eab565b809150509250925092565b80820281158282048414176146b4576146b4614365565b60008261479a57634e487b7160e01b600052601260045260246000fd5b500490565b602081526000613b466020830184614115565b81810360008312801583831316838312821617156147d2576147d2614365565b5092915050565b600080604083850312156147ec57600080fd5b505080516020909101519092909150565b600080600080600060a0868803121561481557600080fd5b85516001600160401b0381111561482b57600080fd5b61483788828901614520565b6020880151604089015160608a01516080909a0151929b919a509897509095509350505050565b6001600160801b038181168382160190808211156147d2576147d2614365565b808201808211156146b4576146b4614365565b602081526000613b4660208301846143d0565b8051600881900b811461465757600080fd5b805160ff8116811461465757600080fd5b600060e082840312156148d957600080fd5b6148e1613ffe565b825168ffffffffffffffffff811681146148fa57600080fd5b81526149086020840161464c565b6020820152614919604084016148a4565b604082015261492a606084016148b6565b606082015261493b608084016148b6565b608082015261494c60a0840161464c565b60a082015261495d60c08401614679565b60c08201529392505050565b6000604080835261497c818401866143d0565b83810360208581019190915285518083528682019282019060005b81811015614a25578451805168ffffffffffffffffff168452848101516001600160a01b0316858501528681015160080b8785015260608082015160ff908116918601919091526080808301519091169085015260a080820151614a05828701826001600160a01b03169052565b505060c0908101511515908401529383019360e090920191600101614997565b509098975050505050505050565b60008251614a458184602087016140f1565b919091019291505056fea2646970667358221220c87174f0c894151860a1e227ff037e959d1c5d845988d8e5d63c758ec670d13264736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000e8e40fd4ddab26b44b1fb2d6d73833cb0a33b736000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e10000000000000000000000000000000000000000000000000000000000000064
-----Decoded View---------------
Arg [0] : _oracleModule (address): 0xe8e40Fd4DdAb26B44b1fb2D6d73833Cb0A33B736
Arg [1] : _govModule (address): 0xc6F50903a058f3807111619bD4B24cA64b8239E1
Arg [2] : _deviationThreshold (uint8): 100
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000e8e40fd4ddab26b44b1fb2d6d73833cb0a33b736
Arg [1] : 000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e1
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000064
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
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.