15M+ users trust MoonPay. Checkout with your preferred payment method.
Ready to onboard to Ethereum? With MetaMask Portfolio, you're in control.
Get up to 0.5% cashback per purchase and receive daily interest.
Ready to simplify your web3 experience? Try the all-in-one web3 app trusted by millions worldwide.
Opt-in, make your first trade on Exchange Plus & receive random crypto rewards from 10,000 SHIB, to 0.01 BTC.
Everyday giveaways up to 100 ETH, Lucky Spins. Deposit BONUS 300% and Cashbacks!
9 years old Licensed Crypto Casino, Instant Withdraw 24/7, 6000+ Slots available, Paypal Deposit, Instant Live Support 24/7, 30% Rakeback.
5000+ Slots & Live Casino Games, 50+cryptos. Register with Etherscan and get 760% deposit bonus. Win Big$, withdraw it fast.
5000+ Slots & Live Casino Games, 50+cryptos. Register with Etherscan and get 760% deposit bonus. Win Big$, withdraw it fast.
Play 100s of games anonymously with all major cryptos. Join CryptoWins & start winning!
Anonymous play on awesome games - sign up now for 25 free jackpot spins - worth $100s!
Overview
ETH Balance
Eth Value
$0.00Token Holdings
Could not find any matches!
- ERC-20 Tokens (58)2,978,334.86853998 ENQAIenqAI (ENQAI)$58,920.91@0.019810,700.15157265 AGRSAgoras Token (AGRS)$23,219.33@2.170.13343992 ALCXAlchemix (ALCX)$2.45@18.361,702,965.29580775 BEAMBeam (BEAM)$30,589.94@0.018105.34615015 CRVCurve DAO To... (CRV)$30.73@0.29173,092.09823778 ENAEthena (ENA)$1,463.25@0.4732171.95227924 ETHFIether.fi gov... (ETHFI)$416.12@2.4262.85665391 FRAXFrax (FRAX)$62.80@0.999123,827.0429779 HUNTHUNT Token (HUNT)$37,982.09@0.306719.89166314 IMXImmutable X (IMX)$32.22@1.6273,139.35857935 IPORIPOR Token (IPOR)$40,115.26@0.548533,272.94110011 ONDOOndo (ONDO)$36,433.87@1.0953,592.10773381 OGNOriginToken (OGN)$364.03@0.10133,504,867,973.31825 PEPEPepe (PEPE)$41,953.27@0.00108,564.929208 POWRPowerLedger (POWR)$23,282.40@0.214578.59939946 PRIMEPrime (PRIME)$728.62@9.273,276.03673597 RNDRRender Token (RNDR)$22,244.29@6.795,542,491.9041515 RSRReserve Righ... (RSR)$31,333.15@0.005716.18204888 rETHRocket Pool ... (rETH)$62,685.05@3,873.742,023,158.87767172 SiloSilo Governa... (Silo)$106,966.43@0.05291,421,883.96783092 SDEXSmarDex Toke... (SDEX)$19,821.32@0.01391,429,514.21469284 TRUTrueFi (TRU)$198,753.94@0.13981.63213074 wTAOWrapped TAO (wTAO)$26,238.20@321.425,240.40054931 TONCOINWrapped TON ... (TONCOI...)$38,097.71@7.2750.87144831 XDEFIXDEFI (XDEFI)$4.30@0.0845174.9420426 AAVEAave Token (AAVE)$17,394.15@99.42812,536.59107771 LINKChainLink To... (LINK)$36,476.18@14.385.87085438 DAIDai Stableco... (DAI)$5.87@1.0022,642.6584737 LDOLido DAO Tok... (LDO)$44,606.04@1.9711.89486438 MKRMaker (MKR)$34,713.14@2,918.330.93329968 MNTMantle (MNT)$0.73@0.78198,044.69097335 PENDLEPendle (PENDLE)$37,166.47@4.6210.654556 USDTTether USD (USDT)$10.67@1.00137.92829368 UNIUniswap (UNI)$309.12@8.1524,842.264644 USDCUSDC (USDC)$24,842.26@1.000.00228069 WBTCWrapped BTC (WBTC)$148.27@65,011.0021.92280673 WETHWrapped Ethe... (WETH)$75,693.02@3,452.706818.6213034 wstETHWrapped liqu... (wstETH)$75,641.41@4,062.098,888,888,888,888,880,00... Fyde Points - www.fyde.cc! FYDE (Fyde P...)639,999,998,296,767,000 Fyde Points - www.fyde.cc! FYDE (Fyde P...)639,999,999,452,125,000 Fyde Points - www.fyde.cc! FYDE (Fyde P...)750 $stLink rewards on stlink.fi! stlink.fi ($stLin...)56.72558027 ETH+ETHPlus (ETH+)8,446.771839 LNDXLandX Governance Token$9,257.66@1.09612,722.79394288 PEASPeapods$44,402.55@3.49386.57830792 TRSYTRSY584,892.501688 VIRTUALVirtual Protocol$28,720.08@0.049130,000ERC20 ***50,000 yield-ENAyield-ENA (yield-...)70 yield-WETHyield-WETH (yield-...)3.07680954 LUSDLUSD Stablecoin$3.07@0.99931.2 TokenERC-20 TOKEN*[Suspicious]30 TokenERC-20 TOKEN*[Suspicious]245.44 TokenERC-20 TOKEN*[Suspicious]1.5 TokenERC-20 TOKEN*[Suspicious]3,999.99 TokenERC-20 TOKEN*[Suspicious]132.84 TokenERC-20 TOKEN*[Spam]29,176 TokenERC-20 TOKEN*[Spam]NFT Tokens (26)nft-dai.comDAI Mysterybox NFTERC-1155EventERC-1155Visit Lido-LP.com to claim rewardsVisit Lido-LP.com to claim rewardsERC-1155Withdraw NFT originethers.comWithdraw NFT originethers.comERC-1155ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Suspicious]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]ERC-1155 TOKEN*[Spam]
More Info
Private Name Tags
ContractCreator
TokenTracker
- Transactions
- Internal Transactions
- Token Transfers (ERC-20)
- NFT Transfers
- Contract
- Events
- Analytics
- Multichain Portfolio
- Cards New
- Info
Advanced Filter- Filter by Tx Type:
- Tx
- Internal Tx
- ERC-20
- NFTs
Latest 25 from a total of 1,265 transactions
Transaction Hash MethodBlockFromToApprove 20324967 2024-07-17 8:10:59 6 hrs ago 1721203859 IN 0 ETH$0.00 0.00028056 9.63123348 Approve 20324945 2024-07-17 8:06:35 6 hrs ago 1721203595 IN 0 ETH$0.00 0.00042378 9.17146388 Approve 20323975 2024-07-17 4:51:59 9 hrs ago 1721191919 IN 0 ETH$0.00 0.00018 7.4312339 Approve 20323956 2024-07-17 4:48:11 9 hrs ago 1721191691 IN 0 ETH$0.00 0.00032063 6.93540151 Approve 20322181 2024-07-16 22:52:11 15 hrs ago 1721170331 IN 0 ETH$0.00 0.00021616 4.67575281 Approve 20319414 2024-07-16 13:36:59 24 hrs ago 1721137019 IN 0 ETH$0.00 0.00021013 8.67490012 Approve 20318921 2024-07-16 11:58:11 26 hrs ago 1721131091 IN 0 ETH$0.00 0.00044626 9.65285203 Approve 20318673 2024-07-16 11:08:35 27 hrs ago 1721128115 IN 0 ETH$0.00 0.00035664 7.71444327 Approve 20318645 2024-07-16 11:02:59 27 hrs ago 1721127779 IN 0 ETH$0.00 0.00028306 6.1275421 Transfer 20318584 2024-07-16 10:50:35 27 hrs ago 1721127035 IN 0 ETH$0.00 0.00016989 4.96106752 Approve 20318428 2024-07-16 10:19:11 28 hrs ago 1721125151 IN 0 ETH$0.00 0.00026257 5.67962697 Approve 20317855 2024-07-16 8:23:59 30 hrs ago 1721118239 IN 0 ETH$0.00 0.00020504 8.46496489 Approve 20317309 2024-07-16 6:34:11 31 hrs ago 1721111651 IN 0 ETH$0.00 0.00018835 4.07416379 Approve 20316655 2024-07-16 4:22:59 34 hrs ago 1721103779 IN 0 ETH$0.00 0.00022829 4.94062111 Approve 20314293 2024-07-15 20:27:35 42 hrs ago 1721075255 IN 0 ETH$0.00 0.00072787 15.74431676 Approve 20314133 2024-07-15 19:55:11 42 hrs ago 1721073311 IN 0 ETH$0.00 0.00049491 16.98914855 Approve 20313222 2024-07-15 16:51:59 45 hrs ago 1721062319 IN 0 ETH$0.00 0.00141736 30.65821888 Approve 20312002 2024-07-15 12:46:23 2 days ago 1721047583 IN 0 ETH$0.00 0.00041616 9.00190347 Approve 20310783 2024-07-15 8:41:11 2 days ago 1721032871 IN 0 ETH$0.00 0.00023032 4.98207602 Approve 20310772 2024-07-15 8:38:59 2 days ago 1721032739 IN 0 ETH$0.00 0.00022843 4.94114176 Approve 20310202 2024-07-15 6:44:23 2 days ago 1721025863 IN 0 ETH$0.00 0.00010036 3.44544925 Approve 20310176 2024-07-15 6:39:11 2 days ago 1721025551 IN 0 ETH$0.00 0.00009253 3.51608156 Approve 20310158 2024-07-15 6:35:35 2 days ago 1721025335 IN 0 ETH$0.00 0.00014106 3.05205806 Approve 20306553 2024-07-14 18:31:59 2 days ago 1720981919 IN 0 ETH$0.00 0.00029011 6.27543492 Approve 20304887 2024-07-14 12:57:23 3 days ago 1720961843 IN 0 ETH$0.00 0.00012944 2.79988732 View more zero value Internal Transactions in Advanced View mode
Advanced mode:Loading...LoadingContract Name:Fyde
Compiler Versionv0.8.19+commit.7dd6d404
Optimization Enabled:Yes with 200 runs
Other Settings:paris EvmVersionContract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; /// Import from Core ///// import {TRSY} from "./core/TRSY.sol"; import {AssetRegistry} from "./core/AssetRegistry.sol"; import {AddressRegistry} from "./core/AddressRegistry.sol"; import {ProtocolState} from "./core/ProtocolState.sol"; import {Tax} from "./core/Tax.sol"; import {GovernanceAccess} from "./core/GovernanceAccess.sol"; /// Structs ///// import {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 {IOracle} from "src/interfaces/IOracle.sol"; import {IRelayer} from "src/interfaces/IRelayer.sol"; ///@title Fyde contract ///@notice Fyde is the main contract of the protocol, it handles logic of deposit and withdraw in /// the protocol /// Deposit and withdraw occurs a mint or a burn of TRSY (ERC20 that represent shares of the /// procotol in USD value) /// Users can both deposit/withdraw in standard or governance pool contract Fyde is TRSY, AddressRegistry, ProtocolState, AssetRegistry, GovernanceAccess, Tax { using SafeERC20 for IERC20; /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event FeesCollected(address indexed recipient, uint256 trsyFeesCollected); event Deposit(uint32 requestId, uint256 trsyPrice, uint256 usdDepositValue, uint256 trsyMinted); event Withdraw(uint32 requestId, uint256 trsyPrice, uint256 usdWithdrawValue, uint256 trsyBurned); event Swap(uint32 requestId, address assetOut, uint256 amountOut); event ManagementFeeCollected(uint256 feeToMint); /*////////////////////////////////////////////////////////////// ERROR //////////////////////////////////////////////////////////////*/ error AumNotInRange(); error OnlyOneUpdatePerBlock(); error SlippageExceed(); error FydeBalanceInsufficient(); error InsufficientTRSYBalance(); error AssetPriceNotAvailable(); error SwapAmountNotAvailable(); error AssetNotSupported(address asset); error SwapDisabled(address asset); error AssetIsQuarantined(address asset); /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( address _relayer, address _oracleModule, address _governanceModule, uint16 _maxAumDeviationAllowed, uint72 _taxFactor, uint72 _managementFee ) Ownable(msg.sender) AddressRegistry(_governanceModule, _relayer) { oracleModule = IOracle(_oracleModule); updateMaxAumDeviationAllowed(_maxAumDeviationAllowed); updateTaxFactor(_taxFactor); updateManagementFee(_managementFee); _updateLastFeeCollectionTime(); } /*////////////////////////////////////////////////////////////// AUTH //////////////////////////////////////////////////////////////*/ ///@notice Collect and send TRSY fees (from tax fees) to an external address ///@param _recipient Address to send TRSY fees to ///@param _amount Amount of TRSY to send function collectFees(address _recipient, uint256 _amount) external onlyOwner { _checkZeroAddress(_recipient); _checkZeroValue(_amount); balanceOf[address(this)] -= _amount; balanceOf[_recipient] += _amount; emit FeesCollected(_recipient, _amount); } ///@notice Collect management fee by inflating TRSY and minting to Fyde /// is called by the relayer when processingRequests function collectManagementFee() external { uint256 feePerSecond = uint256(protocolData.managementFee / 31_557_600); uint256 timePeriod = block.timestamp - protocolData.lastFeeCollectionTime; if (timePeriod == 0) return; uint256 feeToMint = feePerSecond * timePeriod * totalSupply / 1e18; _updateLastFeeCollectionTime(); _mint(address(this), feeToMint); emit ManagementFeeCollected(feeToMint); } /*////////////////////////////////////////////////////////////// RELAYER & KEEPER FUNCTIONS //////////////////////////////////////////////////////////////*/ ///@notice Update protocol AUM, called by keeper ///@param _aum New AUM ///@dev Can at most be updated by maxDeviationThreshold and only once per block function updateProtocolAUM(uint256 _aum) external { if (msg.sender != RELAYER && msg.sender != owner) revert Unauthorized(); if (block.number == protocolData.lastAUMUpdateBlock) revert CoolDownPeriodActive(); protocolData.lastAUMUpdateBlock = uint48(block.number); (, uint256 limitedAum) = _AumIsInRange(_aum); _updateProtocolAUM(limitedAum); } /*////////////////////////////////////////////////////////////// PROCESSING DEPOSIT ACTIONS //////////////////////////////////////////////////////////////*/ ///@notice Process deposit action, called by relayer ///@param _protocolAUM AUM given by keeper ///@param _req RequestData struct ///@return totalUsdDeposit USD value of the deposit function processDeposit(uint256 _protocolAUM, RequestData calldata _req) external onlyRelayer returns (uint256) { // Check if asset is supported _checkIsSupported(_req.assetIn); _checkIsNotQuarantined(_req.assetIn); // is keeper AUM in range (bool isInRange,) = _AumIsInRange(_protocolAUM); if (!isInRange) revert AumNotInRange(); ( ProcessParam[] memory processParam, uint256 sharesToMint, uint256 taxInTRSY, uint256 totalUsdDeposit ) = getProcessParamDeposit(_req, _protocolAUM); // Slippage checker if (_req.slippageChecker > sharesToMint) revert SlippageExceed(); // Transfer assets to Fyde for (uint256 i; i < _req.assetIn.length; i++) { IERC20(_req.assetIn[i]).safeTransferFrom(_req.requestor, address(this), _req.amountIn[i]); } if (_req.keepGovRights) _govDeposit(_req, processParam); else _standardDeposit(_req, sharesToMint); // Mint tax and keep in contract if (taxInTRSY > 0) _mint(address(this), taxInTRSY); _updateProtocolAUM(_protocolAUM + totalUsdDeposit); uint256 trsyPrice = (1e18 * (_protocolAUM + totalUsdDeposit)) / totalSupply; emit Deposit(_req.id, trsyPrice, totalUsdDeposit, sharesToMint); return totalUsdDeposit; } function _standardDeposit(RequestData calldata _req, uint256 _sharesToMint) internal { // Accounting _increaseAssetTotalAmount(_req.assetIn, _req.amountIn); // Minting shares _mint(_req.requestor, _sharesToMint); } function _govDeposit(RequestData calldata _req, ProcessParam[] memory _processParam) internal { uint256[] memory sharesAfterTax = new uint256[](_req.assetIn.length); uint256[] memory amountInAfterTax = new uint256[](_req.assetIn.length); // Same average tax rate is applied to each asset uint256 taxMultiplicator; uint256 totalTrsy; for (uint256 i; i < _req.assetIn.length; i++) { taxMultiplicator = 1e18 * _processParam[i].sharesAfterTax / (_processParam[i].sharesBeforeTax); amountInAfterTax[i] = _req.amountIn[i] * taxMultiplicator / 1e18; sharesAfterTax[i] = _processParam[i].sharesAfterTax; totalTrsy += sharesAfterTax[i]; } // Mint stTRSY and transfer token into proxy address proxy = GOVERNANCE_MODULE.govDeposit( _req.requestor, _req.assetIn, amountInAfterTax, sharesAfterTax, totalTrsy ); for (uint256 i; i < _req.assetIn.length; i++) { IERC20(_req.assetIn[i]).safeTransfer(proxy, amountInAfterTax[i]); } // Accounting _increaseAssetTotalAmount(_req.assetIn, _req.amountIn); _increaseAssetProxyAmount(_req.assetIn, amountInAfterTax); // Mint _mint(address(GOVERNANCE_MODULE), totalTrsy); } /*////////////////////////////////////////////////////////////// PROCESSING WITHDRAW ACTIONS //////////////////////////////////////////////////////////////*/ ///@notice Process withdraw action, called by relayer ///@param _protocolAUM AUM given by keeper ///@param _req RequestData struct ///@return totalUsdWithdraw USD value of the withdraw function processWithdraw(uint256 _protocolAUM, RequestData calldata _req) external onlyRelayer returns (uint256) { // Check if asset is supported _checkIsSupported(_req.assetOut); _checkIsNotQuarantined(_req.assetOut); // is keeper AUM in range (bool isInRange,) = _AumIsInRange(_protocolAUM); if (!isInRange) revert AumNotInRange(); uint256 totalUsdWithdraw; uint256 totalSharesToBurn; (totalUsdWithdraw, totalSharesToBurn) = _req.keepGovRights ? _govWithdraw(_protocolAUM, _req) : _standardWithdraw(_protocolAUM, _req); // Accounting _decreaseAssetTotalAmount(_req.assetOut, _req.amountOut); _updateProtocolAUM(_protocolAUM - totalUsdWithdraw); // Calculate for offchain purpose uint256 trsyPrice = totalSupply != 0 ? (1e18 * (_protocolAUM - totalUsdWithdraw)) / totalSupply : 0; emit Withdraw(_req.id, trsyPrice, totalUsdWithdraw, totalSharesToBurn); return totalUsdWithdraw; } function _govWithdraw(uint256 _protocolAUM, RequestData calldata _req) internal returns (uint256, uint256) { uint256 usdVal = getQuote(_req.assetOut[0], _req.amountOut[0]); if (usdVal == 0) revert AssetPriceNotAvailable(); uint256 trsyToBurn = _convertToShares(usdVal, _protocolAUM); if (_req.slippageChecker < trsyToBurn) revert SlippageExceed(); _burn(address(GOVERNANCE_MODULE), trsyToBurn); _decreaseAssetProxyAmount(_req.assetOut, _req.amountOut); GOVERNANCE_MODULE.govWithdraw(_req.requestor, _req.assetOut[0], _req.amountOut[0], trsyToBurn); IERC20(_req.assetOut[0]).safeTransfer(_req.requestor, _req.amountOut[0]); return (usdVal, trsyToBurn); } function _standardWithdraw(uint256 _protocolAUM, RequestData calldata _req) internal returns (uint256, uint256) { // check if requested token are available for (uint256 i = 0; i < _req.assetOut.length; i++) { if (standardAssetAccounting(_req.assetOut[i]) < _req.amountOut[i]) { revert FydeBalanceInsufficient(); } } (, uint256 totalSharesToBurn,, uint256 taxInTRSY, uint256 totalUsdWithdraw) = getProcessParamWithdraw(_req, _protocolAUM); if (totalSharesToBurn > _req.slippageChecker) revert SlippageExceed(); if (balanceOf[_req.requestor] < totalSharesToBurn) revert InsufficientTRSYBalance(); _burn(_req.requestor, totalSharesToBurn); // Give tax to this contract if (taxInTRSY > 0) _mint(address(this), taxInTRSY); for (uint256 i = 0; i < _req.assetOut.length; i++) { // Send asset to recipient IERC20(_req.assetOut[i]).safeTransfer(_req.requestor, _req.amountOut[i]); } return (totalUsdWithdraw, totalSharesToBurn); } /*////////////////////////////////////////////////////////////// SWAP //////////////////////////////////////////////////////////////*/ function processSwap(uint256 _protocolAUM, RequestData calldata _req) external onlyRelayer returns (int256) { // Check if asset is supported _checkIsSupported(_req.assetIn); _checkIsSupported(_req.assetOut); _checkIsNotQuarantined(_req.assetIn); _checkIsNotQuarantined(_req.assetOut); _checkIfSwapAllowed(_req.assetIn); _checkIfSwapAllowed(_req.assetOut); // is keeper AUM in range (bool isInRange,) = _AumIsInRange(_protocolAUM); if (!isInRange) revert AumNotInRange(); (uint256 amountOut, int256 deltaAUM) = getSwapAmountOut(_req.assetIn[0], _req.amountIn[0], _req.assetOut[0], _protocolAUM); if (amountOut == 0) revert SwapAmountNotAvailable(); if (amountOut < _req.slippageChecker) revert SlippageExceed(); // Check enough asset in protocol if (standardAssetAccounting(_req.assetOut[0]) < amountOut) revert FydeBalanceInsufficient(); // Update AUM uint256 aum; // If the swapper pays net tax, we mint the corresponding TRSY to fyde. This way TRSY price // stays constant if (deltaAUM > 0) { aum = _protocolAUM + uint256(deltaAUM); _mint(address(this), _convertToShares(uint256(deltaAUM), _protocolAUM)); // If incentives are higher tan taxes, we burn TRSY from fyde, to keep TRSY price constant // as backup if not enough TRSY in Fyde, we don't burn, i.e. TRSY price goes down and // incentives are // paid by pool // this way by frequently cashing out TRSY from fyde we can manually decide how much tax to // keep for ourselves // or leave in Fyde for incentives } else if (deltaAUM < 0) { aum = _protocolAUM - uint256(-deltaAUM); uint256 trsyToBurn = _convertToShares(uint256(-deltaAUM), _protocolAUM); trsyToBurn = balanceOf[address(this)] >= trsyToBurn ? trsyToBurn : balanceOf[address(this)]; if (trsyToBurn != 0) _burn(address(this), trsyToBurn); } else { aum = _protocolAUM; } _updateProtocolAUM(aum); // Log accounting _increaseAssetTotalAmount(_req.assetIn[0], _req.amountIn[0]); _decreaseAssetTotalAmount(_req.assetOut[0], amountOut); // Transfer asset IERC20(_req.assetIn[0]).safeTransferFrom(_req.requestor, address(this), _req.amountIn[0]); IERC20(_req.assetOut[0]).safeTransfer(_req.requestor, amountOut); emit Swap(_req.id, _req.assetOut[0], amountOut); return deltaAUM; } /*/////////////////////////////////////////////////////////////// GETTERS //////////////////////////////////////////////////////////////*/ ///@notice Give a quote for a speficic asset deposit ///@param _asset asset address to quote ///@param _amount amount of asset to deposit ///@return USD value of the specified deposit (return 18 decimals, 1USD = 1e18) ///@dev If price is inconsistent or not available, returns 0 from oracle module -> needs proper /// handling function getQuote(address _asset, uint256 _amount) public view override returns (uint256) { AssetInfo memory _assetInfo = assetInfo[_asset]; uint256 price = oracleModule.getPriceInUSD(_asset, _assetInfo); return (_amount * price) / (10 ** _assetInfo.assetDecimals); } ///@notice Get the USD value of an asset in the protocol ///@param _asset asset address ///@return USD value of the asset ///@dev If price is inconsistent or not available, returns 0 -> needs proper handling function getAssetAUM(address _asset) public view returns (uint256) { return getQuote(_asset, totalAssetAccounting[_asset]); } ///@notice Compute the USD AUM for the protocol ///@dev Should NOT be call within a contract (GAS EXPENSIVE), called off-chain by keeper function computeProtocolAUM() public view returns (uint256) { address asset; uint256 aum; uint256 assetAUM; address[] memory nAsset = assetsList; uint256 length = nAsset.length; for (uint256 i = 0; i < length; ++i) { asset = nAsset[i]; if (totalAssetAccounting[asset] == 0) continue; assetAUM = getAssetAUM(asset); if (assetAUM == 0) return protocolData.aum; aum += assetAUM; } return aum; } /*////////////////////////////////////////////////////////////// PROCESS PARAM //////////////////////////////////////////////////////////////*/ ///@notice Return the process param for a deposit ///@param _req RequestData struct ///@param _protocolAUM AUM given by keeper ///@return processParam array of ProcessParam struct ///@return sharesToMint amount of shares to mint ///@return taxInTRSY amount of tax in TRSY ///@return totalUsdDeposit USD value of the depositn function getProcessParamDeposit(RequestData memory _req, uint256 _protocolAUM) public view returns ( ProcessParam[] memory processParam, uint256 sharesToMint, uint256 taxInTRSY, uint256 totalUsdDeposit ) { processParam = new ProcessParam[](_req.assetIn.length); // Build data struct and compute value of deposit for (uint256 i; i < _req.assetIn.length; i++) { uint256 usdVal = getQuote(_req.assetIn[i], _req.amountIn[i]); if (usdVal == 0) revert AssetPriceNotAvailable(); processParam[i] = ProcessParam({ targetConc: assetInfo[_req.assetIn[i]].targetConcentration, currentConc: _getAssetConcentration(_req.assetIn[i], _protocolAUM), usdValue: usdVal, sharesBeforeTax: _convertToShares(usdVal, _protocolAUM), taxableAmount: 0, taxInUSD: 0, sharesAfterTax: 0 }); totalUsdDeposit += usdVal; } for (uint256 i; i < processParam.length; i++) { // Get the TaxInUSD processParam[i] = _getDepositTax(processParam[i], _protocolAUM, totalUsdDeposit, protocolData.taxFactor); // Apply tax to the deposit processParam[i].sharesAfterTax = _convertToShares(processParam[i].usdValue - processParam[i].taxInUSD, _protocolAUM); sharesToMint += processParam[i].sharesAfterTax; taxInTRSY += processParam[i].sharesBeforeTax - processParam[i].sharesAfterTax; } return (processParam, sharesToMint, taxInTRSY, totalUsdDeposit); } ///@notice Return the process param for a withdraw ///@param _req RequestData struct ///@param _protocolAUM AUM given by keeper ///@return processParam array of ProcessParam struct ///@return totalSharesToBurn amount of shares to burn ///@return sharesToBurnBeforeTax amount of shares to burn before tax ///@return taxInTRSY amount of tax in TRSY ///@return totalUsdWithdraw USD value of the withdraw function getProcessParamWithdraw(RequestData calldata _req, uint256 _protocolAUM) public view returns ( ProcessParam[] memory processParam, uint256 totalSharesToBurn, uint256 sharesToBurnBeforeTax, uint256 taxInTRSY, uint256 totalUsdWithdraw ) { processParam = new ProcessParam[](_req.assetOut.length); // Build data struct and compute value of deposit for (uint256 i; i < _req.assetOut.length; i++) { uint256 usdVal = getQuote(_req.assetOut[i], _req.amountOut[i]); if (usdVal == 0) revert AssetPriceNotAvailable(); processParam[i] = ProcessParam({ targetConc: assetInfo[_req.assetOut[i]].targetConcentration, currentConc: _getAssetConcentration(_req.assetOut[i], _protocolAUM), usdValue: usdVal, sharesBeforeTax: 0, taxableAmount: 0, taxInUSD: 0, sharesAfterTax: 0 }); totalUsdWithdraw += usdVal; } for (uint256 i; i < processParam.length; i++) { // Get the TaxInUSD processParam[i] = _getWithdrawTax(processParam[i], _protocolAUM, totalUsdWithdraw, protocolData.taxFactor); taxInTRSY += _convertToShares(processParam[i].taxInUSD, _protocolAUM); } sharesToBurnBeforeTax = _convertToShares(totalUsdWithdraw, _protocolAUM); totalSharesToBurn = sharesToBurnBeforeTax + taxInTRSY; } ///@notice Return the amountOut for a swap accounting for tax and incentive ///@param _assetIn asset address to swap ///@param _amountIn amount of asset to swap ///@param _assetOut asset address to receive ///@param _protocolAUM AUM given by keeper function getSwapAmountOut( address _assetIn, uint256 _amountIn, address _assetOut, uint256 _protocolAUM ) public view returns (uint256, int256) { // Scope to avoid stack too deep { uint256 usdValIn = getQuote(_assetIn, _amountIn); uint256 assetOutPrice = getQuote(_assetOut, 10 ** assetInfo[_assetOut].assetDecimals); if (usdValIn == 0 || assetOutPrice == 0) return (0, int256(0)); } ProcessParam memory processParamIn = ProcessParam({ targetConc: assetInfo[_assetIn].targetConcentration, currentConc: _getAssetConcentration(_assetIn, _protocolAUM), usdValue: getQuote(_assetIn, _amountIn), sharesBeforeTax: 0, taxableAmount: 0, taxInUSD: 0, sharesAfterTax: 0 }); ProcessParam memory processParamOut = ProcessParam({ targetConc: assetInfo[_assetOut].targetConcentration, currentConc: _getAssetConcentration(_assetOut, _protocolAUM), usdValue: 0, sharesBeforeTax: 0, taxableAmount: 0, taxInUSD: 0, sharesAfterTax: 0 }); uint256 usdAmountOut = _getSwapRate( processParamIn, processParamOut, _protocolAUM, protocolData.taxFactor, assetInfo[_assetIn].incentiveFactor, assetInfo[_assetOut].incentiveFactor ); return ( 1e18 * usdAmountOut / getQuote(_assetOut, 1e18), int256(processParamIn.usdValue) - int256(usdAmountOut) ); } /*////////////////////////////////////////////////////////////// INTERNAL //////////////////////////////////////////////////////////////*/ ///@notice Return asset concentration with keeper AUM ///@param _asset asset address ///@param _protocolAUM AUM given by keeper ///@return current concentration for an asset ///@dev If price is inconsistent or not available, returns 0 -> needs proper handling function _getAssetConcentration(address _asset, uint256 _protocolAUM) internal view returns (uint256) { // To avoid division by 0 if (_protocolAUM == 0 && protocolData.aum == 0) return 0; return (1e20 * getAssetAUM(_asset)) / _protocolAUM; } ///@notice Perform the comparison between AUM registry and one given by Keeper, return limited AUM /// if out of bounds function _AumIsInRange(uint256 _keeperAUM) internal view returns (bool, uint256) { uint16 maxAumDeviationAllowed = protocolData.maxAumDeviationAllowed; uint256 currAum = protocolData.aum; uint256 lowerBound = PercentageMath.percentSub(currAum, maxAumDeviationAllowed); uint256 upperBound = PercentageMath.percentAdd(currAum, maxAumDeviationAllowed); if (_keeperAUM < lowerBound) return (false, lowerBound); if (_keeperAUM > upperBound) return (false, upperBound); return (true, _keeperAUM); } function _checkIsSupported(address[] memory _assets) internal view { address notSupportedAsset = isAnyNotSupported(_assets); if (notSupportedAsset != address(0x0)) revert AssetNotSupported(notSupportedAsset); } function _checkIsNotQuarantined(address[] memory _assets) internal view { address quarantinedAsset = IRelayer(RELAYER).isAnyQuarantined(_assets); if (quarantinedAsset != address(0x0)) revert AssetIsQuarantined(quarantinedAsset); } function _checkIfSwapAllowed(address[] memory _assets) internal view { address notAllowedAsset = isSwapAllowed(_assets); if (notAllowedAsset != address(0x0)) revert SwapDisabled(notAllowedAsset); } /*////////////////////////////////////////////////////////////// MODIFIERS //////////////////////////////////////////////////////////////*/ modifier onlyRelayer() { if (msg.sender != RELAYER) revert Unauthorized(); _; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; import {ERC20} from "solmate/tokens/ERC20.sol"; ///@title TRSY contract ///@notice Handle the logic for minting and burning TRSY shares abstract contract TRSY is ERC20 { /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor() ERC20("TRSY", "TRSY", 18) {} /*////////////////////////////////////////////////////////////// INTERNAL //////////////////////////////////////////////////////////////*/ ///@notice Convert the value of deposit into share of the protocol ///@param _usdValue usd value of the deposit ///@param _usdAUM AUM of the protocol in USD (given by keeper) ///@return TSRY share for an USD deposit function _convertToShares(uint256 _usdValue, uint256 _usdAUM) internal view returns (uint256) { uint256 supply = totalSupply; return supply == 0 ? _usdValue : (_usdValue * supply) / _usdAUM; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; import {AssetInfo} from "./Structs.sol"; import {AddressRegistry} from "./AddressRegistry.sol"; import {ProtocolState} from "./ProtocolState.sol"; import {Ownable} from "../utils/Ownable.sol"; import {BaseChecker} from "../utils/BaseChecker.sol"; import {IERC20Metadata} from "openzeppelin-contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {IUniswapV3PoolImmutables} from "lib/v3-core/contracts/interfaces/pool/IUniswapV3PoolImmutables.sol"; import {IRelayer} from "src/interfaces/IRelayer.sol"; ///@title AssetRegistry contract ///@notice Handle logic and state for logging informations regarding the assets abstract contract AssetRegistry is Ownable, BaseChecker, AddressRegistry, ProtocolState { /*////////////////////////////////////////////////////////////// STORAGE //////////////////////////////////////////////////////////////*/ ///@notice Asset list; address[] public assetsList; ///@notice last block incentiveFactor was updated, safety measure uint128 public lastIncentiveUpdateBlock; int128 public incentiveCap; ///@notice Map asset address to struct containing info mapping(address => AssetInfo) public assetInfo; /*////////////////////////////////////////////////////////////// ERROR //////////////////////////////////////////////////////////////*/ error PoolNotValid(); error AssetSupported(address asset); error NotNormalized(); error NotZero(); error CoolDownPeriodActive(); /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event AssetAdded(address _asset); event IncentiveFactorUpdated(address indexed asset, int72 incentiveFactor); event TargetConcentrationsUpdated(); event UniswapPoolUpdated(address indexed asset, address uniswapPool); event AssetRemoved(address indexed asset); /*////////////////////////////////////////////////////////////// ADD ASSETS //////////////////////////////////////////////////////////////*/ ///@notice Add assets in batch ///@param _assets Array of assets to add ///@param _uniswapPools Array of address of uniswap Pool ///@dev only uniswap pool and incentive factor are relevant in assetsInfo, the rest is retrieved /// on-chain function addAssets(address[] calldata _assets, address[] calldata _uniswapPools) external onlyOwner { if (_assets.length != _uniswapPools.length) revert InconsistentLengths(); for (uint256 i; i < _assets.length; ++i) { _addAsset(_assets[i], _uniswapPools[i]); } } function _addAsset(address _asset, address _uniswapPool) private { if (assetInfo[_asset].isSupported) revert AssetSupported(_asset); assetInfo[_asset].isSupported = true; assetInfo[_asset].assetDecimals = IERC20Metadata(_asset).decimals(); setUniswapPool(_asset, _uniswapPool); assetsList.push(_asset); emit AssetAdded(_asset); } ///@notice Removes asset from the protocol whitelist ///@param _assetIdx index of the asset in the assets array ///@dev only possible if there are no tokens of the asset held by the protocol anymore function removeAsset(uint256 _assetIdx) external onlyOwner { address asset = assetsList[_assetIdx]; if (totalAssetAccounting[asset] != 0) revert NotZero(); if (assetInfo[asset].targetConcentration != 0) revert NotZero(); delete assetInfo[asset]; assetsList[_assetIdx] = assetsList[assetsList.length - 1]; assetsList.pop(); emit AssetRemoved(asset); } /*////////////////////////////////////////////////////////////// SETTER //////////////////////////////////////////////////////////////*/ ///@notice Set target concentration for all asset ///@param _targetConcentrations Target concentration (1e18 -> 1%) ///@dev 1e18 = 1% ///@dev targetConcentrations must have same length as assetsList -> can only update all conc at // once to enforce normalization function setTargetConcentrations(uint72[] calldata _targetConcentrations) external onlyOwner { if (_targetConcentrations.length != assetsList.length) revert InconsistentLengths(); uint72 sum; for (uint256 i; i < _targetConcentrations.length; i++) { sum += _targetConcentrations[i]; } if (sum > (1e20 + 1e10) || sum < (1e20 - 1e10)) revert NotNormalized(); for (uint256 i; i < _targetConcentrations.length; i++) { assetInfo[assetsList[i]].targetConcentration = _targetConcentrations[i]; } emit TargetConcentrationsUpdated(); } ///@notice Set target concentration for an asset ///@param _asset Asset address ///@param _incentiveFactor IncentiveFactor (1e18 -> 1%) ///@dev 1e18 = 1%, max incentiveCap ///@dev Can only be called every 5 blocks, safety measure in case of compromised IncentiveManager function setIncentiveFactor(address _asset, int72 _incentiveFactor) external onlyIncentiveManager { if (int128(_incentiveFactor) > incentiveCap) revert ValueOutOfBounds(); if (block.number < uint256(lastIncentiveUpdateBlock) + 5) revert CoolDownPeriodActive(); lastIncentiveUpdateBlock = uint128(block.number); assetInfo[_asset].incentiveFactor = _incentiveFactor; emit IncentiveFactorUpdated(_asset, _incentiveFactor); } ///@notice Set maximum incentive factor ///@param _incentiveCap maximum incentive factor ///@dev Capped at 1e20 == 100% function setIncentiveCap(int128 _incentiveCap) external onlyOwner { if (_incentiveCap > 1e20) revert ValueOutOfBounds(); incentiveCap = _incentiveCap; } ///@notice Set uniswap pool for an asset ///@param _asset Asset address ///@param _uniswapPool Uniswap pool address function setUniswapPool(address _asset, address _uniswapPool) public onlyOwner { if (_uniswapPool == address(0x0)) { assetInfo[_asset].uniswapPool = _uniswapPool; } else { address token0 = IUniswapV3PoolImmutables(_uniswapPool).token0(); address token1 = IUniswapV3PoolImmutables(_uniswapPool).token1(); address quoteToken; if (token0 == _asset) quoteToken = token1; else if (token1 == _asset) quoteToken = token0; else revert PoolNotValid(); assetInfo[_asset].uniswapPool = _uniswapPool; assetInfo[_asset].uniswapQuoteToken = quoteToken; assetInfo[_asset].quoteTokenDecimals = IERC20Metadata(quoteToken).decimals(); } emit UniswapPoolUpdated(_asset, _uniswapPool); } /*////////////////////////////////////////////////////////////// GETTER //////////////////////////////////////////////////////////////*/ ///@notice Get isSupported for an asset ///@param _assets asset addresses ///@return address of first not supported asset or address(0x0) if all supported function isAnyNotSupported(address[] memory _assets) public view returns (address) { for (uint256 i; i < _assets.length; i++) { if (!assetInfo[_assets[i]].isSupported) return _assets[i]; } return address(0x0); } ///@notice Get isSwapAllowed for an asset array ///@param _assets asset addresses ///@return address of first not supported asset or address(0x0) if all supported function isSwapAllowed(address[] memory _assets) public view returns (address) { for (uint256 i; i < _assets.length; i++) { if (assetInfo[_assets[i]].incentiveFactor == -100e18) return _assets[i]; } return address(0x0); } ///@notice Get number of asset decimals ///@param _asset Asset address ///@return number of decimals function getAssetDecimals(address _asset) external view returns (uint8) { return assetInfo[_asset].assetDecimals; } ///@notice Get number of assets in protocol function getAssetsListLength() public view returns (uint256) { return assetsList.length; } ///@dev caller has to be whitelisted manager on relayer modifier onlyIncentiveManager() { if (!IRelayer(RELAYER).isIncentiveManager(msg.sender)) revert Unauthorized(); _; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; // Utils import {Ownable} from "../utils/Ownable.sol"; // Interfaces import {IOracle} from "../interfaces/IOracle.sol"; import {IGovernanceModule} from "../interfaces/IGovernanceModule.sol"; ///@title AddressRegistry contract ///@notice Handle state and logic for external authorized call (mainly keeper) and the oracle module abstract contract AddressRegistry is Ownable { /*////////////////////////////////////////////////////////////// STORAGE //////////////////////////////////////////////////////////////*/ ///@notice Address of the oracle module IOracle public oracleModule; ///@notice Governance Registry contract address interface IGovernanceModule public immutable GOVERNANCE_MODULE; address public RELAYER; /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event OracleModuleUpdated(address indexed oracleModule); /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor(address _govModule, address _relayer) { GOVERNANCE_MODULE = IGovernanceModule(_govModule); RELAYER = _relayer; } /*////////////////////////////////////////////////////////////// ACCESS //////////////////////////////////////////////////////////////*/ function setRelayer(address _relayer) external onlyOwner { RELAYER = _relayer; } ///@notice Set the oracle address function setOracleModule(address _oracle) public onlyOwner { oracleModule = IOracle(_oracle); emit OracleModuleUpdated(_oracle); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; import {ProtocolData} from "./Structs.sol"; import {Ownable} from "../utils/Ownable.sol"; ///@title ProtocolState contract ///@notice Protocol data storage abstract contract ProtocolState is Ownable { /*////////////////////////////////////////////////////////////// STORAGE //////////////////////////////////////////////////////////////*/ ///@notice Protocol data ProtocolData public protocolData; ///@notice Number of token in the protocol mapping(address => uint256) public totalAssetAccounting; ///@notice Number of token in the proxy mapping(address => uint256) public proxyAssetAccounting; /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ error ValueOutOfBounds(); /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event ProtocolAumUpdated(uint256); event MaxAumDeviationAllowedUpdated(uint16); event TaxFactorUpdated(uint72); event ManagementFeeUpdated(uint72); /*////////////////////////////////////////////////////////////// GETTER //////////////////////////////////////////////////////////////*/ ///@notice Get number of token in the standard pool ///@param _asset asset address ///@return number of token in standard pool function standardAssetAccounting(address _asset) public view returns (uint256) { return totalAssetAccounting[_asset] - proxyAssetAccounting[_asset]; } ///@notice Get protocolAUM in USD ///@return protocol AUM function getProtocolAUM() external view returns (uint256) { return protocolData.aum; } /*////////////////////////////////////////////////////////////// SETTER //////////////////////////////////////////////////////////////*/ ///@notice Change the AUM's comparison deviation threshold ///@param threshold new threshold ///@dev 200 = 2 % of deviation function updateMaxAumDeviationAllowed(uint16 threshold) public onlyOwner { // We bound the threshold to 0.1 % to 5% if (threshold < 10 || threshold > 500) revert ValueOutOfBounds(); protocolData.maxAumDeviationAllowed = threshold; emit MaxAumDeviationAllowedUpdated(threshold); } ///@notice set the tax factor ///@param _taxFactor new tax factor ///@dev 100% = 100e18 function updateTaxFactor(uint72 _taxFactor) public onlyOwner { if (_taxFactor > 100e18) revert ValueOutOfBounds(); protocolData.taxFactor = _taxFactor; emit TaxFactorUpdated(_taxFactor); } ///@notice change annual management fee ///@param _annualFee new annual fee ///@dev 100% = 1e18 function updateManagementFee(uint72 _annualFee) public onlyOwner { // We bound the fee to 0 % to 5% if (_annualFee > 5e16) revert ValueOutOfBounds(); protocolData.managementFee = _annualFee; emit ManagementFeeUpdated(_annualFee); } ///@notice Update last fee collection time to current timestamp function _updateLastFeeCollectionTime() internal { protocolData.lastFeeCollectionTime = uint48(block.timestamp); } ///@notice Update the protocol AUM function _updateProtocolAUM(uint256 _aum) internal { protocolData.aum = _aum; emit ProtocolAumUpdated(_aum); } function _increaseAssetTotalAmount(address[] memory _assets, uint256[] memory _amounts) internal { for (uint256 i; i < _assets.length; i++) { _increaseAssetTotalAmount(_assets[i], _amounts[i]); } } function _increaseAssetTotalAmount(address _asset, uint256 _amount) internal { totalAssetAccounting[_asset] += _amount; } function _increaseAssetProxyAmount(address[] memory _assets, uint256[] memory _amounts) internal { for (uint256 i; i < _assets.length; i++) { proxyAssetAccounting[_assets[i]] += _amounts[i]; } } function _decreaseAssetTotalAmount(address[] memory _assets, uint256[] memory _amounts) internal { for (uint256 i; i < _assets.length; i++) { _decreaseAssetTotalAmount(_assets[i], _amounts[i]); } } function _decreaseAssetTotalAmount(address _asset, uint256 _amount) internal { totalAssetAccounting[_asset] -= _amount; } function _decreaseAssetProxyAmount(address[] memory _assets, uint256[] memory _amounts) internal { for (uint256 i; i < _assets.length; i++) { proxyAssetAccounting[_assets[i]] -= _amounts[i]; } } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; import {ProcessParam} from "./Structs.sol"; import {MathUtil} from "../utils/MathUtil.sol"; import "synthetix-v3/utils/core-contracts/contracts/utils/SafeCast.sol"; ///@title Tax contract ///@notice Handle tax logic, for either a deposit or withdraw compute if the action is unabalacing /// the protocol /// if this is the case, the protocol will compute a tax applied on deposit or withdraw by /// reducing the number of shares to mint /// or by increasing the number of shares to burn. This tax is then minted to fyde contract. /// The main logic is that for each action, we compute a taxable amount which is the amount that /// unbalance the protocol for a given deposit or withdraw, /// then we apply the tax on this taxable amount. /// For the swap the logic is the same, we compute the tax and incentive for assetIn and that give /// the value of assetOut, /// for this value we compute the tax and incentive for assetOut. /// SwapRate can be greater for assetOut in case there is no tax and some incentives, the same if no /// tax no incentive, or lower if there is tax and no incentive. abstract contract Tax { using SafeCastU256 for uint256; using SafeCastI256 for int256; /*////////////////////////////////////////////////////////////// MAIN //////////////////////////////////////////////////////////////*/ function _getDepositTax( ProcessParam memory processParam, uint256 protocolAUM, uint256 totalUsdDeposit, uint256 taxFactor ) internal pure returns (ProcessParam memory) { if (processParam.targetConc == 0) { processParam.taxInUSD = processParam.usdValue; return processParam; } if (taxFactor == 0) return processParam; processParam = _computeDepositTaxableAmount(processParam, protocolAUM, totalUsdDeposit); if (processParam.taxableAmount == 0) return processParam; processParam = _computeDepositTaxInUSD(processParam, protocolAUM, totalUsdDeposit, taxFactor); return processParam; } function _getWithdrawTax( ProcessParam memory processParam, uint256 protocolAUM, uint256 totalUsdWithdraw, uint256 taxFactor ) internal pure returns (ProcessParam memory) { if (taxFactor == 0) return processParam; processParam = _computeWithdrawTaxableAmount(processParam, protocolAUM, totalUsdWithdraw); if (processParam.taxableAmount == 0) return processParam; processParam = _computeWithdrawTaxInUSD(processParam, protocolAUM, totalUsdWithdraw, taxFactor); return processParam; } function _getSwapRate( ProcessParam memory processParamIn, ProcessParam memory processParamOut, uint256 protocolAUM, uint256 taxFactor, int256 incentiveFactorIn, int256 incentiveFactorOut ) internal pure returns (uint256) { // Compute tax on deposit processParamIn = _getDepositTax(processParamIn, protocolAUM, 0, taxFactor); int256 valIn = incentiveFactorIn * int256(processParamIn.usdValue - processParamIn.taxableAmount) / int256(1e20); // usdValue adjusted with potential tax and incentive uint256 withdrawValOut = valIn >= 0 ? processParamIn.usdValue - processParamIn.taxInUSD + valIn.toUint() : processParamIn.usdValue - processParamIn.taxInUSD - (-1 * valIn).toUint(); processParamOut.usdValue = withdrawValOut; processParamOut = _getWithdrawTax(processParamOut, protocolAUM, 0, taxFactor); // usdValueOut adjusted with potential tax and incentive int256 valOut = incentiveFactorOut * int256(withdrawValOut - processParamOut.taxableAmount) / 1e20; uint256 usdValOut = valOut >= 0 ? withdrawValOut - processParamOut.taxInUSD + valOut.toUint() : withdrawValOut - processParamOut.taxInUSD - (-1 * valOut).toUint(); return usdValOut; } /*////////////////////////////////////////////////////////////// DEPOSIT //////////////////////////////////////////////////////////////*/ function _computeDepositTaxableAmount( ProcessParam memory processParam, uint256 protocolAUM, uint256 totalUsdDeposit ) internal pure returns (ProcessParam memory) { int256 deltaConc = protocolAUM.toInt() * (processParam.currentConc.toInt() - processParam.targetConc.toInt()) / 1e20; int256 targetDeposit = totalUsdDeposit != 0 ? processParam.targetConc.toInt() * totalUsdDeposit.toInt() / 1e20 : int256(0); int256 tax = processParam.usdValue.toInt() + deltaConc - targetDeposit; processParam.taxableAmount = MathUtil.min(processParam.usdValue.toInt(), MathUtil.max(tax, int256(0))).toUint(); return processParam; } function _computeDepositTaxInUSD( ProcessParam memory processParam, uint256 protocolAUM, uint256 totalUsdDeposit, uint256 taxFactor ) internal pure returns (ProcessParam memory) { uint256 numerator = (protocolAUM * processParam.currentConc / 1e20) + processParam.usdValue; uint256 denominator = (protocolAUM + totalUsdDeposit) * processParam.targetConc / 1e20; uint256 eq = (1e18 * numerator / denominator) - 1e18; uint256 tmpRes = MathUtil.min(eq, 1e18); uint256 taxPerc = taxFactor * tmpRes / 1e20; // 1e20 for applying expressing tax as a percentage processParam.taxInUSD = processParam.taxableAmount * taxPerc / 1e18; return processParam; } /*////////////////////////////////////////////////////////////// WITHDRAW //////////////////////////////////////////////////////////////*/ function _computeWithdrawTaxableAmount( ProcessParam memory processParam, uint256 protocolAUM, uint256 totalUsdWithdraw ) internal pure returns (ProcessParam memory) { int256 deltaConc = protocolAUM.toInt() * (processParam.currentConc.toInt() - processParam.targetConc.toInt()) / 1e20; int256 targetDeposit = processParam.targetConc.toInt() * totalUsdWithdraw.toInt() / 1e20; int256 tax = processParam.usdValue.toInt() - deltaConc - targetDeposit; processParam.taxableAmount = MathUtil.min(processParam.usdValue.toInt(), MathUtil.max(tax, int256(0))).toUint(); return processParam; } function _computeWithdrawTaxInUSD( ProcessParam memory processParam, uint256 protocolAUM, uint256 totalUsdWithdraw, uint256 taxFactor ) internal pure returns (ProcessParam memory) { int256 numerator = protocolAUM.toInt() * processParam.currentConc.toInt() / 1e20 - processParam.usdValue.toInt(); int256 denominator = processParam.targetConc.toInt() * (protocolAUM.toInt() - totalUsdWithdraw.toInt()) / 1e20; int256 tmpRes = 1e18 - (1e18 * numerator / denominator); uint256 tmpRes2 = MathUtil.min(tmpRes.toUint(), 1e18); uint256 taxPerc = taxFactor * tmpRes2 / 1e20; // 1e20 for applying expressing tax as a // percentage processParam.taxInUSD = processParam.taxableAmount * taxPerc / 1e18; return processParam; } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; /// Import from Core ///// import {AddressRegistry} from "./AddressRegistry.sol"; import {AssetRegistry} from "./AssetRegistry.sol"; import {ProtocolState} from "./ProtocolState.sol"; import {TRSY} from "./TRSY.sol"; /// Structs ///// import {RebalanceParam} from "./Structs.sol"; // Interface import {IERC20} from "openzeppelin-contracts/token/ERC20/IERC20.sol"; import {SafeERC20} from "openzeppelin-contracts/token/ERC20/utils/SafeERC20.sol"; ///@title GovernanceAccess contract ///@notice Exposes functions for the governance module abstract contract GovernanceAccess is TRSY, AddressRegistry, ProtocolState, AssetRegistry { using SafeERC20 for IERC20; ///@notice Called by the governance module in order to transfer asset when proxy is funded ///@param _asset asset address ///@param _recipient user address ///@param _amount number of token function transferAsset(address _asset, address _recipient, uint256 _amount) external onlyGovernance { IERC20(_asset).safeTransfer(_recipient, _amount); } ///@notice Called by the governance module in order to update proxy Accounting after rebalancing ///@param _asset asset address ///@param _amount number of token function updateAssetProxyAmount(address _asset, uint256 _amount) external onlyGovernance { proxyAssetAccounting[_asset] = _amount; } ///@notice Called by the governance module in order get all variables for rebalancing in one call /// (save gas) ///@param _asset asset address ///@return RebalanceParam struct with rebalance parameters function getRebalanceParams(address _asset) external view returns (RebalanceParam memory) { return RebalanceParam( _asset, totalAssetAccounting[_asset], proxyAssetAccounting[_asset], getQuote(_asset, 1e18), 0, 1e18 * protocolData.aum / totalSupply ); } function getQuote(address _asset, uint256 _amount) public view virtual returns (uint256); modifier onlyGovernance() { if (msg.sender != address(GOVERNANCE_MODULE)) revert Unauthorized(); _; } }
// 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 {AssetInfo} from "../core/Structs.sol"; interface IOracle { function getPriceInUSD(address, AssetInfo calldata) external view returns (uint256); function getGweiPrice() external view returns (uint256); }
// SPDX-License-Identifier: UNLICENSED pragma solidity 0.8.19; import {RequestData, UserRequest} from "../core/Structs.sol"; interface IRelayer { function getNumPendingRequest() external view returns (uint256); function getRequest(uint64 idx) external view returns (RequestData memory); function requestGovernanceWithdraw( UserRequest memory _userRequest, address _user, uint256 _maxTRSYToPay ) external payable; function requestWithdraw(UserRequest[] memory _userRequest, uint256 _maxTRSYToPay) external payable; function requestDeposit( UserRequest[] memory _userRequest, bool _keepGovRights, uint256 _minTRSYExpected ) external payable; function requestSwap( address _assetIn, uint256 _amountIn, address _assetOut, uint256 _minAmountOut ) external payable; function processRequests(uint256 _protocolAUM) external; function isQuarantined(address _asset) external view returns (bool); function isIncentiveManager(address _incentiveManager) external view returns (bool); function MAX_ASSET_TO_REQUEST() external view returns (uint8); function actionToGasUsage(bytes32 _actionHash) external view returns (uint256); function isUser(address _asset) external view returns (bool); function isAnyQuarantined(address[] memory _assets) external view returns (address); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Modern and gas efficient ERC20 + EIP-2612 implementation. /// @author Solmate (https://github.com/transmissions11/solmate/blob/main/src/tokens/ERC20.sol) /// @author Modified from Uniswap (https://github.com/Uniswap/uniswap-v2-core/blob/master/contracts/UniswapV2ERC20.sol) /// @dev Do not manually set balances without updating totalSupply, as the sum of all user balances must not exceed it. abstract contract ERC20 { /*////////////////////////////////////////////////////////////// EVENTS //////////////////////////////////////////////////////////////*/ event Transfer(address indexed from, address indexed to, uint256 amount); event Approval(address indexed owner, address indexed spender, uint256 amount); /*////////////////////////////////////////////////////////////// METADATA STORAGE //////////////////////////////////////////////////////////////*/ string public name; string public symbol; uint8 public immutable decimals; /*////////////////////////////////////////////////////////////// ERC20 STORAGE //////////////////////////////////////////////////////////////*/ uint256 public totalSupply; mapping(address => uint256) public balanceOf; mapping(address => mapping(address => uint256)) public allowance; /*////////////////////////////////////////////////////////////// EIP-2612 STORAGE //////////////////////////////////////////////////////////////*/ uint256 internal immutable INITIAL_CHAIN_ID; bytes32 internal immutable INITIAL_DOMAIN_SEPARATOR; mapping(address => uint256) public nonces; /*////////////////////////////////////////////////////////////// CONSTRUCTOR //////////////////////////////////////////////////////////////*/ constructor( string memory _name, string memory _symbol, uint8 _decimals ) { name = _name; symbol = _symbol; decimals = _decimals; INITIAL_CHAIN_ID = block.chainid; INITIAL_DOMAIN_SEPARATOR = computeDomainSeparator(); } /*////////////////////////////////////////////////////////////// ERC20 LOGIC //////////////////////////////////////////////////////////////*/ function approve(address spender, uint256 amount) public virtual returns (bool) { allowance[msg.sender][spender] = amount; emit Approval(msg.sender, spender, amount); return true; } function transfer(address to, uint256 amount) public virtual returns (bool) { balanceOf[msg.sender] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(msg.sender, to, amount); return true; } function transferFrom( address from, address to, uint256 amount ) public virtual returns (bool) { uint256 allowed = allowance[from][msg.sender]; // Saves gas for limited approvals. if (allowed != type(uint256).max) allowance[from][msg.sender] = allowed - amount; balanceOf[from] -= amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(from, to, amount); return true; } /*////////////////////////////////////////////////////////////// EIP-2612 LOGIC //////////////////////////////////////////////////////////////*/ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual { require(deadline >= block.timestamp, "PERMIT_DEADLINE_EXPIRED"); // Unchecked because the only math done is incrementing // the owner's nonce which cannot realistically overflow. unchecked { address recoveredAddress = ecrecover( keccak256( abi.encodePacked( "\x19\x01", DOMAIN_SEPARATOR(), keccak256( abi.encode( keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ), owner, spender, value, nonces[owner]++, deadline ) ) ) ), v, r, s ); require(recoveredAddress != address(0) && recoveredAddress == owner, "INVALID_SIGNER"); allowance[recoveredAddress][spender] = value; } emit Approval(owner, spender, value); } function DOMAIN_SEPARATOR() public view virtual returns (bytes32) { return block.chainid == INITIAL_CHAIN_ID ? INITIAL_DOMAIN_SEPARATOR : computeDomainSeparator(); } function computeDomainSeparator() internal view virtual returns (bytes32) { return keccak256( abi.encode( keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"), keccak256(bytes(name)), keccak256("1"), block.chainid, address(this) ) ); } /*////////////////////////////////////////////////////////////// INTERNAL MINT/BURN LOGIC //////////////////////////////////////////////////////////////*/ function _mint(address to, uint256 amount) internal virtual { totalSupply += amount; // Cannot overflow because the sum of all user // balances can't exceed the max uint256 value. unchecked { balanceOf[to] += amount; } emit Transfer(address(0), to, amount); } function _burn(address from, uint256 amount) internal virtual { balanceOf[from] -= amount; // Cannot underflow because a user's balance // will never be larger than the total supply. unchecked { totalSupply -= amount; } emit Transfer(from, address(0), amount); } }
// SPDX-License-Identifier: BUSL-1.1 pragma solidity 0.8.19; abstract contract BaseChecker { error ZeroParameter(); error InconsistentLengths(); function _checkZeroValue(uint256 val) internal pure { if (val == 0) revert ZeroParameter(); } function _checkZeroAddress(address addr) internal pure { if (addr == address(0x0)) revert ZeroParameter(); } function _checkForConsistentLength(address[] memory arr1, uint256[] memory arr2) internal pure { if (arr1.length != arr2.length) revert InconsistentLengths(); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Pool state that never changes /// @notice These parameters are fixed for a pool forever, i.e., the methods will always return the same values interface IUniswapV3PoolImmutables { /// @notice The contract that deployed the pool, which must adhere to the IUniswapV3Factory interface /// @return The contract address function factory() external view returns (address); /// @notice The first of the two tokens of the pool, sorted by address /// @return The token contract address function token0() external view returns (address); /// @notice The second of the two tokens of the pool, sorted by address /// @return The token contract address function token1() external view returns (address); /// @notice The pool's fee in hundredths of a bip, i.e. 1e-6 /// @return The fee function fee() external view returns (uint24); /// @notice The pool tick spacing /// @dev Ticks can only be used at multiples of this value, minimum of 1 and always positive /// e.g.: a tickSpacing of 3 means ticks can be initialized every 3rd tick, i.e., ..., -6, -3, 0, 3, 6, ... /// This value is an int24 to avoid casting even though it is always positive. /// @return The tick spacing function tickSpacing() external view returns (int24); /// @notice The maximum amount of position liquidity that can use any tick in the range /// @dev This parameter is enforced per tick to prevent liquidity from overflowing a uint128 at any point, and /// also prevents out-of-range liquidity from being used to prevent adding in-range liquidity to a pool /// @return The max amount of liquidity per tick function maxLiquidityPerTick() external view returns (uint128); }
// 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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) pragma solidity 0.8.19; /** * @dev Standard math utilities missing in the Solidity language. */ library MathUtil { /** * @dev Returns the largest of two numbers. */ function max(int256 a, int256 b) internal pure returns (int256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(int256 a, int256 b) internal pure returns (int256) { return a < b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * Utilities that convert numeric types avoiding silent overflows. */ import "./SafeCast/SafeCastU32.sol"; import "./SafeCast/SafeCastI32.sol"; import "./SafeCast/SafeCastI24.sol"; import "./SafeCast/SafeCastU56.sol"; import "./SafeCast/SafeCastI56.sol"; import "./SafeCast/SafeCastU64.sol"; import "./SafeCast/SafeCastI128.sol"; import "./SafeCast/SafeCastI256.sol"; import "./SafeCast/SafeCastU128.sol"; import "./SafeCast/SafeCastU160.sol"; import "./SafeCast/SafeCastU256.sol"; import "./SafeCast/SafeCastAddress.sol"; import "./SafeCast/SafeCastBytes32.sol";
// 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); } } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastU32 { error OverflowUint32ToInt32(); function toInt(uint32 x) internal pure returns (int32) { // -------------------------------o=========>---------------------- // ----------------------<========o========>x---------------------- if (x > uint32(type(int32).max)) { revert OverflowUint32ToInt32(); } return int32(x); } function to256(uint32 x) internal pure returns (uint256) { return uint256(x); } function to56(uint32 x) internal pure returns (uint56) { return uint56(x); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastI32 { error OverflowInt32ToUint32(); function toUint(int32 x) internal pure returns (uint32) { // ----------------------<========o========>---------------------- // ----------------------xxxxxxxxxo=========>---------------------- if (x < 0) { revert OverflowInt32ToUint32(); } return uint32(x); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastI24 { function to256(int24 x) internal pure returns (int256) { return int256(x); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastU56 { error OverflowUint56ToInt56(); function toInt(uint56 x) internal pure returns (int56) { // -------------------------------o=========>---------------------- // ----------------------<========o========>x---------------------- if (x > uint56(type(int56).max)) { revert OverflowUint56ToInt56(); } return int56(x); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastI56 { error OverflowInt56ToInt24(); function to24(int56 x) internal pure returns (int24) { // ----------------------<========o========>----------------------- // ----------------------xxx<=====o=====>xxx----------------------- if (x < int(type(int24).min) || x > int(type(int24).max)) { revert OverflowInt56ToInt24(); } return int24(x); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastU64 { error OverflowUint64ToInt64(); function toInt(uint64 x) internal pure returns (int64) { // -------------------------------o=========>---------------------- // ----------------------<========o========>x---------------------- if (x > uint64(type(int64).max)) { revert OverflowUint64ToInt64(); } return int64(x); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastI128 { error OverflowInt128ToUint128(); error OverflowInt128ToInt32(); function toUint(int128 x) internal pure returns (uint128) { // ----------------<==============o==============>----------------- // ----------------xxxxxxxxxxxxxxxo===============>---------------- if (x < 0) { revert OverflowInt128ToUint128(); } return uint128(x); } function to256(int128 x) internal pure returns (int256) { return int256(x); } function to32(int128 x) internal pure returns (int32) { // ----------------<==============o==============>----------------- // ----------------xxxxxxxxxxxx<==o==>xxxxxxxxxxxx----------------- if (x < int(type(int32).min) || x > int(type(int32).max)) { revert OverflowInt128ToInt32(); } return int32(x); } function zero() internal pure returns (int128) { return int128(0); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastI256 { error OverflowInt256ToUint256(); error OverflowInt256ToInt128(); error OverflowInt256ToInt24(); function to128(int256 x) internal pure returns (int128) { // ----<==========================o===========================>---- // ----xxxxxxxxxxxx<==============o==============>xxxxxxxxxxxxx---- if (x < int256(type(int128).min) || x > int256(type(int128).max)) { revert OverflowInt256ToInt128(); } return int128(x); } function to24(int256 x) internal pure returns (int24) { // ----<==========================o===========================>---- // ----xxxxxxxxxxxxxxxxxxxx<======o=======>xxxxxxxxxxxxxxxxxxxx---- if (x < int256(type(int24).min) || x > int256(type(int24).max)) { revert OverflowInt256ToInt24(); } return int24(x); } function toUint(int256 x) internal pure returns (uint256) { // ----<==========================o===========================>---- // ----xxxxxxxxxxxxxxxxxxxxxxxxxxxo===============================> if (x < 0) { revert OverflowInt256ToUint256(); } return uint256(x); } function zero() internal pure returns (int256) { return int256(0); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastU128 { error OverflowUint128ToInt128(); function to256(uint128 x) internal pure returns (uint256) { return uint256(x); } function toInt(uint128 x) internal pure returns (int128) { // -------------------------------o===============>---------------- // ----------------<==============o==============>x---------------- if (x > uint128(type(int128).max)) { revert OverflowUint128ToInt128(); } return int128(x); } function toBytes32(uint128 x) internal pure returns (bytes32) { return bytes32(uint256(x)); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastU160 { function to256(uint160 x) internal pure returns (uint256) { return uint256(x); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastU256 { error OverflowUint256ToUint128(); error OverflowUint256ToInt256(); error OverflowUint256ToUint64(); error OverflowUint256ToUint32(); error OverflowUint256ToUint160(); function to128(uint256 x) internal pure returns (uint128) { // -------------------------------o===============================> // -------------------------------o===============>xxxxxxxxxxxxxxxx if (x > type(uint128).max) { revert OverflowUint256ToUint128(); } return uint128(x); } function to64(uint256 x) internal pure returns (uint64) { // -------------------------------o===============================> // -------------------------------o======>xxxxxxxxxxxxxxxxxxxxxxxxx if (x > type(uint64).max) { revert OverflowUint256ToUint64(); } return uint64(x); } function to32(uint256 x) internal pure returns (uint32) { // -------------------------------o===============================> // -------------------------------o===>xxxxxxxxxxxxxxxxxxxxxxxxxxxx if (x > type(uint32).max) { revert OverflowUint256ToUint32(); } return uint32(x); } function to160(uint256 x) internal pure returns (uint160) { // -------------------------------o===============================> // -------------------------------o==================>xxxxxxxxxxxxx if (x > type(uint160).max) { revert OverflowUint256ToUint160(); } return uint160(x); } function toBytes32(uint256 x) internal pure returns (bytes32) { return bytes32(x); } function toInt(uint256 x) internal pure returns (int256) { // -------------------------------o===============================> // ----<==========================o===========================>xxxx if (x > uint256(type(int256).max)) { revert OverflowUint256ToInt256(); } return int256(x); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastAddress { function toBytes32(address x) internal pure returns (bytes32) { return bytes32(uint256(uint160(x))); } }
//SPDX-License-Identifier: MIT pragma solidity >=0.8.11 <0.9.0; /** * @title See SafeCast.sol. */ library SafeCastBytes32 { function toAddress(bytes32 x) internal pure returns (address) { return address(uint160(uint256(x))); } function toUint(bytes32 x) internal pure returns (uint) { return uint(x); } }
{ "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
[{"inputs":[{"internalType":"address","name":"_relayer","type":"address"},{"internalType":"address","name":"_oracleModule","type":"address"},{"internalType":"address","name":"_governanceModule","type":"address"},{"internalType":"uint16","name":"_maxAumDeviationAllowed","type":"uint16"},{"internalType":"uint72","name":"_taxFactor","type":"uint72"},{"internalType":"uint72","name":"_managementFee","type":"uint72"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetIsQuarantined","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetNotSupported","type":"error"},{"inputs":[],"name":"AssetPriceNotAvailable","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"AssetSupported","type":"error"},{"inputs":[],"name":"AumNotInRange","type":"error"},{"inputs":[],"name":"CoolDownPeriodActive","type":"error"},{"inputs":[],"name":"FydeBalanceInsufficient","type":"error"},{"inputs":[],"name":"InconsistentLengths","type":"error"},{"inputs":[],"name":"InsufficientTRSYBalance","type":"error"},{"inputs":[],"name":"NotNormalized","type":"error"},{"inputs":[],"name":"NotZero","type":"error"},{"inputs":[],"name":"OnlyOneUpdatePerBlock","type":"error"},{"inputs":[],"name":"OverflowInt256ToUint256","type":"error"},{"inputs":[],"name":"OverflowUint256ToInt256","type":"error"},{"inputs":[],"name":"PoolNotValid","type":"error"},{"inputs":[],"name":"SlippageExceed","type":"error"},{"inputs":[],"name":"SwapAmountNotAvailable","type":"error"},{"inputs":[{"internalType":"address","name":"asset","type":"address"}],"name":"SwapDisabled","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"ValueOutOfBounds","type":"error"},{"inputs":[],"name":"ZeroParameter","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"_asset","type":"address"}],"name":"AssetAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"}],"name":"AssetRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"requestId","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"trsyPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdDepositValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"trsyMinted","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recipient","type":"address"},{"indexed":false,"internalType":"uint256","name":"trsyFeesCollected","type":"uint256"}],"name":"FeesCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"int72","name":"incentiveFactor","type":"int72"}],"name":"IncentiveFactorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"feeToMint","type":"uint256"}],"name":"ManagementFeeCollected","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint72","name":"","type":"uint72"}],"name":"ManagementFeeUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"","type":"uint16"}],"name":"MaxAumDeviationAllowedUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"oracleModule","type":"address"}],"name":"OracleModuleUpdated","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":"","type":"uint256"}],"name":"ProtocolAumUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"requestId","type":"uint32"},{"indexed":false,"internalType":"address","name":"assetOut","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[],"name":"TargetConcentrationsUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint72","name":"","type":"uint72"}],"name":"TaxFactorUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"asset","type":"address"},{"indexed":false,"internalType":"address","name":"uniswapPool","type":"address"}],"name":"UniswapPoolUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"requestId","type":"uint32"},{"indexed":false,"internalType":"uint256","name":"trsyPrice","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"usdWithdrawValue","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"trsyBurned","type":"uint256"}],"name":"Withdraw","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GOVERNANCE_MODULE","outputs":[{"internalType":"contract IGovernanceModule","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RELAYER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assets","type":"address[]"},{"internalType":"address[]","name":"_uniswapPools","type":"address[]"}],"name":"addAssets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"assetInfo","outputs":[{"internalType":"uint72","name":"targetConcentration","type":"uint72"},{"internalType":"address","name":"uniswapPool","type":"address"},{"internalType":"int72","name":"incentiveFactor","type":"int72"},{"internalType":"uint8","name":"assetDecimals","type":"uint8"},{"internalType":"uint8","name":"quoteTokenDecimals","type":"uint8"},{"internalType":"address","name":"uniswapQuoteToken","type":"address"},{"internalType":"bool","name":"isSupported","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"assetsList","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelTransferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"collectFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"collectManagementFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"computeProtocolAUM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getAssetAUM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getAssetDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAssetsListLength","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"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"}],"internalType":"struct RequestData","name":"_req","type":"tuple"},{"internalType":"uint256","name":"_protocolAUM","type":"uint256"}],"name":"getProcessParamDeposit","outputs":[{"components":[{"internalType":"uint256","name":"targetConc","type":"uint256"},{"internalType":"uint256","name":"currentConc","type":"uint256"},{"internalType":"uint256","name":"usdValue","type":"uint256"},{"internalType":"uint256","name":"taxableAmount","type":"uint256"},{"internalType":"uint256","name":"taxInUSD","type":"uint256"},{"internalType":"uint256","name":"sharesBeforeTax","type":"uint256"},{"internalType":"uint256","name":"sharesAfterTax","type":"uint256"}],"internalType":"struct ProcessParam[]","name":"processParam","type":"tuple[]"},{"internalType":"uint256","name":"sharesToMint","type":"uint256"},{"internalType":"uint256","name":"taxInTRSY","type":"uint256"},{"internalType":"uint256","name":"totalUsdDeposit","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"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"}],"internalType":"struct RequestData","name":"_req","type":"tuple"},{"internalType":"uint256","name":"_protocolAUM","type":"uint256"}],"name":"getProcessParamWithdraw","outputs":[{"components":[{"internalType":"uint256","name":"targetConc","type":"uint256"},{"internalType":"uint256","name":"currentConc","type":"uint256"},{"internalType":"uint256","name":"usdValue","type":"uint256"},{"internalType":"uint256","name":"taxableAmount","type":"uint256"},{"internalType":"uint256","name":"taxInUSD","type":"uint256"},{"internalType":"uint256","name":"sharesBeforeTax","type":"uint256"},{"internalType":"uint256","name":"sharesAfterTax","type":"uint256"}],"internalType":"struct ProcessParam[]","name":"processParam","type":"tuple[]"},{"internalType":"uint256","name":"totalSharesToBurn","type":"uint256"},{"internalType":"uint256","name":"sharesToBurnBeforeTax","type":"uint256"},{"internalType":"uint256","name":"taxInTRSY","type":"uint256"},{"internalType":"uint256","name":"totalUsdWithdraw","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getProtocolAUM","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"getQuote","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"getRebalanceParams","outputs":[{"components":[{"internalType":"address","name":"asset","type":"address"},{"internalType":"uint256","name":"assetTotalAmount","type":"uint256"},{"internalType":"uint256","name":"assetProxyAmount","type":"uint256"},{"internalType":"uint256","name":"assetPrice","type":"uint256"},{"internalType":"uint256","name":"sTrsyTotalSupply","type":"uint256"},{"internalType":"uint256","name":"trsyPrice","type":"uint256"}],"internalType":"struct RebalanceParam","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_assetIn","type":"address"},{"internalType":"uint256","name":"_amountIn","type":"uint256"},{"internalType":"address","name":"_assetOut","type":"address"},{"internalType":"uint256","name":"_protocolAUM","type":"uint256"}],"name":"getSwapAmountOut","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incentiveCap","outputs":[{"internalType":"int128","name":"","type":"int128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assets","type":"address[]"}],"name":"isAnyNotSupported","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_assets","type":"address[]"}],"name":"isSwapAllowed","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastIncentiveUpdateBlock","outputs":[{"internalType":"uint128","name":"","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_protocolAUM","type":"uint256"},{"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"}],"internalType":"struct RequestData","name":"_req","type":"tuple"}],"name":"processDeposit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_protocolAUM","type":"uint256"},{"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"}],"internalType":"struct RequestData","name":"_req","type":"tuple"}],"name":"processSwap","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_protocolAUM","type":"uint256"},{"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"}],"internalType":"struct RequestData","name":"_req","type":"tuple"}],"name":"processWithdraw","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"protocolData","outputs":[{"internalType":"uint256","name":"aum","type":"uint256"},{"internalType":"uint72","name":"taxFactor","type":"uint72"},{"internalType":"uint16","name":"maxAumDeviationAllowed","type":"uint16"},{"internalType":"uint48","name":"lastAUMUpdateBlock","type":"uint48"},{"internalType":"uint72","name":"managementFee","type":"uint72"},{"internalType":"uint48","name":"lastFeeCollectionTime","type":"uint48"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"proxyAssetAccounting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_assetIdx","type":"uint256"}],"name":"removeAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"int128","name":"_incentiveCap","type":"int128"}],"name":"setIncentiveCap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"int72","name":"_incentiveFactor","type":"int72"}],"name":"setIncentiveFactor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oracle","type":"address"}],"name":"setOracleModule","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_relayer","type":"address"}],"name":"setRelayer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint72[]","name":"_targetConcentrations","type":"uint72[]"}],"name":"setTargetConcentrations","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"address","name":"_uniswapPool","type":"address"}],"name":"setUniswapPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"}],"name":"standardAssetAccounting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"totalAssetAccounting","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferAsset","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_asset","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"updateAssetProxyAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint72","name":"_annualFee","type":"uint72"}],"name":"updateManagementFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"threshold","type":"uint16"}],"name":"updateMaxAumDeviationAllowed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_aum","type":"uint256"}],"name":"updateProtocolAUM","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint72","name":"_taxFactor","type":"uint72"}],"name":"updateTaxFactor","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101006040523480156200001257600080fd5b506040516200660e3803806200660e83398101604081905262000035916200047a565b838633604051806040016040528060048152602001635452535960e01b815250604051806040016040528060048152602001635452535960e01b81525060128260009081620000859190620005a8565b506001620000948382620005a8565b5060ff81166080524660a052620000aa62000183565b60c0525050600680546001600160a01b0319166001600160a01b0384169081179091556040519091506000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3506001600160a01b0391821660e052600980549183166001600160a01b031992831617905560088054928816929091169190911790556200013c836200021f565b6200014782620002df565b62000152816200038d565b62000177600b80546001600160d01b0316600160d01b4265ffffffffffff1602179055565b505050505050620006f2565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051620001b7919062000674565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6006546001600160a01b031633146200024a576040516282b42960e81b815260040160405180910390fd5b600a8161ffff1610806200026357506101f48161ffff16115b156200028257604051636d4d4a6760e11b815260040160405180910390fd5b600b805461ffff60481b1916690100000000000000000061ffff8416908102919091179091556040519081527fd08c1bc3993b0af9ff782c23b664467f9c10136abbd2f03262557fc2abde0f55906020015b60405180910390a150565b6006546001600160a01b031633146200030a576040516282b42960e81b815260040160405180910390fd5b68056bc75e2d63100000816001600160481b031611156200033e57604051636d4d4a6760e11b815260040160405180910390fd5b600b80546001600160481b0319166001600160481b0383169081179091556040519081527ff036cc909a40e5a5297fc43a607fba898d621fe78a6153d56c6bf249ce92dee490602001620002d4565b6006546001600160a01b03163314620003b8576040516282b42960e81b815260040160405180910390fd5b66b1a2bc2ec50000816001600160481b03161115620003ea57604051636d4d4a6760e11b815260040160405180910390fd5b600b8054600160881b600160d01b031916600160881b6001600160481b038416908102919091179091556040519081527f40ecaade69bfd8d44b55fee3f7dc31cdb78157320c6ba966c032db84bd85586090602001620002d4565b80516001600160a01b03811681146200045d57600080fd5b919050565b80516001600160481b03811681146200045d57600080fd5b60008060008060008060c087890312156200049457600080fd5b6200049f8762000445565b9550620004af6020880162000445565b9450620004bf6040880162000445565b9350606087015161ffff81168114620004d757600080fd5b9250620004e76080880162000462565b9150620004f760a0880162000462565b90509295509295509295565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200052e57607f821691505b6020821081036200054f57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620005a357600081815260208120601f850160051c810160208610156200057e5750805b601f850160051c820191505b818110156200059f578281556001016200058a565b5050505b505050565b81516001600160401b03811115620005c457620005c462000503565b620005dc81620005d5845462000519565b8462000555565b602080601f831160018114620006145760008415620005fb5750858301515b600019600386901b1c1916600185901b1785556200059f565b600085815260208120601f198616915b82811015620006455788860151825594840194600190910190840162000624565b5085821015620006645787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b6000808354620006848162000519565b600182811680156200069f5760018114620006b557620006e6565b60ff1984168752821515830287019450620006e6565b8760005260208060002060005b85811015620006dd5781548a820152908401908201620006c2565b50505082870194505b50929695505050505050565b60805160a05160c05160e051615eb86200075660003960008181610457015281816116500152818161191501528181613aa101528181613c8a0152818161439a015261444f01526000611623015260006115ee015260006104ef0152615eb86000f3fe608060405234801561001057600080fd5b50600436106103995760003560e01c806382c0ab21116101e9578063cc88688b1161010f578063e787caa4116100ad578063f2fde38b1161007c578063f2fde38b14610a0c578063f58f951014610a1f578063f6fabac614610a47578063fdc5a0fe14610a6757600080fd5b8063e787caa4146109c0578063eb95c56c146109d3578063ec2a0992146109e6578063f14f58f1146109f957600080fd5b8063db10e60f116100e9578063db10e60f1461095c578063dd62ed3e1461096f578063e02ff0541461099a578063e30c3978146109ad57600080fd5b8063cc88688b146108a2578063d505accf146108b5578063d7691f8f146108c857600080fd5b80639622c75611610187578063a9059cbb11610156578063a9059cbb14610806578063aeabb17f14610819578063b023c8651461082c578063c76ece881461088f57600080fd5b80639622c756146107915780639c016ffd146107b55780639efd6f72146107bd578063a033fcd4146107f357600080fd5b80638be859ec116101c35780638be859ec146107665780638da5cb5b1461076e57806392fede001461078157806395d89b411461078957600080fd5b806382c0ab211461068257806383307f43146106955780638b0dcb4e1461069d57600080fd5b80633745a192116102ce57806371e85c411161026c5780637bcbb1dd1161023b5780637bcbb1dd146106295780637d43447e1461063c5780637ebcf3bf1461064f5780637ecebe001461066257600080fd5b806371e85c41146105e85780637494e604146105fb57806379ba50971461060e5780637acab86e1461061657600080fd5b80636548e9bc116102a85780636548e9bc1461058f578063683ab4a9146105a25780636ede2988146105b557806370a08231146105c857600080fd5b80633745a1921461053e578063439e2e451461056957806352e49dd91461057c57600080fd5b806323b872dd1161033b5780632efda2bc116103155780632efda2bc146104ca578063313ce567146104ea57806335dda72f146105235780633644e5151461053657600080fd5b806323b872dd146104915780632483e715146104a45780632d58fd75146104b757600080fd5b8063095ea7b311610377578063095ea7b3146103f5578063154bb43c1461041857806318160ddd1461043b5780631a366bb71461045257600080fd5b806302e43cbc1461039e5780630505af94146103b357806306fdde03146103e0575b600080fd5b6103b16103ac366004614ffb565b610a6f565b005b600f80546103c891600160801b909104900b81565b604051600f9190910b81526020015b60405180910390f35b6103e8610b2d565b6040516103d79190615048565b6104086104033660046150a0565b610bbb565b60405190151581526020016103d7565b61042b610426366004615350565b610c28565b6040516103d7949392919061540d565b61044460025481565b6040519081526020016103d7565b6104797f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016103d7565b61040861049f36600461543c565b610f6d565b600954610479906001600160a01b031681565b6104446104c5366004615496565b61104d565b6104446104d83660046154dc565b600c6020526000908152604090205481565b6105117f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff90911681526020016103d7565b6103b16105313660046154f9565b611306565b6104446115ea565b600f54610551906001600160801b031681565b6040516001600160801b0390911681526020016103d7565b6103b161057736600461543c565b611645565b6103b161058a366004615532565b6116a6565b6103b161059d3660046154dc565b61175c565b6103b16105b036600461559a565b6117a8565b6103b16105c3366004615605565b61186a565b6104446105d63660046154dc565b60036020526000908152604090205481565b6104796105f6366004615628565b6118e0565b6103b16106093660046150a0565b61190a565b6103b161196e565b610444610624366004615496565b6119f5565b6103b1610637366004615641565b611eba565b61044461064a366004615496565b612039565b6103b161065d366004614ffb565b61221d565b6104446106703660046154dc565b60056020526000908152604090205481565b6104446106903660046150a0565b6122ca565b6104446123f6565b61070f6106ab3660046154dc565b601060205260009081526040902080546001909101546001600160481b038216916001600160a01b03600160481b91829004811692600881900b9260ff908204811692600160501b8304821692600160581b810490911691600160f81b9091041687565b604080516001600160481b0390981688526001600160a01b03968716602089015260089590950b9487019490945260ff9283166060870152911660808501529190911660a0830152151560c082015260e0016103d7565b600a54610444565b600654610479906001600160a01b031681565b6103b16124fd565b6103e8612571565b6107a461079f366004615676565b61257e565b6040516103d79594939291906156ab565b6103b1612850565b6105116107cb3660046154dc565b6001600160a01b0316600090815260106020526040902060010154600160481b900460ff1690565b6103b16108013660046150a0565b612941565b6104086108143660046150a0565b612a09565b6104796108273660046156e2565b612a6f565b61083f61083a3660046154dc565b612b09565b6040516103d7919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0918201519181019190915260c00190565b6103b161089d366004615716565b612bd9565b600854610479906001600160a01b031681565b6103b16108c3366004615766565b612d95565b600a54600b5461091291906001600160481b038082169161ffff600160481b8204169165ffffffffffff600160581b8304811692600160881b810490921691600160d01b90041686565b604080519687526001600160481b03958616602088015261ffff9094169386019390935265ffffffffffff91821660608601529290921660808401521660a082015260c0016103d7565b61047961096a3660046156e2565b612fde565b61044461097d3660046154f9565b600460209081526000928352604080842090915290825290205481565b6104446109a83660046154dc565b613062565b600754610479906001600160a01b031681565b6103b16109ce366004615628565b613090565b6104446109e13660046154dc565b613141565b6103b16109f43660046154dc565b613165565b6103b1610a07366004615628565b6131d9565b6103b1610a1a3660046154dc565b6133af565b610a32610a2d3660046157d7565b613425565b604080519283526020830191909152016103d7565b610444610a553660046154dc565b600d6020526000908152604090205481565b600e54610444565b6006546001600160a01b03163314610a99576040516282b42960e81b815260040160405180910390fd5b66b1a2bc2ec50000816001600160481b03161115610aca57604051636d4d4a6760e11b815260040160405180910390fd5b600b805468ffffffffffffffffff60881b1916600160881b6001600160481b038416908102919091179091556040519081527f40ecaade69bfd8d44b55fee3f7dc31cdb78157320c6ba966c032db84bd855860906020015b60405180910390a150565b60008054610b3a9061581f565b80601f0160208091040260200160405190810160405280929190818152602001828054610b669061581f565b8015610bb35780601f10610b8857610100808354040283529160200191610bb3565b820191906000526020600020905b815481529060010190602001808311610b9657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610c169086815260200190565b60405180910390a35060015b92915050565b606060008060008560400151516001600160401b03811115610c4c57610c4c6150cc565b604051908082528060200260200182016040528015610c8557816020015b610c72614fbe565b815260200190600190039081610c6a5790505b50935060005b866040015151811015610e04576000610cde88604001518381518110610cb357610cb3615853565b602002602001015189606001518481518110610cd157610cd1615853565b60200260200101516122ca565b905080600003610d015760405163e49d3ed160e01b815260040160405180910390fd5b6040518060e00160405280601060008b604001518681518110610d2657610d26615853565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060000160009054906101000a90046001600160481b03166001600160481b03168152602001610d9a8a604001518581518110610d8c57610d8c615853565b60200260200101518a613601565b81526020018281526020016000815260200160008152602001610dbd838a61364c565b81526020016000815250868381518110610dd957610dd9615853565b6020908102919091010152610dee818461587f565b9250508080610dfc90615892565b915050610c8b565b5060005b8451811015610f6357610e46858281518110610e2657610e26615853565b6020908102919091010151600b54889085906001600160481b031661367c565b858281518110610e5857610e58615853565b6020026020010181905250610eb2858281518110610e7857610e78615853565b602002602001015160800151868381518110610e9657610e96615853565b602002602001015160400151610eac91906158ab565b8761364c565b858281518110610ec457610ec4615853565b602002602001015160c0018181525050848181518110610ee657610ee6615853565b602002602001015160c0015184610efd919061587f565b9350848181518110610f1157610f11615853565b602002602001015160c00151858281518110610f2f57610f2f615853565b602002602001015160a00151610f4591906158ab565b610f4f908461587f565b925080610f5b81615892565b915050610e08565b5092959194509250565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610fc957610fa483826158ab565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610ff19084906158ab565b90915550506001600160a01b0380851660008181526003602052604090819020805487019055519091871690600080516020615e638339815191529061103a9087815260200190565b60405180910390a3506001949350505050565b6009546000906001600160a01b0316331461107a576040516282b42960e81b815260040160405180910390fd5b6110c161108a60408401846158be565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506136d992505050565b6111086110d160408401846158be565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061371992505050565b6000611113846137c0565b50905080611134576040516374b3e54160e01b815260040160405180910390fd5b600080808061114b61114588615907565b89610c28565b9350935093509350828760e00135111561117857604051635b688e4760e01b815260040160405180910390fd5b60005b61118860408901896158be565b90508110156112215761120f6111a460408a0160208b016154dc565b306111b260608c018c6158be565b858181106111c2576111c2615853565b905060200201358b80604001906111d991906158be565b868181106111e9576111e9615853565b90506020020160208101906111fe91906154dc565b6001600160a01b031692919061382f565b8061121981615892565b91505061117b565b5061123260e0880160c08901615913565b156112465761124187856138a0565b611250565b6112508784613cb8565b8115611260576112603083613d1c565b61127261126d828a61587f565b613d76565b600254600090611282838b61587f565b61129490670de0b6b3a7640000615930565b61129e919061595d565b90507f27bd68e1c50cdd7ad817c783781d4ff30255bc19b0f9b1eb3477892bc9e38d386112ce60208a018a615971565b6040805163ffffffff90921682526020820184905281018490526060810186905260800160405180910390a150979650505050505050565b6006546001600160a01b03163314611330576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811661137c576001600160a01b0380831660009081526010602052604090208054918316600160481b02600160481b600160e81b03199092169190911790556115a5565b6000816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e0919061598c565b90506000826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611422573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611446919061598c565b90506000846001600160a01b0316836001600160a01b03160361146a5750806114a3565b846001600160a01b0316826001600160a01b03160361148a5750816114a3565b60405163d35a91cf60e01b815260040160405180910390fd5b6001600160a01b038581166000908152601060209081526040918290208054600160481b600160e81b031916600160481b8986160217815560010180547fff0000000000000000000000000000000000000000ffffffffffffffffffffff16600160581b948616948502179055815163313ce56760e01b8152915163313ce5679260048082019392918290030181865afa158015611545573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156991906159a9565b6001600160a01b0386166000908152601060205260409020600101805460ff92909216600160501b0260ff60501b199092169190911790555050505b6040516001600160a01b0382811682528316907ff09d9fda2e96eeb85eacfdc7def084e286e39b2c8dab78b35221f9a5e2502cb4906020015b60405180910390a25050565b60007f000000000000000000000000000000000000000000000000000000000000000046146116205761161b613dab565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461168d576040516282b42960e81b815260040160405180910390fd5b6116a16001600160a01b0384168383613e45565b505050565b6006546001600160a01b031633146116d0576040516282b42960e81b815260040160405180910390fd5b600a8161ffff1610806116e857506101f48161ffff16115b1561170657604051636d4d4a6760e11b815260040160405180910390fd5b600b80546affff0000000000000000001916600160481b61ffff8416908102919091179091556040519081527fd08c1bc3993b0af9ff782c23b664467f9c10136abbd2f03262557fc2abde0f5590602001610b22565b6006546001600160a01b03163314611786576040516282b42960e81b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6006546001600160a01b031633146117d2576040516282b42960e81b815260040160405180910390fd5b8281146117f25760405163b1f40f7760e01b815260040160405180910390fd5b60005b838110156118635761185385858381811061181257611812615853565b905060200201602081019061182791906154dc565b84848481811061183957611839615853565b905060200201602081019061184e91906154dc565b613e75565b61185c81615892565b90506117f5565b5050505050565b6006546001600160a01b03163314611894576040516282b42960e81b815260040160405180910390fd5b68056bc75e2d6310000081600f0b13156118c157604051636d4d4a6760e11b815260040160405180910390fd5b600f80546001600160801b03928316600160801b029216919091179055565b600e81815481106118f057600080fd5b6000918252602090912001546001600160a01b0316905081565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614611952576040516282b42960e81b815260040160405180910390fd5b6001600160a01b039091166000908152600d6020526040902055565b6007546001600160a01b03163314611998576040516282b42960e81b815260040160405180910390fd5b60068054600780546001600160a01b03198084166001600160a01b038381169182179096559116909155604051929091169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6009546000906001600160a01b03163314611a22576040516282b42960e81b815260040160405180910390fd5b611a3261108a60408401846158be565b611a4261108a60808401846158be565b611a526110d160408401846158be565b611a626110d160808401846158be565b611aa9611a7260408401846158be565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061401c92505050565b611ab9611a7260808401846158be565b6000611ac4846137c0565b50905080611ae5576040516374b3e54160e01b815260040160405180910390fd5b600080611b7f611af860408701876158be565b6000818110611b0957611b09615853565b9050602002016020810190611b1e91906154dc565b611b2b60608801886158be565b6000818110611b3c57611b3c615853565b90506020020135878060800190611b5391906158be565b6000818110611b6457611b64615853565b9050602002016020810190611b7991906154dc565b89613425565b9150915081600003611ba45760405163c573eaa560e01b815260040160405180910390fd5b8460e00135821015611bc957604051635b688e4760e01b815260040160405180910390fd5b81611c00611bda60808801886158be565b6000818110611beb57611beb615853565b90506020020160208101906109a891906154dc565b1015611c1f576040516336eefe3560e01b815260040160405180910390fd5b600080821315611c4d57611c33828861587f565b9050611c4830611c43848a61364c565b613d1c565b611ccb565b6000821215611cc857611c5f826159c6565b611c6990886158ab565b90506000611c7f611c79846159c6565b8961364c565b30600090815260036020526040902054909150811115611cae5730600090815260036020526040902054611cb0565b805b90508015611cc257611cc2308261405c565b50611ccb565b50855b611cd481613d76565b611d34611ce460408801886158be565b6000818110611cf557611cf5615853565b9050602002016020810190611d0a91906154dc565b611d1760608901896158be565b6000818110611d2857611d28615853565b905060200201356140be565b611d70611d4460808801886158be565b6000818110611d5557611d55615853565b9050602002016020810190611d6a91906154dc565b846140ef565b611dca611d8360408801602089016154dc565b30611d9160608a018a6158be565b6000818110611da257611da2615853565b90506020020135898060400190611db991906158be565b60008181106111e9576111e9615853565b611e21611ddd60408801602089016154dc565b84611deb60808a018a6158be565b6000818110611dfc57611dfc615853565b9050602002016020810190611e1191906154dc565b6001600160a01b03169190613e45565b7fc84ce3ed8ab6ac38b6355da334b0da7d1c924c8b5d0e83d53d6883f2be0fcce8611e4f6020880188615971565b611e5c60808901896158be565b6000818110611e6d57611e6d615853565b9050602002016020810190611e8291906154dc565b6040805163ffffffff90931683526001600160a01b039091166020830152810185905260600160405180910390a15095945050505050565b60095460405163b588c10b60e01b81523360048201526001600160a01b039091169063b588c10b90602401602060405180830381865afa158015611f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2691906159e2565b611f42576040516282b42960e81b815260040160405180910390fd5b600f8054600160801b9004900b600882900b1315611f7357604051636d4d4a6760e11b815260040160405180910390fd5b600f54611f8a906001600160801b0316600561587f565b431015611faa576040516311a3df9560e01b815260040160405180910390fd5b600f80546fffffffffffffffffffffffffffffffff1916436001600160801b03161790556001600160a01b038216600081815260106020908152604091829020600101805468ffffffffffffffffff19166001600160481b0386161790559051600884900b81527f05d3a92f1773bfe6b86e42c45a0bfdf57247864d79797482e71c94f22c8dcb2a91016115de565b6009546000906001600160a01b03163314612066576040516282b42960e81b815260040160405180910390fd5b61207661108a60808401846158be565b6120866110d160808401846158be565b6000612091846137c0565b509050806120b2576040516374b3e54160e01b815260040160405180910390fd5b6000806120c560e0860160c08701615913565b6120d8576120d38686614117565b6120e2565b6120e286866142e7565b909250905061216d6120f760808701876158be565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506121369250505060a08801886158be565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506145a092505050565b61217a61126d83886158ab565b600060025460000361218d5760006121b6565b60025461219a84896158ab565b6121ac90670de0b6b3a7640000615930565b6121b6919061595d565b90507f90b5f7dd30f1e6716a37f642aab9e2a5a1216c72e1044251b59c801e40dba82f6121e66020880188615971565b6040805163ffffffff90921682526020820184905281018590526060810184905260800160405180910390a1509095945050505050565b6006546001600160a01b03163314612247576040516282b42960e81b815260040160405180910390fd5b68056bc75e2d63100000816001600160481b0316111561227a57604051636d4d4a6760e11b815260040160405180910390fd5b600b805468ffffffffffffffffff19166001600160481b0383169081179091556040519081527ff036cc909a40e5a5297fc43a607fba898d621fe78a6153d56c6bf249ce92dee490602001610b22565b6001600160a01b038281166000908152601060209081526040808320815160e08101835281546001600160481b0381168252600160481b90819004871694820194909452600190910154600881810b8385015293810460ff9081166060840152600160501b820481166080840152600160581b8204871660a0840152600160f81b90910416151560c0820152915490516378c8814f60e11b8152929391928492919091169063f191029e9061238590889086906004016159ff565b602060405180830381865afa1580156123a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c69190615a88565b90508160600151600a6123d99190615b85565b6123e38286615930565b6123ed919061595d565b95945050505050565b6000806000806000600e80548060200260200160405190810160405280929190818152602001828054801561245457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612436575b505083519394506000925050505b818110156124f25782818151811061247c5761247c615853565b60200260200101519550600c6000876001600160a01b03166001600160a01b0316815260200190815260200160002054600003156124e2576124bd86613141565b9350836000036124d5575050600a5495945050505050565b6124df848661587f565b94505b6124eb81615892565b9050612462565b509295945050505050565b6006546001600160a01b03163314612527576040516282b42960e81b815260040160405180910390fd5b6007546040516001600160a01b03909116907f6ecd4842251bedd053b09547c0fabaab9ec98506ebf24469e8dd5560412ed37f90600090a2600780546001600160a01b0319169055565b60018054610b3a9061581f565b6060600080808061259260808801886158be565b90506001600160401b038111156125ab576125ab6150cc565b6040519080825280602002602001820160405280156125e457816020015b6125d1614fbe565b8152602001906001900390816125c95790505b50945060005b6125f760808901896158be565b905081101561278957600061266061261260808b018b6158be565b8481811061262257612622615853565b905060200201602081019061263791906154dc565b61264460a08c018c6158be565b8581811061265457612654615853565b905060200201356122ca565b9050806000036126835760405163e49d3ed160e01b815260040160405180910390fd5b6040805160e0810190915280601060006126a060808e018e6158be565b878181106126b0576126b0615853565b90506020020160208101906126c591906154dc565b6001600160a01b03168152602080820192909252604001600020546001600160481b03168252016127276126fc60808d018d6158be565b8681811061270c5761270c615853565b905060200201602081019061272191906154dc565b8b613601565b8152602001828152602001600081526020016000815260200160008152602001600081525087838151811061275e5761275e615853565b6020908102919091010152612773818461587f565b925050808061278190615892565b9150506125ea565b5060005b855181101561282d576127cb8682815181106127ab576127ab615853565b6020908102919091010151600b54899085906001600160481b03166145fa565b8682815181106127dd576127dd615853565b602002602001018190525061280f8682815181106127fd576127fd615853565b6020026020010151608001518861364c565b612819908461587f565b92508061282581615892565b91505061278d565b50612838818761364c565b9250612844828461587f565b93509295509295909350565b600b54600090612875906301e187e090600160881b90046001600160481b0316615b94565b600b546001600160481b039190911691506000906128a290600160d01b900465ffffffffffff16426158ab565b9050806000036128b0575050565b6000670de0b6b3a764000060025483856128ca9190615930565b6128d49190615930565b6128de919061595d565b600b80546001600160d01b0316600160d01b4265ffffffffffff160217905590506129093082613d1c565b6040518181527f147fac6415bee3006ba6002a9a6636f492d311690c9e52a2421afc6392e0fb959060200160405180910390a1505050565b6006546001600160a01b0316331461296b576040516282b42960e81b815260040160405180910390fd5b6129748261463d565b61297d81614667565b306000908152600360205260408120805483929061299c9084906158ab565b90915550506001600160a01b038216600090815260036020526040812080548392906129c990849061587f565b90915550506040518181526001600160a01b038316907f9dc46f23cfb5ddcad0ae7ea2be38d47fec07bb9382ec7e564efc69e036dd66ce906020016115de565b33600090815260036020526040812080548391908390612a2a9084906158ab565b90915550506001600160a01b03831660008181526003602052604090819020805485019055513390600080516020615e6383398151915290610c169086815260200190565b6000805b8251811015612b005760106000848381518110612a9257612a92615853565b6020908102919091018101516001600160a01b031682528101919091526040016000206001015460080b68056bc75e2d630fffff1903612aee57828181518110612ade57612ade615853565b6020026020010151915050919050565b80612af881615892565b915050612a73565b50600092915050565b612b4b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805160c0810182526001600160a01b0384168082526000818152600c60209081528482205481850152918152600d909152829020549181019190915260608101612b9f84670de0b6b3a76400006122ca565b815260200160008152602001600254600a60000154670de0b6b3a7640000612bc79190615930565b612bd1919061595d565b905292915050565b6006546001600160a01b03163314612c03576040516282b42960e81b815260040160405180910390fd5b600e548114612c255760405163b1f40f7760e01b815260040160405180910390fd5b6000805b82811015612c7657838382818110612c4357612c43615853565b9050602002016020810190612c589190614ffb565b612c629083615bba565b915080612c6e81615892565b915050612c29565b5068056bc75e2fb71be400816001600160481b03161180612ca8575068056bc75e2b0f041c00816001600160481b0316105b15612cc657604051636b522f1160e11b815260040160405180910390fd5b60005b82811015612d6657838382818110612ce357612ce3615853565b9050602002016020810190612cf89190614ffb565b60106000600e8481548110612d0f57612d0f615853565b6000918252602080832091909101546001600160a01b031683528201929092526040019020805468ffffffffffffffffff19166001600160481b039290921691909117905580612d5e81615892565b915050612cc9565b506040517f0f76096615ee194cca6c5e0f25f4a332cbf3aaa195ae55f2cbcb881db1aef18390600090a1505050565b42841015612dea5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064015b60405180910390fd5b60006001612df66115ea565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015612f02573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590612f385750876001600160a01b0316816001600160a01b0316145b612f755760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401612de1565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000805b8251811015612b00576010600084838151811061300157613001615853565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600101601f9054906101000a900460ff1661305057828181518110612ade57612ade615853565b8061305a81615892565b915050612fe2565b6001600160a01b0381166000908152600d6020908152604080832054600c909252822054610c2291906158ab565b6009546001600160a01b031633148015906130b657506006546001600160a01b03163314155b156130d3576040516282b42960e81b815260040160405180910390fd5b600b54600160581b900465ffffffffffff164303613104576040516311a3df9560e01b815260040160405180910390fd5b600b805465ffffffffffff60581b1916600160581b4365ffffffffffff16021790556000613131826137c0565b91505061313d81613d76565b5050565b6001600160a01b0381166000908152600c6020526040812054610c229083906122ca565b6006546001600160a01b0316331461318f576040516282b42960e81b815260040160405180910390fd5b600880546001600160a01b0319166001600160a01b0383169081179091556040517f90f3093aefb44e115f8088a7f69b5f3adf9d7ec6f153ac758de49cfe3c740cd190600090a250565b6006546001600160a01b03163314613203576040516282b42960e81b815260040160405180910390fd5b6000600e828154811061321857613218615853565b60009182526020808320909101546001600160a01b0316808352600c9091526040909120549091501561325d576040516252b55360e31b815260040160405180910390fd5b6001600160a01b0381166000908152601060205260409020546001600160481b03161561329c576040516252b55360e31b815260040160405180910390fd5b6001600160a01b038116600090815260106020526040812080546001600160e81b0319168155600190810191909155600e805490916132da916158ab565b815481106132ea576132ea615853565b600091825260209091200154600e80546001600160a01b03909216918490811061331657613316615853565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600e80548061335557613355615be1565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f37803e2125c48ee96c38ddf04e826daf335b0e1603579040fd275aba6d06b6fc91a25050565b6006546001600160a01b031633146133d9576040516282b42960e81b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b03831690811790915560405133907f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270090600090a350565b600080600061343487876122ca565b6001600160a01b0386166000908152601060205260408120600101549192509061346f90879061069090600160481b900460ff16600a615b85565b905081158061347c575080155b1561348f576000809350935050506135f8565b50506040805160e0810182526001600160a01b038816600090815260106020908152928120546001600160481b031682529181016134cd8987613601565b81526020016134dc89896122ca565b8152600060208083018290526040808401839052606084018390526080909301829052825160e0810184526001600160a01b038a16835260108252928220546001600160481b031683529293509181016135368888613601565b8152600060208083018290526040808401839052606084018390526080840183905260a0909301829052600b546001600160a01b03808e1684526010909252838320600190810154928c1684529383209093015493945090926135b092869286928b926001600160481b031691600890810b91900b614688565b90506135c487670de0b6b3a76400006122ca565b6135d682670de0b6b3a7640000615930565b6135e0919061595d565b8184604001516135f09190615bf7565b945094505050505b94509492505050565b6000811580156136115750600a54155b1561361e57506000610c22565b8161362884613141565b61363b9068056bc75e2d63100000615930565b613645919061595d565b9392505050565b600254600090801561367257826136638286615930565b61366d919061595d565b613674565b835b949350505050565b613684614fbe565b845160000361369e57506040840151608085015283613674565b816000036136ad575083613674565b6136b88585856147e9565b945084606001516000036136cd575083613674565b6123ed858585856148df565b60006136e482612fde565b90506001600160a01b0381161561313d57604051632777a68f60e11b81526001600160a01b0382166004820152602401612de1565b600954604051633e031b6760e21b81526000916001600160a01b03169063f80c6d9c9061374a908590600401615c17565b602060405180830381865afa158015613767573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061378b919061598c565b90506001600160a01b0381161561313d5760405163fc31f2eb60e01b81526001600160a01b0382166004820152602401612de1565b600b54600a546000918291600160481b90910461ffff1690826137e382846149e9565b905060006137f5838561ffff16614a1a565b90508187101561380d57506000969095509350505050565b8087111561382357600097909650945050505050565b50600196945050505050565b6040516001600160a01b038085166024830152831660448201526064810182905261389a9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614a39565b50505050565b60006138af60408401846158be565b90506001600160401b038111156138c8576138c86150cc565b6040519080825280602002602001820160405280156138f1578160200160208202803683370190505b509050600061390360408501856158be565b90506001600160401b0381111561391c5761391c6150cc565b604051908082528060200260200182016040528015613945578160200160208202803683370190505b50905060008060005b61395b60408801886158be565b9050811015613a945785818151811061397657613976615853565b602002602001015160a0015186828151811061399457613994615853565b602002602001015160c00151670de0b6b3a76400006139b39190615930565b6139bd919061595d565b9250670de0b6b3a7640000836139d660608a018a6158be565b848181106139e6576139e6615853565b905060200201356139f79190615930565b613a01919061595d565b848281518110613a1357613a13615853565b602002602001018181525050858181518110613a3157613a31615853565b602002602001015160c00151858281518110613a4f57613a4f615853565b602002602001018181525050848181518110613a6d57613a6d615853565b602002602001015182613a80919061587f565b915080613a8c81615892565b91505061394e565b5060006001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001663c92b75c4613ad660408a0160208b016154dc565b613ae360408b018b6158be565b888a886040518763ffffffff1660e01b8152600401613b0796959493929190615c94565b6020604051808303816000875af1158015613b26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b4a919061598c565b905060005b613b5c60408901896158be565b9050811015613bb557613ba382868381518110613b7b57613b7b615853565b60200260200101518a8060400190613b9391906158be565b85818110611dfc57611dfc615853565b80613bad81615892565b915050613b4f565b50613c3c613bc660408901896158be565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613c059250505060608a018a6158be565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250614b0e92505050565b613c85613c4c60408901896158be565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250889250614b68915050565b613caf7f000000000000000000000000000000000000000000000000000000000000000083613d1c565b50505050505050565b613d07613cc860408401846158be565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613c059250505060608501856158be565b61313d613d1a60408401602085016154dc565b825b8060026000828254613d2e919061587f565b90915550506001600160a01b038216600081815260036020908152604080832080548601905551848152600080516020615e6383398151915291015b60405180910390a35050565b600a8190556040518181527fb4f10f1c952679350ddb7fefb943b40a586171e621e220adfb9ed55f0a643d0f90602001610b22565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051613ddd9190615d21565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6040516001600160a01b0383166024820152604481018290526116a190849063a9059cbb60e01b90606401613863565b6001600160a01b038216600090815260106020526040902060010154600160f81b900460ff1615613ec457604051634f1ac48560e01b81526001600160a01b0383166004820152602401612de1565b6001600160a01b03821660008181526010602090815260409182902060010180546001600160f81b0316600160f81b179055815163313ce56760e01b8152915163313ce5679260048082019392918290030181865afa158015613f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f4f91906159a9565b6001600160a01b0383166000908152601060205260409020600101805460ff92909216600160481b0269ff00000000000000000019909216919091179055613f978282611306565b600e80546001810182556000919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0180546001600160a01b0319166001600160a01b0384169081179091556040519081527f0e3c58ebfb2e7465fbb1c32e6b4f40c3c4f5ca77e8218a386aff8617831260d79060200160405180910390a15050565b600061402782612a6f565b90506001600160a01b0381161561313d576040516303e4acb760e01b81526001600160a01b0382166004820152602401612de1565b6001600160a01b038216600090815260036020526040812080548392906140849084906158ab565b90915550506002805482900390556040518181526000906001600160a01b03841690600080516020615e6383398151915290602001613d6a565b6001600160a01b0382166000908152600c6020526040812080548392906140e690849061587f565b90915550505050565b6001600160a01b0382166000908152600c6020526040812080548392906140e69084906158ab565b60008060005b61412a60808501856158be565b90508110156141ab5761414060a08501856158be565b8281811061415057614150615853565b9050602002013561417a85806080019061416a91906158be565b84818110611beb57611beb615853565b1015614199576040516336eefe3560e01b815260040160405180910390fd5b806141a381615892565b91505061411d565b5060008060006141bb868861257e565b94509450509350508560e001358311156141e857604051635b688e4760e01b815260040160405180910390fd5b82600360006141fd60408a0160208b016154dc565b6001600160a01b03166001600160a01b0316815260200190815260200160002054101561423d57604051637596688560e01b815260040160405180910390fd5b61425661425060408801602089016154dc565b8461405c565b8115614266576142663083613d1c565b60005b61427660808801886158be565b90508110156142d8576142c66142926040890160208a016154dc565b61429f60a08a018a6158be565b848181106142af576142af615853565b90506020020135898060800190613b9391906158be565b806142d081615892565b915050614269565b509350909150505b9250929050565b6000808061433f6142fb60808601866158be565b600081811061430c5761430c615853565b905060200201602081019061432191906154dc565b61432e60a08701876158be565b600081811061265457612654615853565b9050806000036143625760405163e49d3ed160e01b815260040160405180910390fd5b600061436e828761364c565b9050808560e00135101561439557604051635b688e4760e01b815260040160405180910390fd5b6143bf7f00000000000000000000000000000000000000000000000000000000000000008261405c565b6144456143cf60808701876158be565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061440e9250505060a08801886158be565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250614bf392505050565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016639c787c6761448460408801602089016154dc565b61449160808901896158be565b60008181106144a2576144a2615853565b90506020020160208101906144b791906154dc565b6144c460a08a018a6158be565b60008181106144d5576144d5615853565b6040516001600160e01b031960e088901b1681526001600160a01b0395861660048201529490931660248501525060209091020135604482015260648101849052608401600060405180830381600087803b15801561453357600080fd5b505af1158015614547573d6000803e3d6000fd5b50614595925061456091505060408701602088016154dc565b61456d60a08801886158be565b600081811061457e5761457e615853565b90506020020135878060800190611deb91906158be565b909590945092505050565b60005b82518110156116a1576145e88382815181106145c1576145c1615853565b60200260200101518383815181106145db576145db615853565b60200260200101516140ef565b806145f281615892565b9150506145a3565b614602614fbe565b81600003614611575083613674565b61461c858585614c7e565b94508460600151600003614631575083613674565b6123ed85858585614d26565b6001600160a01b0381166146645760405163339d6ef160e21b815260040160405180910390fd5b50565b806000036146645760405163339d6ef160e21b815260040160405180910390fd5b6000614697878660008761367c565b9650600068056bc75e2d63100000886060015189604001516146b991906158ab565b6146c39086615dc0565b6146cd9190615df0565b9050600080821215614710576146ed6146e883600019615dc0565b614e15565b89608001518a6040015161470191906158ab565b61470b91906158ab565b614737565b61471982614e15565b89608001518a6040015161472d91906158ab565b614737919061587f565b60408901819052905061474d88886000896145fa565b9750600068056bc75e2d6310000089606001518361476b91906158ab565b6147759087615dc0565b61477f9190615df0565b90506000808212156147b85761479a6146e883600019615dc0565b60808b01516147a990856158ab565b6147b391906158ab565b6147da565b6147c182614e15565b60808b01516147d090856158ab565b6147da919061587f565b9b9a5050505050505050505050565b6147f1614fbe565b600068056bc75e2d6310000061480a8660000151614e3c565b6148178760200151614e3c565b6148219190615bf7565b61482a86614e3c565b6148349190615dc0565b61483e9190615df0565b9050600083600003614851576000614883565b68056bc75e2d6310000061486485614e3c565b875161486f90614e3c565b6148799190615dc0565b6148839190615df0565b9050600081836148968960400151614e3c565b6148a09190615e1e565b6148aa9190615bf7565b90506148cf6146e86148bf8960400151614e3c565b6148ca846000614e66565b614e7d565b6060880152509495945050505050565b6148e7614fbe565b6000856040015168056bc75e2d631000008760200151876149089190615930565b614912919061595d565b61491c919061587f565b865190915060009068056bc75e2d6310000090614939878961587f565b6149439190615930565b61494d919061595d565b90506000670de0b6b3a7640000826149658583615930565b61496f919061595d565b61497991906158ab565b9050600061498f82670de0b6b3a7640000614e8c565b9050600068056bc75e2d631000006149a78389615930565b6149b1919061595d565b9050670de0b6b3a7640000818b606001516149cc9190615930565b6149d6919061595d565b60808b0152509798975050505050505050565b61271081810390821161138819829004841182021715614a0857600080fd5b61271092026113880191909104919050565b61271081016127101982116113881982900484111715614a0857600080fd5b6000614a8e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614e9b9092919063ffffffff16565b9050805160001480614aaf575080806020019051810190614aaf91906159e2565b6116a15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401612de1565b60005b82518110156116a157614b56838281518110614b2f57614b2f615853565b6020026020010151838381518110614b4957614b49615853565b60200260200101516140be565b80614b6081615892565b915050614b11565b60005b82518110156116a157818181518110614b8657614b86615853565b6020026020010151600d6000858481518110614ba457614ba4615853565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000828254614bdb919061587f565b90915550819050614beb81615892565b915050614b6b565b60005b82518110156116a157818181518110614c1157614c11615853565b6020026020010151600d6000858481518110614c2f57614c2f615853565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000828254614c6691906158ab565b90915550819050614c7681615892565b915050614bf6565b614c86614fbe565b600068056bc75e2d63100000614c9f8660000151614e3c565b614cac8760200151614e3c565b614cb69190615bf7565b614cbf86614e3c565b614cc99190615dc0565b614cd39190615df0565b9050600068056bc75e2d63100000614cea85614e3c565b8751614cf590614e3c565b614cff9190615dc0565b614d099190615df0565b905060008183614d1c8960400151614e3c565b6148a09190615bf7565b614d2e614fbe565b6000614d3d8660400151614e3c565b68056bc75e2d63100000614d548860200151614e3c565b614d5d88614e3c565b614d679190615dc0565b614d719190615df0565b614d7b9190615bf7565b9050600068056bc75e2d63100000614d9286614e3c565b614d9b88614e3c565b614da59190615bf7565b8851614db090614e3c565b614dba9190615dc0565b614dc49190615df0565b9050600081614ddb84670de0b6b3a7640000615dc0565b614de59190615df0565b614df790670de0b6b3a7640000615bf7565b9050600061498f614e0783614e15565b670de0b6b3a7640000614e8c565b600080821215614e385760405163029f024d60e31b815260040160405180910390fd5b5090565b60006001600160ff1b03821115614e385760405163677c430560e11b815260040160405180910390fd5b600081831215614e765781613645565b5090919050565b6000818312614e765781613645565b6000818310614e765781613645565b6060613674848460008585600080866001600160a01b03168587604051614ec29190615e46565b60006040518083038185875af1925050503d8060008114614eff576040519150601f19603f3d011682016040523d82523d6000602084013e614f04565b606091505b5091509150614f1587838387614f20565b979650505050505050565b60608315614f8f578251600003614f88576001600160a01b0385163b614f885760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612de1565b5081613674565b6136748383815115614fa45781518083602001fd5b8060405162461bcd60e51b8152600401612de19190615048565b6040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60006020828403121561500d57600080fd5b81356001600160481b038116811461364557600080fd5b60005b8381101561503f578181015183820152602001615027565b50506000910152565b6020815260008251806020840152615067816040850160208701615024565b601f01601f19169190910160400192915050565b6001600160a01b038116811461466457600080fd5b803561509b8161507b565b919050565b600080604083850312156150b357600080fd5b82356150be8161507b565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405161010081016001600160401b0381118282101715615105576151056150cc565b60405290565b604051601f8201601f191681016001600160401b0381118282101715615133576151336150cc565b604052919050565b803563ffffffff8116811461509b57600080fd5b60006001600160401b03821115615168576151686150cc565b5060051b60200190565b600082601f83011261518357600080fd5b813560206151986151938361514f565b61510b565b82815260059290921b840181019181810190868411156151b757600080fd5b8286015b848110156151db5780356151ce8161507b565b83529183019183016151bb565b509695505050505050565b600082601f8301126151f757600080fd5b813560206152076151938361514f565b82815260059290921b8401810191818101908684111561522657600080fd5b8286015b848110156151db578035835291830191830161522a565b801515811461466457600080fd5b803561509b81615241565b6000610100828403121561526d57600080fd5b6152756150e2565b90506152808261513b565b815261528e60208301615090565b602082015260408201356001600160401b03808211156152ad57600080fd5b6152b985838601615172565b604084015260608401359150808211156152d257600080fd5b6152de858386016151e6565b606084015260808401359150808211156152f757600080fd5b61530385838601615172565b608084015260a084013591508082111561531c57600080fd5b50615329848285016151e6565b60a08301525061533b60c0830161524f565b60c082015260e082013560e082015292915050565b6000806040838503121561536357600080fd5b82356001600160401b0381111561537957600080fd5b6153858582860161525a565b95602094909401359450505050565b600081518084526020808501945080840160005b8381101561540257815180518852838101518489015260408082015190890152606080820151908901526080808201519089015260a0808201519089015260c0908101519088015260e090960195908201906001016153a8565b509495945050505050565b6080815260006154206080830187615394565b6020830195909552506040810192909252606090910152919050565b60008060006060848603121561545157600080fd5b833561545c8161507b565b9250602084013561546c8161507b565b929592945050506040919091013590565b6000610100828403121561549057600080fd5b50919050565b600080604083850312156154a957600080fd5b8235915060208301356001600160401b038111156154c657600080fd5b6154d28582860161547d565b9150509250929050565b6000602082840312156154ee57600080fd5b81356136458161507b565b6000806040838503121561550c57600080fd5b82356155178161507b565b915060208301356155278161507b565b809150509250929050565b60006020828403121561554457600080fd5b813561ffff8116811461364557600080fd5b60008083601f84011261556857600080fd5b5081356001600160401b0381111561557f57600080fd5b6020830191508360208260051b85010111156142e057600080fd5b600080600080604085870312156155b057600080fd5b84356001600160401b03808211156155c757600080fd5b6155d388838901615556565b909650945060208701359150808211156155ec57600080fd5b506155f987828801615556565b95989497509550505050565b60006020828403121561561757600080fd5b813580600f0b811461364557600080fd5b60006020828403121561563a57600080fd5b5035919050565b6000806040838503121561565457600080fd5b823561565f8161507b565b91506020830135600881900b811461552757600080fd5b6000806040838503121561568957600080fd5b82356001600160401b0381111561569f57600080fd5b6153858582860161547d565b60a0815260006156be60a0830188615394565b90508560208301528460408301528360608301528260808301529695505050505050565b6000602082840312156156f457600080fd5b81356001600160401b0381111561570a57600080fd5b61367484828501615172565b6000806020838503121561572957600080fd5b82356001600160401b0381111561573f57600080fd5b61574b85828601615556565b90969095509350505050565b60ff8116811461466457600080fd5b600080600080600080600060e0888a03121561578157600080fd5b873561578c8161507b565b9650602088013561579c8161507b565b9550604088013594506060880135935060808801356157ba81615757565b9699959850939692959460a0840135945060c09093013592915050565b600080600080608085870312156157ed57600080fd5b84356157f88161507b565b935060208501359250604085013561580f8161507b565b9396929550929360600135925050565b600181811c9082168061583357607f821691505b60208210810361549057634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610c2257610c22615869565b6000600182016158a4576158a4615869565b5060010190565b81810381811115610c2257610c22615869565b6000808335601e198436030181126158d557600080fd5b8301803591506001600160401b038211156158ef57600080fd5b6020019150600581901b36038213156142e057600080fd5b6000610c22368361525a565b60006020828403121561592557600080fd5b813561364581615241565b8082028115828204841417610c2257610c22615869565b634e487b7160e01b600052601260045260246000fd5b60008261596c5761596c615947565b500490565b60006020828403121561598357600080fd5b6136458261513b565b60006020828403121561599e57600080fd5b81516136458161507b565b6000602082840312156159bb57600080fd5b815161364581615757565b6000600160ff1b82016159db576159db615869565b5060000390565b6000602082840312156159f457600080fd5b815161364581615241565b60006101008201905060018060a01b0380851683526001600160481b03845116602084015280602085015116604084015250604083015160080b606083015260ff606084015116608083015260ff60808401511660a083015260a0830151615a7260c08401826001600160a01b03169052565b5060c083015180151560e0840152509392505050565b600060208284031215615a9a57600080fd5b5051919050565b600181815b80851115615adc578160001904821115615ac257615ac2615869565b80851615615acf57918102915b93841c9390800290615aa6565b509250929050565b600082615af357506001610c22565b81615b0057506000610c22565b8160018114615b165760028114615b2057615b3c565b6001915050610c22565b60ff841115615b3157615b31615869565b50506001821b610c22565b5060208310610133831016604e8410600b8410161715615b5f575081810a610c22565b615b698383615aa1565b8060001904821115615b7d57615b7d615869565b029392505050565b600061364560ff841683615ae4565b60006001600160481b0380841680615bae57615bae615947565b92169190910492915050565b6001600160481b03818116838216019080821115615bda57615bda615869565b5092915050565b634e487b7160e01b600052603160045260246000fd5b8181036000831280158383131683831282161715615bda57615bda615869565b6020808252825182820181905260009190848201906040850190845b81811015615c585783516001600160a01b031683529284019291840191600101615c33565b50909695505050505050565b600081518084526020808501945080840160005b8381101561540257815187529582019590820190600101615c78565b6001600160a01b03878116825260a06020808401829052908301879052600091889160c08501845b8a811015615ce3578435615ccf8161507b565b841682529382019390820190600101615cbc565b508581036040870152615cf6818a615c64565b93505050508281036060840152615d0d8186615c64565b915050826080830152979650505050505050565b600080835481600182811c915080831680615d3d57607f831692505b60208084108203615d5c57634e487b7160e01b86526022600452602486fd5b818015615d705760018114615d8557615db2565b60ff1986168952841515850289019650615db2565b60008a81526020902060005b86811015615daa5781548b820152908501908301615d91565b505084890196505b509498975050505050505050565b80820260008212600160ff1b84141615615ddc57615ddc615869565b8181058314821517610c2257610c22615869565b600082615dff57615dff615947565b600160ff1b821460001984141615615e1957615e19615869565b500590565b8082018281126000831280158216821582161715615e3e57615e3e615869565b505092915050565b60008251615e58818460208701615024565b919091019291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122068e9ddcfbd3c43085683c87112d80438c0cb8e8db0d4c7ebf93715cd6bbf957f64736f6c6343000813003300000000000000000000000094194de310b99d3c8a5b8c0768cfce7aef81d9be0000000000000000000000009b122361e8708be33b785e44fce4d6ca86ab6c5a000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e100000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002386f26fc10000Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103995760003560e01c806382c0ab21116101e9578063cc88688b1161010f578063e787caa4116100ad578063f2fde38b1161007c578063f2fde38b14610a0c578063f58f951014610a1f578063f6fabac614610a47578063fdc5a0fe14610a6757600080fd5b8063e787caa4146109c0578063eb95c56c146109d3578063ec2a0992146109e6578063f14f58f1146109f957600080fd5b8063db10e60f116100e9578063db10e60f1461095c578063dd62ed3e1461096f578063e02ff0541461099a578063e30c3978146109ad57600080fd5b8063cc88688b146108a2578063d505accf146108b5578063d7691f8f146108c857600080fd5b80639622c75611610187578063a9059cbb11610156578063a9059cbb14610806578063aeabb17f14610819578063b023c8651461082c578063c76ece881461088f57600080fd5b80639622c756146107915780639c016ffd146107b55780639efd6f72146107bd578063a033fcd4146107f357600080fd5b80638be859ec116101c35780638be859ec146107665780638da5cb5b1461076e57806392fede001461078157806395d89b411461078957600080fd5b806382c0ab211461068257806383307f43146106955780638b0dcb4e1461069d57600080fd5b80633745a192116102ce57806371e85c411161026c5780637bcbb1dd1161023b5780637bcbb1dd146106295780637d43447e1461063c5780637ebcf3bf1461064f5780637ecebe001461066257600080fd5b806371e85c41146105e85780637494e604146105fb57806379ba50971461060e5780637acab86e1461061657600080fd5b80636548e9bc116102a85780636548e9bc1461058f578063683ab4a9146105a25780636ede2988146105b557806370a08231146105c857600080fd5b80633745a1921461053e578063439e2e451461056957806352e49dd91461057c57600080fd5b806323b872dd1161033b5780632efda2bc116103155780632efda2bc146104ca578063313ce567146104ea57806335dda72f146105235780633644e5151461053657600080fd5b806323b872dd146104915780632483e715146104a45780632d58fd75146104b757600080fd5b8063095ea7b311610377578063095ea7b3146103f5578063154bb43c1461041857806318160ddd1461043b5780631a366bb71461045257600080fd5b806302e43cbc1461039e5780630505af94146103b357806306fdde03146103e0575b600080fd5b6103b16103ac366004614ffb565b610a6f565b005b600f80546103c891600160801b909104900b81565b604051600f9190910b81526020015b60405180910390f35b6103e8610b2d565b6040516103d79190615048565b6104086104033660046150a0565b610bbb565b60405190151581526020016103d7565b61042b610426366004615350565b610c28565b6040516103d7949392919061540d565b61044460025481565b6040519081526020016103d7565b6104797f000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e181565b6040516001600160a01b0390911681526020016103d7565b61040861049f36600461543c565b610f6d565b600954610479906001600160a01b031681565b6104446104c5366004615496565b61104d565b6104446104d83660046154dc565b600c6020526000908152604090205481565b6105117f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff90911681526020016103d7565b6103b16105313660046154f9565b611306565b6104446115ea565b600f54610551906001600160801b031681565b6040516001600160801b0390911681526020016103d7565b6103b161057736600461543c565b611645565b6103b161058a366004615532565b6116a6565b6103b161059d3660046154dc565b61175c565b6103b16105b036600461559a565b6117a8565b6103b16105c3366004615605565b61186a565b6104446105d63660046154dc565b60036020526000908152604090205481565b6104796105f6366004615628565b6118e0565b6103b16106093660046150a0565b61190a565b6103b161196e565b610444610624366004615496565b6119f5565b6103b1610637366004615641565b611eba565b61044461064a366004615496565b612039565b6103b161065d366004614ffb565b61221d565b6104446106703660046154dc565b60056020526000908152604090205481565b6104446106903660046150a0565b6122ca565b6104446123f6565b61070f6106ab3660046154dc565b601060205260009081526040902080546001909101546001600160481b038216916001600160a01b03600160481b91829004811692600881900b9260ff908204811692600160501b8304821692600160581b810490911691600160f81b9091041687565b604080516001600160481b0390981688526001600160a01b03968716602089015260089590950b9487019490945260ff9283166060870152911660808501529190911660a0830152151560c082015260e0016103d7565b600a54610444565b600654610479906001600160a01b031681565b6103b16124fd565b6103e8612571565b6107a461079f366004615676565b61257e565b6040516103d79594939291906156ab565b6103b1612850565b6105116107cb3660046154dc565b6001600160a01b0316600090815260106020526040902060010154600160481b900460ff1690565b6103b16108013660046150a0565b612941565b6104086108143660046150a0565b612a09565b6104796108273660046156e2565b612a6f565b61083f61083a3660046154dc565b612b09565b6040516103d7919081516001600160a01b031681526020808301519082015260408083015190820152606080830151908201526080808301519082015260a0918201519181019190915260c00190565b6103b161089d366004615716565b612bd9565b600854610479906001600160a01b031681565b6103b16108c3366004615766565b612d95565b600a54600b5461091291906001600160481b038082169161ffff600160481b8204169165ffffffffffff600160581b8304811692600160881b810490921691600160d01b90041686565b604080519687526001600160481b03958616602088015261ffff9094169386019390935265ffffffffffff91821660608601529290921660808401521660a082015260c0016103d7565b61047961096a3660046156e2565b612fde565b61044461097d3660046154f9565b600460209081526000928352604080842090915290825290205481565b6104446109a83660046154dc565b613062565b600754610479906001600160a01b031681565b6103b16109ce366004615628565b613090565b6104446109e13660046154dc565b613141565b6103b16109f43660046154dc565b613165565b6103b1610a07366004615628565b6131d9565b6103b1610a1a3660046154dc565b6133af565b610a32610a2d3660046157d7565b613425565b604080519283526020830191909152016103d7565b610444610a553660046154dc565b600d6020526000908152604090205481565b600e54610444565b6006546001600160a01b03163314610a99576040516282b42960e81b815260040160405180910390fd5b66b1a2bc2ec50000816001600160481b03161115610aca57604051636d4d4a6760e11b815260040160405180910390fd5b600b805468ffffffffffffffffff60881b1916600160881b6001600160481b038416908102919091179091556040519081527f40ecaade69bfd8d44b55fee3f7dc31cdb78157320c6ba966c032db84bd855860906020015b60405180910390a150565b60008054610b3a9061581f565b80601f0160208091040260200160405190810160405280929190818152602001828054610b669061581f565b8015610bb35780601f10610b8857610100808354040283529160200191610bb3565b820191906000526020600020905b815481529060010190602001808311610b9657829003601f168201915b505050505081565b3360008181526004602090815260408083206001600160a01b038716808552925280832085905551919290917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92590610c169086815260200190565b60405180910390a35060015b92915050565b606060008060008560400151516001600160401b03811115610c4c57610c4c6150cc565b604051908082528060200260200182016040528015610c8557816020015b610c72614fbe565b815260200190600190039081610c6a5790505b50935060005b866040015151811015610e04576000610cde88604001518381518110610cb357610cb3615853565b602002602001015189606001518481518110610cd157610cd1615853565b60200260200101516122ca565b905080600003610d015760405163e49d3ed160e01b815260040160405180910390fd5b6040518060e00160405280601060008b604001518681518110610d2657610d26615853565b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002060000160009054906101000a90046001600160481b03166001600160481b03168152602001610d9a8a604001518581518110610d8c57610d8c615853565b60200260200101518a613601565b81526020018281526020016000815260200160008152602001610dbd838a61364c565b81526020016000815250868381518110610dd957610dd9615853565b6020908102919091010152610dee818461587f565b9250508080610dfc90615892565b915050610c8b565b5060005b8451811015610f6357610e46858281518110610e2657610e26615853565b6020908102919091010151600b54889085906001600160481b031661367c565b858281518110610e5857610e58615853565b6020026020010181905250610eb2858281518110610e7857610e78615853565b602002602001015160800151868381518110610e9657610e96615853565b602002602001015160400151610eac91906158ab565b8761364c565b858281518110610ec457610ec4615853565b602002602001015160c0018181525050848181518110610ee657610ee6615853565b602002602001015160c0015184610efd919061587f565b9350848181518110610f1157610f11615853565b602002602001015160c00151858281518110610f2f57610f2f615853565b602002602001015160a00151610f4591906158ab565b610f4f908461587f565b925080610f5b81615892565b915050610e08565b5092959194509250565b6001600160a01b03831660009081526004602090815260408083203384529091528120546000198114610fc957610fa483826158ab565b6001600160a01b03861660009081526004602090815260408083203384529091529020555b6001600160a01b03851660009081526003602052604081208054859290610ff19084906158ab565b90915550506001600160a01b0380851660008181526003602052604090819020805487019055519091871690600080516020615e638339815191529061103a9087815260200190565b60405180910390a3506001949350505050565b6009546000906001600160a01b0316331461107a576040516282b42960e81b815260040160405180910390fd5b6110c161108a60408401846158be565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506136d992505050565b6111086110d160408401846158be565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061371992505050565b6000611113846137c0565b50905080611134576040516374b3e54160e01b815260040160405180910390fd5b600080808061114b61114588615907565b89610c28565b9350935093509350828760e00135111561117857604051635b688e4760e01b815260040160405180910390fd5b60005b61118860408901896158be565b90508110156112215761120f6111a460408a0160208b016154dc565b306111b260608c018c6158be565b858181106111c2576111c2615853565b905060200201358b80604001906111d991906158be565b868181106111e9576111e9615853565b90506020020160208101906111fe91906154dc565b6001600160a01b031692919061382f565b8061121981615892565b91505061117b565b5061123260e0880160c08901615913565b156112465761124187856138a0565b611250565b6112508784613cb8565b8115611260576112603083613d1c565b61127261126d828a61587f565b613d76565b600254600090611282838b61587f565b61129490670de0b6b3a7640000615930565b61129e919061595d565b90507f27bd68e1c50cdd7ad817c783781d4ff30255bc19b0f9b1eb3477892bc9e38d386112ce60208a018a615971565b6040805163ffffffff90921682526020820184905281018490526060810186905260800160405180910390a150979650505050505050565b6006546001600160a01b03163314611330576040516282b42960e81b815260040160405180910390fd5b6001600160a01b03811661137c576001600160a01b0380831660009081526010602052604090208054918316600160481b02600160481b600160e81b03199092169190911790556115a5565b6000816001600160a01b0316630dfe16816040518163ffffffff1660e01b8152600401602060405180830381865afa1580156113bc573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113e0919061598c565b90506000826001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa158015611422573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611446919061598c565b90506000846001600160a01b0316836001600160a01b03160361146a5750806114a3565b846001600160a01b0316826001600160a01b03160361148a5750816114a3565b60405163d35a91cf60e01b815260040160405180910390fd5b6001600160a01b038581166000908152601060209081526040918290208054600160481b600160e81b031916600160481b8986160217815560010180547fff0000000000000000000000000000000000000000ffffffffffffffffffffff16600160581b948616948502179055815163313ce56760e01b8152915163313ce5679260048082019392918290030181865afa158015611545573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156991906159a9565b6001600160a01b0386166000908152601060205260409020600101805460ff92909216600160501b0260ff60501b199092169190911790555050505b6040516001600160a01b0382811682528316907ff09d9fda2e96eeb85eacfdc7def084e286e39b2c8dab78b35221f9a5e2502cb4906020015b60405180910390a25050565b60007f000000000000000000000000000000000000000000000000000000000000000146146116205761161b613dab565b905090565b507f654f2e151e312aaa03257bfcb0557766569b89904f51ac099a50f8b945511b2b90565b336001600160a01b037f000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e1161461168d576040516282b42960e81b815260040160405180910390fd5b6116a16001600160a01b0384168383613e45565b505050565b6006546001600160a01b031633146116d0576040516282b42960e81b815260040160405180910390fd5b600a8161ffff1610806116e857506101f48161ffff16115b1561170657604051636d4d4a6760e11b815260040160405180910390fd5b600b80546affff0000000000000000001916600160481b61ffff8416908102919091179091556040519081527fd08c1bc3993b0af9ff782c23b664467f9c10136abbd2f03262557fc2abde0f5590602001610b22565b6006546001600160a01b03163314611786576040516282b42960e81b815260040160405180910390fd5b600980546001600160a01b0319166001600160a01b0392909216919091179055565b6006546001600160a01b031633146117d2576040516282b42960e81b815260040160405180910390fd5b8281146117f25760405163b1f40f7760e01b815260040160405180910390fd5b60005b838110156118635761185385858381811061181257611812615853565b905060200201602081019061182791906154dc565b84848481811061183957611839615853565b905060200201602081019061184e91906154dc565b613e75565b61185c81615892565b90506117f5565b5050505050565b6006546001600160a01b03163314611894576040516282b42960e81b815260040160405180910390fd5b68056bc75e2d6310000081600f0b13156118c157604051636d4d4a6760e11b815260040160405180910390fd5b600f80546001600160801b03928316600160801b029216919091179055565b600e81815481106118f057600080fd5b6000918252602090912001546001600160a01b0316905081565b336001600160a01b037f000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e11614611952576040516282b42960e81b815260040160405180910390fd5b6001600160a01b039091166000908152600d6020526040902055565b6007546001600160a01b03163314611998576040516282b42960e81b815260040160405180910390fd5b60068054600780546001600160a01b03198084166001600160a01b038381169182179096559116909155604051929091169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a350565b6009546000906001600160a01b03163314611a22576040516282b42960e81b815260040160405180910390fd5b611a3261108a60408401846158be565b611a4261108a60808401846158be565b611a526110d160408401846158be565b611a626110d160808401846158be565b611aa9611a7260408401846158be565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061401c92505050565b611ab9611a7260808401846158be565b6000611ac4846137c0565b50905080611ae5576040516374b3e54160e01b815260040160405180910390fd5b600080611b7f611af860408701876158be565b6000818110611b0957611b09615853565b9050602002016020810190611b1e91906154dc565b611b2b60608801886158be565b6000818110611b3c57611b3c615853565b90506020020135878060800190611b5391906158be565b6000818110611b6457611b64615853565b9050602002016020810190611b7991906154dc565b89613425565b9150915081600003611ba45760405163c573eaa560e01b815260040160405180910390fd5b8460e00135821015611bc957604051635b688e4760e01b815260040160405180910390fd5b81611c00611bda60808801886158be565b6000818110611beb57611beb615853565b90506020020160208101906109a891906154dc565b1015611c1f576040516336eefe3560e01b815260040160405180910390fd5b600080821315611c4d57611c33828861587f565b9050611c4830611c43848a61364c565b613d1c565b611ccb565b6000821215611cc857611c5f826159c6565b611c6990886158ab565b90506000611c7f611c79846159c6565b8961364c565b30600090815260036020526040902054909150811115611cae5730600090815260036020526040902054611cb0565b805b90508015611cc257611cc2308261405c565b50611ccb565b50855b611cd481613d76565b611d34611ce460408801886158be565b6000818110611cf557611cf5615853565b9050602002016020810190611d0a91906154dc565b611d1760608901896158be565b6000818110611d2857611d28615853565b905060200201356140be565b611d70611d4460808801886158be565b6000818110611d5557611d55615853565b9050602002016020810190611d6a91906154dc565b846140ef565b611dca611d8360408801602089016154dc565b30611d9160608a018a6158be565b6000818110611da257611da2615853565b90506020020135898060400190611db991906158be565b60008181106111e9576111e9615853565b611e21611ddd60408801602089016154dc565b84611deb60808a018a6158be565b6000818110611dfc57611dfc615853565b9050602002016020810190611e1191906154dc565b6001600160a01b03169190613e45565b7fc84ce3ed8ab6ac38b6355da334b0da7d1c924c8b5d0e83d53d6883f2be0fcce8611e4f6020880188615971565b611e5c60808901896158be565b6000818110611e6d57611e6d615853565b9050602002016020810190611e8291906154dc565b6040805163ffffffff90931683526001600160a01b039091166020830152810185905260600160405180910390a15095945050505050565b60095460405163b588c10b60e01b81523360048201526001600160a01b039091169063b588c10b90602401602060405180830381865afa158015611f02573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f2691906159e2565b611f42576040516282b42960e81b815260040160405180910390fd5b600f8054600160801b9004900b600882900b1315611f7357604051636d4d4a6760e11b815260040160405180910390fd5b600f54611f8a906001600160801b0316600561587f565b431015611faa576040516311a3df9560e01b815260040160405180910390fd5b600f80546fffffffffffffffffffffffffffffffff1916436001600160801b03161790556001600160a01b038216600081815260106020908152604091829020600101805468ffffffffffffffffff19166001600160481b0386161790559051600884900b81527f05d3a92f1773bfe6b86e42c45a0bfdf57247864d79797482e71c94f22c8dcb2a91016115de565b6009546000906001600160a01b03163314612066576040516282b42960e81b815260040160405180910390fd5b61207661108a60808401846158be565b6120866110d160808401846158be565b6000612091846137c0565b509050806120b2576040516374b3e54160e01b815260040160405180910390fd5b6000806120c560e0860160c08701615913565b6120d8576120d38686614117565b6120e2565b6120e286866142e7565b909250905061216d6120f760808701876158be565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506121369250505060a08801886158be565b808060200260200160405190810160405280939291908181526020018383602002808284376000920191909152506145a092505050565b61217a61126d83886158ab565b600060025460000361218d5760006121b6565b60025461219a84896158ab565b6121ac90670de0b6b3a7640000615930565b6121b6919061595d565b90507f90b5f7dd30f1e6716a37f642aab9e2a5a1216c72e1044251b59c801e40dba82f6121e66020880188615971565b6040805163ffffffff90921682526020820184905281018590526060810184905260800160405180910390a1509095945050505050565b6006546001600160a01b03163314612247576040516282b42960e81b815260040160405180910390fd5b68056bc75e2d63100000816001600160481b0316111561227a57604051636d4d4a6760e11b815260040160405180910390fd5b600b805468ffffffffffffffffff19166001600160481b0383169081179091556040519081527ff036cc909a40e5a5297fc43a607fba898d621fe78a6153d56c6bf249ce92dee490602001610b22565b6001600160a01b038281166000908152601060209081526040808320815160e08101835281546001600160481b0381168252600160481b90819004871694820194909452600190910154600881810b8385015293810460ff9081166060840152600160501b820481166080840152600160581b8204871660a0840152600160f81b90910416151560c0820152915490516378c8814f60e11b8152929391928492919091169063f191029e9061238590889086906004016159ff565b602060405180830381865afa1580156123a2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123c69190615a88565b90508160600151600a6123d99190615b85565b6123e38286615930565b6123ed919061595d565b95945050505050565b6000806000806000600e80548060200260200160405190810160405280929190818152602001828054801561245457602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311612436575b505083519394506000925050505b818110156124f25782818151811061247c5761247c615853565b60200260200101519550600c6000876001600160a01b03166001600160a01b0316815260200190815260200160002054600003156124e2576124bd86613141565b9350836000036124d5575050600a5495945050505050565b6124df848661587f565b94505b6124eb81615892565b9050612462565b509295945050505050565b6006546001600160a01b03163314612527576040516282b42960e81b815260040160405180910390fd5b6007546040516001600160a01b03909116907f6ecd4842251bedd053b09547c0fabaab9ec98506ebf24469e8dd5560412ed37f90600090a2600780546001600160a01b0319169055565b60018054610b3a9061581f565b6060600080808061259260808801886158be565b90506001600160401b038111156125ab576125ab6150cc565b6040519080825280602002602001820160405280156125e457816020015b6125d1614fbe565b8152602001906001900390816125c95790505b50945060005b6125f760808901896158be565b905081101561278957600061266061261260808b018b6158be565b8481811061262257612622615853565b905060200201602081019061263791906154dc565b61264460a08c018c6158be565b8581811061265457612654615853565b905060200201356122ca565b9050806000036126835760405163e49d3ed160e01b815260040160405180910390fd5b6040805160e0810190915280601060006126a060808e018e6158be565b878181106126b0576126b0615853565b90506020020160208101906126c591906154dc565b6001600160a01b03168152602080820192909252604001600020546001600160481b03168252016127276126fc60808d018d6158be565b8681811061270c5761270c615853565b905060200201602081019061272191906154dc565b8b613601565b8152602001828152602001600081526020016000815260200160008152602001600081525087838151811061275e5761275e615853565b6020908102919091010152612773818461587f565b925050808061278190615892565b9150506125ea565b5060005b855181101561282d576127cb8682815181106127ab576127ab615853565b6020908102919091010151600b54899085906001600160481b03166145fa565b8682815181106127dd576127dd615853565b602002602001018190525061280f8682815181106127fd576127fd615853565b6020026020010151608001518861364c565b612819908461587f565b92508061282581615892565b91505061278d565b50612838818761364c565b9250612844828461587f565b93509295509295909350565b600b54600090612875906301e187e090600160881b90046001600160481b0316615b94565b600b546001600160481b039190911691506000906128a290600160d01b900465ffffffffffff16426158ab565b9050806000036128b0575050565b6000670de0b6b3a764000060025483856128ca9190615930565b6128d49190615930565b6128de919061595d565b600b80546001600160d01b0316600160d01b4265ffffffffffff160217905590506129093082613d1c565b6040518181527f147fac6415bee3006ba6002a9a6636f492d311690c9e52a2421afc6392e0fb959060200160405180910390a1505050565b6006546001600160a01b0316331461296b576040516282b42960e81b815260040160405180910390fd5b6129748261463d565b61297d81614667565b306000908152600360205260408120805483929061299c9084906158ab565b90915550506001600160a01b038216600090815260036020526040812080548392906129c990849061587f565b90915550506040518181526001600160a01b038316907f9dc46f23cfb5ddcad0ae7ea2be38d47fec07bb9382ec7e564efc69e036dd66ce906020016115de565b33600090815260036020526040812080548391908390612a2a9084906158ab565b90915550506001600160a01b03831660008181526003602052604090819020805485019055513390600080516020615e6383398151915290610c169086815260200190565b6000805b8251811015612b005760106000848381518110612a9257612a92615853565b6020908102919091018101516001600160a01b031682528101919091526040016000206001015460080b68056bc75e2d630fffff1903612aee57828181518110612ade57612ade615853565b6020026020010151915050919050565b80612af881615892565b915050612a73565b50600092915050565b612b4b6040518060c0016040528060006001600160a01b0316815260200160008152602001600081526020016000815260200160008152602001600081525090565b6040805160c0810182526001600160a01b0384168082526000818152600c60209081528482205481850152918152600d909152829020549181019190915260608101612b9f84670de0b6b3a76400006122ca565b815260200160008152602001600254600a60000154670de0b6b3a7640000612bc79190615930565b612bd1919061595d565b905292915050565b6006546001600160a01b03163314612c03576040516282b42960e81b815260040160405180910390fd5b600e548114612c255760405163b1f40f7760e01b815260040160405180910390fd5b6000805b82811015612c7657838382818110612c4357612c43615853565b9050602002016020810190612c589190614ffb565b612c629083615bba565b915080612c6e81615892565b915050612c29565b5068056bc75e2fb71be400816001600160481b03161180612ca8575068056bc75e2b0f041c00816001600160481b0316105b15612cc657604051636b522f1160e11b815260040160405180910390fd5b60005b82811015612d6657838382818110612ce357612ce3615853565b9050602002016020810190612cf89190614ffb565b60106000600e8481548110612d0f57612d0f615853565b6000918252602080832091909101546001600160a01b031683528201929092526040019020805468ffffffffffffffffff19166001600160481b039290921691909117905580612d5e81615892565b915050612cc9565b506040517f0f76096615ee194cca6c5e0f25f4a332cbf3aaa195ae55f2cbcb881db1aef18390600090a1505050565b42841015612dea5760405162461bcd60e51b815260206004820152601760248201527f5045524d49545f444541444c494e455f4558504952454400000000000000000060448201526064015b60405180910390fd5b60006001612df66115ea565b6001600160a01b038a811660008181526005602090815260409182902080546001810190915582517f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98184015280840194909452938d166060840152608083018c905260a083019390935260c08083018b90528151808403909101815260e08301909152805192019190912061190160f01b6101008301526101028201929092526101228101919091526101420160408051601f198184030181528282528051602091820120600084529083018083525260ff871690820152606081018590526080810184905260a0016020604051602081039080840390855afa158015612f02573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811615801590612f385750876001600160a01b0316816001600160a01b0316145b612f755760405162461bcd60e51b815260206004820152600e60248201526d24a72b20a624a22fa9a4a3a722a960911b6044820152606401612de1565b6001600160a01b0390811660009081526004602090815260408083208a8516808552908352928190208990555188815291928a16917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a350505050505050565b6000805b8251811015612b00576010600084838151811061300157613001615853565b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020600101601f9054906101000a900460ff1661305057828181518110612ade57612ade615853565b8061305a81615892565b915050612fe2565b6001600160a01b0381166000908152600d6020908152604080832054600c909252822054610c2291906158ab565b6009546001600160a01b031633148015906130b657506006546001600160a01b03163314155b156130d3576040516282b42960e81b815260040160405180910390fd5b600b54600160581b900465ffffffffffff164303613104576040516311a3df9560e01b815260040160405180910390fd5b600b805465ffffffffffff60581b1916600160581b4365ffffffffffff16021790556000613131826137c0565b91505061313d81613d76565b5050565b6001600160a01b0381166000908152600c6020526040812054610c229083906122ca565b6006546001600160a01b0316331461318f576040516282b42960e81b815260040160405180910390fd5b600880546001600160a01b0319166001600160a01b0383169081179091556040517f90f3093aefb44e115f8088a7f69b5f3adf9d7ec6f153ac758de49cfe3c740cd190600090a250565b6006546001600160a01b03163314613203576040516282b42960e81b815260040160405180910390fd5b6000600e828154811061321857613218615853565b60009182526020808320909101546001600160a01b0316808352600c9091526040909120549091501561325d576040516252b55360e31b815260040160405180910390fd5b6001600160a01b0381166000908152601060205260409020546001600160481b03161561329c576040516252b55360e31b815260040160405180910390fd5b6001600160a01b038116600090815260106020526040812080546001600160e81b0319168155600190810191909155600e805490916132da916158ab565b815481106132ea576132ea615853565b600091825260209091200154600e80546001600160a01b03909216918490811061331657613316615853565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550600e80548061335557613355615be1565b600082815260208120820160001990810180546001600160a01b03191690559091019091556040516001600160a01b038316917f37803e2125c48ee96c38ddf04e826daf335b0e1603579040fd275aba6d06b6fc91a25050565b6006546001600160a01b031633146133d9576040516282b42960e81b815260040160405180910390fd5b600780546001600160a01b0319166001600160a01b03831690811790915560405133907f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270090600090a350565b600080600061343487876122ca565b6001600160a01b0386166000908152601060205260408120600101549192509061346f90879061069090600160481b900460ff16600a615b85565b905081158061347c575080155b1561348f576000809350935050506135f8565b50506040805160e0810182526001600160a01b038816600090815260106020908152928120546001600160481b031682529181016134cd8987613601565b81526020016134dc89896122ca565b8152600060208083018290526040808401839052606084018390526080909301829052825160e0810184526001600160a01b038a16835260108252928220546001600160481b031683529293509181016135368888613601565b8152600060208083018290526040808401839052606084018390526080840183905260a0909301829052600b546001600160a01b03808e1684526010909252838320600190810154928c1684529383209093015493945090926135b092869286928b926001600160481b031691600890810b91900b614688565b90506135c487670de0b6b3a76400006122ca565b6135d682670de0b6b3a7640000615930565b6135e0919061595d565b8184604001516135f09190615bf7565b945094505050505b94509492505050565b6000811580156136115750600a54155b1561361e57506000610c22565b8161362884613141565b61363b9068056bc75e2d63100000615930565b613645919061595d565b9392505050565b600254600090801561367257826136638286615930565b61366d919061595d565b613674565b835b949350505050565b613684614fbe565b845160000361369e57506040840151608085015283613674565b816000036136ad575083613674565b6136b88585856147e9565b945084606001516000036136cd575083613674565b6123ed858585856148df565b60006136e482612fde565b90506001600160a01b0381161561313d57604051632777a68f60e11b81526001600160a01b0382166004820152602401612de1565b600954604051633e031b6760e21b81526000916001600160a01b03169063f80c6d9c9061374a908590600401615c17565b602060405180830381865afa158015613767573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061378b919061598c565b90506001600160a01b0381161561313d5760405163fc31f2eb60e01b81526001600160a01b0382166004820152602401612de1565b600b54600a546000918291600160481b90910461ffff1690826137e382846149e9565b905060006137f5838561ffff16614a1a565b90508187101561380d57506000969095509350505050565b8087111561382357600097909650945050505050565b50600196945050505050565b6040516001600160a01b038085166024830152831660448201526064810182905261389a9085906323b872dd60e01b906084015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152614a39565b50505050565b60006138af60408401846158be565b90506001600160401b038111156138c8576138c86150cc565b6040519080825280602002602001820160405280156138f1578160200160208202803683370190505b509050600061390360408501856158be565b90506001600160401b0381111561391c5761391c6150cc565b604051908082528060200260200182016040528015613945578160200160208202803683370190505b50905060008060005b61395b60408801886158be565b9050811015613a945785818151811061397657613976615853565b602002602001015160a0015186828151811061399457613994615853565b602002602001015160c00151670de0b6b3a76400006139b39190615930565b6139bd919061595d565b9250670de0b6b3a7640000836139d660608a018a6158be565b848181106139e6576139e6615853565b905060200201356139f79190615930565b613a01919061595d565b848281518110613a1357613a13615853565b602002602001018181525050858181518110613a3157613a31615853565b602002602001015160c00151858281518110613a4f57613a4f615853565b602002602001018181525050848181518110613a6d57613a6d615853565b602002602001015182613a80919061587f565b915080613a8c81615892565b91505061394e565b5060006001600160a01b037f000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e11663c92b75c4613ad660408a0160208b016154dc565b613ae360408b018b6158be565b888a886040518763ffffffff1660e01b8152600401613b0796959493929190615c94565b6020604051808303816000875af1158015613b26573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613b4a919061598c565b905060005b613b5c60408901896158be565b9050811015613bb557613ba382868381518110613b7b57613b7b615853565b60200260200101518a8060400190613b9391906158be565b85818110611dfc57611dfc615853565b80613bad81615892565b915050613b4f565b50613c3c613bc660408901896158be565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613c059250505060608a018a6158be565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250614b0e92505050565b613c85613c4c60408901896158be565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250889250614b68915050565b613caf7f000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e183613d1c565b50505050505050565b613d07613cc860408401846158be565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250613c059250505060608501856158be565b61313d613d1a60408401602085016154dc565b825b8060026000828254613d2e919061587f565b90915550506001600160a01b038216600081815260036020908152604080832080548601905551848152600080516020615e6383398151915291015b60405180910390a35050565b600a8190556040518181527fb4f10f1c952679350ddb7fefb943b40a586171e621e220adfb9ed55f0a643d0f90602001610b22565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6000604051613ddd9190615d21565b6040805191829003822060208301939093528101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a082015260c00160405160208183030381529060405280519060200120905090565b6040516001600160a01b0383166024820152604481018290526116a190849063a9059cbb60e01b90606401613863565b6001600160a01b038216600090815260106020526040902060010154600160f81b900460ff1615613ec457604051634f1ac48560e01b81526001600160a01b0383166004820152602401612de1565b6001600160a01b03821660008181526010602090815260409182902060010180546001600160f81b0316600160f81b179055815163313ce56760e01b8152915163313ce5679260048082019392918290030181865afa158015613f2b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f4f91906159a9565b6001600160a01b0383166000908152601060205260409020600101805460ff92909216600160481b0269ff00000000000000000019909216919091179055613f978282611306565b600e80546001810182556000919091527fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0180546001600160a01b0319166001600160a01b0384169081179091556040519081527f0e3c58ebfb2e7465fbb1c32e6b4f40c3c4f5ca77e8218a386aff8617831260d79060200160405180910390a15050565b600061402782612a6f565b90506001600160a01b0381161561313d576040516303e4acb760e01b81526001600160a01b0382166004820152602401612de1565b6001600160a01b038216600090815260036020526040812080548392906140849084906158ab565b90915550506002805482900390556040518181526000906001600160a01b03841690600080516020615e6383398151915290602001613d6a565b6001600160a01b0382166000908152600c6020526040812080548392906140e690849061587f565b90915550505050565b6001600160a01b0382166000908152600c6020526040812080548392906140e69084906158ab565b60008060005b61412a60808501856158be565b90508110156141ab5761414060a08501856158be565b8281811061415057614150615853565b9050602002013561417a85806080019061416a91906158be565b84818110611beb57611beb615853565b1015614199576040516336eefe3560e01b815260040160405180910390fd5b806141a381615892565b91505061411d565b5060008060006141bb868861257e565b94509450509350508560e001358311156141e857604051635b688e4760e01b815260040160405180910390fd5b82600360006141fd60408a0160208b016154dc565b6001600160a01b03166001600160a01b0316815260200190815260200160002054101561423d57604051637596688560e01b815260040160405180910390fd5b61425661425060408801602089016154dc565b8461405c565b8115614266576142663083613d1c565b60005b61427660808801886158be565b90508110156142d8576142c66142926040890160208a016154dc565b61429f60a08a018a6158be565b848181106142af576142af615853565b90506020020135898060800190613b9391906158be565b806142d081615892565b915050614269565b509350909150505b9250929050565b6000808061433f6142fb60808601866158be565b600081811061430c5761430c615853565b905060200201602081019061432191906154dc565b61432e60a08701876158be565b600081811061265457612654615853565b9050806000036143625760405163e49d3ed160e01b815260040160405180910390fd5b600061436e828761364c565b9050808560e00135101561439557604051635b688e4760e01b815260040160405180910390fd5b6143bf7f000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e18261405c565b6144456143cf60808701876158be565b8080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525061440e9250505060a08801886158be565b80806020026020016040519081016040528093929190818152602001838360200280828437600092019190915250614bf392505050565b6001600160a01b037f000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e116639c787c6761448460408801602089016154dc565b61449160808901896158be565b60008181106144a2576144a2615853565b90506020020160208101906144b791906154dc565b6144c460a08a018a6158be565b60008181106144d5576144d5615853565b6040516001600160e01b031960e088901b1681526001600160a01b0395861660048201529490931660248501525060209091020135604482015260648101849052608401600060405180830381600087803b15801561453357600080fd5b505af1158015614547573d6000803e3d6000fd5b50614595925061456091505060408701602088016154dc565b61456d60a08801886158be565b600081811061457e5761457e615853565b90506020020135878060800190611deb91906158be565b909590945092505050565b60005b82518110156116a1576145e88382815181106145c1576145c1615853565b60200260200101518383815181106145db576145db615853565b60200260200101516140ef565b806145f281615892565b9150506145a3565b614602614fbe565b81600003614611575083613674565b61461c858585614c7e565b94508460600151600003614631575083613674565b6123ed85858585614d26565b6001600160a01b0381166146645760405163339d6ef160e21b815260040160405180910390fd5b50565b806000036146645760405163339d6ef160e21b815260040160405180910390fd5b6000614697878660008761367c565b9650600068056bc75e2d63100000886060015189604001516146b991906158ab565b6146c39086615dc0565b6146cd9190615df0565b9050600080821215614710576146ed6146e883600019615dc0565b614e15565b89608001518a6040015161470191906158ab565b61470b91906158ab565b614737565b61471982614e15565b89608001518a6040015161472d91906158ab565b614737919061587f565b60408901819052905061474d88886000896145fa565b9750600068056bc75e2d6310000089606001518361476b91906158ab565b6147759087615dc0565b61477f9190615df0565b90506000808212156147b85761479a6146e883600019615dc0565b60808b01516147a990856158ab565b6147b391906158ab565b6147da565b6147c182614e15565b60808b01516147d090856158ab565b6147da919061587f565b9b9a5050505050505050505050565b6147f1614fbe565b600068056bc75e2d6310000061480a8660000151614e3c565b6148178760200151614e3c565b6148219190615bf7565b61482a86614e3c565b6148349190615dc0565b61483e9190615df0565b9050600083600003614851576000614883565b68056bc75e2d6310000061486485614e3c565b875161486f90614e3c565b6148799190615dc0565b6148839190615df0565b9050600081836148968960400151614e3c565b6148a09190615e1e565b6148aa9190615bf7565b90506148cf6146e86148bf8960400151614e3c565b6148ca846000614e66565b614e7d565b6060880152509495945050505050565b6148e7614fbe565b6000856040015168056bc75e2d631000008760200151876149089190615930565b614912919061595d565b61491c919061587f565b865190915060009068056bc75e2d6310000090614939878961587f565b6149439190615930565b61494d919061595d565b90506000670de0b6b3a7640000826149658583615930565b61496f919061595d565b61497991906158ab565b9050600061498f82670de0b6b3a7640000614e8c565b9050600068056bc75e2d631000006149a78389615930565b6149b1919061595d565b9050670de0b6b3a7640000818b606001516149cc9190615930565b6149d6919061595d565b60808b0152509798975050505050505050565b61271081810390821161138819829004841182021715614a0857600080fd5b61271092026113880191909104919050565b61271081016127101982116113881982900484111715614a0857600080fd5b6000614a8e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316614e9b9092919063ffffffff16565b9050805160001480614aaf575080806020019051810190614aaf91906159e2565b6116a15760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401612de1565b60005b82518110156116a157614b56838281518110614b2f57614b2f615853565b6020026020010151838381518110614b4957614b49615853565b60200260200101516140be565b80614b6081615892565b915050614b11565b60005b82518110156116a157818181518110614b8657614b86615853565b6020026020010151600d6000858481518110614ba457614ba4615853565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000828254614bdb919061587f565b90915550819050614beb81615892565b915050614b6b565b60005b82518110156116a157818181518110614c1157614c11615853565b6020026020010151600d6000858481518110614c2f57614c2f615853565b60200260200101516001600160a01b03166001600160a01b031681526020019081526020016000206000828254614c6691906158ab565b90915550819050614c7681615892565b915050614bf6565b614c86614fbe565b600068056bc75e2d63100000614c9f8660000151614e3c565b614cac8760200151614e3c565b614cb69190615bf7565b614cbf86614e3c565b614cc99190615dc0565b614cd39190615df0565b9050600068056bc75e2d63100000614cea85614e3c565b8751614cf590614e3c565b614cff9190615dc0565b614d099190615df0565b905060008183614d1c8960400151614e3c565b6148a09190615bf7565b614d2e614fbe565b6000614d3d8660400151614e3c565b68056bc75e2d63100000614d548860200151614e3c565b614d5d88614e3c565b614d679190615dc0565b614d719190615df0565b614d7b9190615bf7565b9050600068056bc75e2d63100000614d9286614e3c565b614d9b88614e3c565b614da59190615bf7565b8851614db090614e3c565b614dba9190615dc0565b614dc49190615df0565b9050600081614ddb84670de0b6b3a7640000615dc0565b614de59190615df0565b614df790670de0b6b3a7640000615bf7565b9050600061498f614e0783614e15565b670de0b6b3a7640000614e8c565b600080821215614e385760405163029f024d60e31b815260040160405180910390fd5b5090565b60006001600160ff1b03821115614e385760405163677c430560e11b815260040160405180910390fd5b600081831215614e765781613645565b5090919050565b6000818312614e765781613645565b6000818310614e765781613645565b6060613674848460008585600080866001600160a01b03168587604051614ec29190615e46565b60006040518083038185875af1925050503d8060008114614eff576040519150601f19603f3d011682016040523d82523d6000602084013e614f04565b606091505b5091509150614f1587838387614f20565b979650505050505050565b60608315614f8f578251600003614f88576001600160a01b0385163b614f885760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401612de1565b5081613674565b6136748383815115614fa45781518083602001fd5b8060405162461bcd60e51b8152600401612de19190615048565b6040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b60006020828403121561500d57600080fd5b81356001600160481b038116811461364557600080fd5b60005b8381101561503f578181015183820152602001615027565b50506000910152565b6020815260008251806020840152615067816040850160208701615024565b601f01601f19169190910160400192915050565b6001600160a01b038116811461466457600080fd5b803561509b8161507b565b919050565b600080604083850312156150b357600080fd5b82356150be8161507b565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b60405161010081016001600160401b0381118282101715615105576151056150cc565b60405290565b604051601f8201601f191681016001600160401b0381118282101715615133576151336150cc565b604052919050565b803563ffffffff8116811461509b57600080fd5b60006001600160401b03821115615168576151686150cc565b5060051b60200190565b600082601f83011261518357600080fd5b813560206151986151938361514f565b61510b565b82815260059290921b840181019181810190868411156151b757600080fd5b8286015b848110156151db5780356151ce8161507b565b83529183019183016151bb565b509695505050505050565b600082601f8301126151f757600080fd5b813560206152076151938361514f565b82815260059290921b8401810191818101908684111561522657600080fd5b8286015b848110156151db578035835291830191830161522a565b801515811461466457600080fd5b803561509b81615241565b6000610100828403121561526d57600080fd5b6152756150e2565b90506152808261513b565b815261528e60208301615090565b602082015260408201356001600160401b03808211156152ad57600080fd5b6152b985838601615172565b604084015260608401359150808211156152d257600080fd5b6152de858386016151e6565b606084015260808401359150808211156152f757600080fd5b61530385838601615172565b608084015260a084013591508082111561531c57600080fd5b50615329848285016151e6565b60a08301525061533b60c0830161524f565b60c082015260e082013560e082015292915050565b6000806040838503121561536357600080fd5b82356001600160401b0381111561537957600080fd5b6153858582860161525a565b95602094909401359450505050565b600081518084526020808501945080840160005b8381101561540257815180518852838101518489015260408082015190890152606080820151908901526080808201519089015260a0808201519089015260c0908101519088015260e090960195908201906001016153a8565b509495945050505050565b6080815260006154206080830187615394565b6020830195909552506040810192909252606090910152919050565b60008060006060848603121561545157600080fd5b833561545c8161507b565b9250602084013561546c8161507b565b929592945050506040919091013590565b6000610100828403121561549057600080fd5b50919050565b600080604083850312156154a957600080fd5b8235915060208301356001600160401b038111156154c657600080fd5b6154d28582860161547d565b9150509250929050565b6000602082840312156154ee57600080fd5b81356136458161507b565b6000806040838503121561550c57600080fd5b82356155178161507b565b915060208301356155278161507b565b809150509250929050565b60006020828403121561554457600080fd5b813561ffff8116811461364557600080fd5b60008083601f84011261556857600080fd5b5081356001600160401b0381111561557f57600080fd5b6020830191508360208260051b85010111156142e057600080fd5b600080600080604085870312156155b057600080fd5b84356001600160401b03808211156155c757600080fd5b6155d388838901615556565b909650945060208701359150808211156155ec57600080fd5b506155f987828801615556565b95989497509550505050565b60006020828403121561561757600080fd5b813580600f0b811461364557600080fd5b60006020828403121561563a57600080fd5b5035919050565b6000806040838503121561565457600080fd5b823561565f8161507b565b91506020830135600881900b811461552757600080fd5b6000806040838503121561568957600080fd5b82356001600160401b0381111561569f57600080fd5b6153858582860161547d565b60a0815260006156be60a0830188615394565b90508560208301528460408301528360608301528260808301529695505050505050565b6000602082840312156156f457600080fd5b81356001600160401b0381111561570a57600080fd5b61367484828501615172565b6000806020838503121561572957600080fd5b82356001600160401b0381111561573f57600080fd5b61574b85828601615556565b90969095509350505050565b60ff8116811461466457600080fd5b600080600080600080600060e0888a03121561578157600080fd5b873561578c8161507b565b9650602088013561579c8161507b565b9550604088013594506060880135935060808801356157ba81615757565b9699959850939692959460a0840135945060c09093013592915050565b600080600080608085870312156157ed57600080fd5b84356157f88161507b565b935060208501359250604085013561580f8161507b565b9396929550929360600135925050565b600181811c9082168061583357607f821691505b60208210810361549057634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610c2257610c22615869565b6000600182016158a4576158a4615869565b5060010190565b81810381811115610c2257610c22615869565b6000808335601e198436030181126158d557600080fd5b8301803591506001600160401b038211156158ef57600080fd5b6020019150600581901b36038213156142e057600080fd5b6000610c22368361525a565b60006020828403121561592557600080fd5b813561364581615241565b8082028115828204841417610c2257610c22615869565b634e487b7160e01b600052601260045260246000fd5b60008261596c5761596c615947565b500490565b60006020828403121561598357600080fd5b6136458261513b565b60006020828403121561599e57600080fd5b81516136458161507b565b6000602082840312156159bb57600080fd5b815161364581615757565b6000600160ff1b82016159db576159db615869565b5060000390565b6000602082840312156159f457600080fd5b815161364581615241565b60006101008201905060018060a01b0380851683526001600160481b03845116602084015280602085015116604084015250604083015160080b606083015260ff606084015116608083015260ff60808401511660a083015260a0830151615a7260c08401826001600160a01b03169052565b5060c083015180151560e0840152509392505050565b600060208284031215615a9a57600080fd5b5051919050565b600181815b80851115615adc578160001904821115615ac257615ac2615869565b80851615615acf57918102915b93841c9390800290615aa6565b509250929050565b600082615af357506001610c22565b81615b0057506000610c22565b8160018114615b165760028114615b2057615b3c565b6001915050610c22565b60ff841115615b3157615b31615869565b50506001821b610c22565b5060208310610133831016604e8410600b8410161715615b5f575081810a610c22565b615b698383615aa1565b8060001904821115615b7d57615b7d615869565b029392505050565b600061364560ff841683615ae4565b60006001600160481b0380841680615bae57615bae615947565b92169190910492915050565b6001600160481b03818116838216019080821115615bda57615bda615869565b5092915050565b634e487b7160e01b600052603160045260246000fd5b8181036000831280158383131683831282161715615bda57615bda615869565b6020808252825182820181905260009190848201906040850190845b81811015615c585783516001600160a01b031683529284019291840191600101615c33565b50909695505050505050565b600081518084526020808501945080840160005b8381101561540257815187529582019590820190600101615c78565b6001600160a01b03878116825260a06020808401829052908301879052600091889160c08501845b8a811015615ce3578435615ccf8161507b565b841682529382019390820190600101615cbc565b508581036040870152615cf6818a615c64565b93505050508281036060840152615d0d8186615c64565b915050826080830152979650505050505050565b600080835481600182811c915080831680615d3d57607f831692505b60208084108203615d5c57634e487b7160e01b86526022600452602486fd5b818015615d705760018114615d8557615db2565b60ff1986168952841515850289019650615db2565b60008a81526020902060005b86811015615daa5781548b820152908501908301615d91565b505084890196505b509498975050505050505050565b80820260008212600160ff1b84141615615ddc57615ddc615869565b8181058314821517610c2257610c22615869565b600082615dff57615dff615947565b600160ff1b821460001984141615615e1957615e19615869565b500590565b8082018281126000831280158216821582161715615e3e57615e3e615869565b505092915050565b60008251615e58818460208701615024565b919091019291505056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122068e9ddcfbd3c43085683c87112d80438c0cb8e8db0d4c7ebf93715cd6bbf957f64736f6c63430008130033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000094194de310b99d3c8a5b8c0768cfce7aef81d9be0000000000000000000000009b122361e8708be33b785e44fce4d6ca86ab6c5a000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e100000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002386f26fc10000
-----Decoded View---------------
Arg [0] : _relayer (address): 0x94194DE310b99d3c8a5b8C0768cFCE7Aef81D9BE
Arg [1] : _oracleModule (address): 0x9B122361E8708Be33B785e44FcE4d6ca86AB6C5a
Arg [2] : _governanceModule (address): 0xc6F50903a058f3807111619bD4B24cA64b8239E1
Arg [3] : _maxAumDeviationAllowed (uint16): 200
Arg [4] : _taxFactor (uint72): 0
Arg [5] : _managementFee (uint72): 10000000000000000
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 00000000000000000000000094194de310b99d3c8a5b8c0768cfce7aef81d9be
Arg [1] : 0000000000000000000000009b122361e8708be33b785e44fce4d6ca86ab6c5a
Arg [2] : 000000000000000000000000c6f50903a058f3807111619bd4b24ca64b8239e1
Arg [3] : 00000000000000000000000000000000000000000000000000000000000000c8
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [5] : 000000000000000000000000000000000000000000000000002386f26fc10000Loading...LoadingLoading...Loading
Loading...Loading
Loading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingLoading...LoadingOVERVIEW
Fyde enables the crypto ecosystem to diversify portfolios & treasuries, unlock token liquidity, and generate yield while retaining governance rights. The protocol introduces an innovation of the Liquid Vault that creates large multi-asset liquidity vaults directly accessible by governance token.
Multichain Portfolio | 26 Chains
Chain Token Portfolio % Price Amount Value ETH 16.14% $0.139036 1,429,514.2147 $198,753.94 ETH 8.69% $0.052871 2,023,158.8777 $106,966.43 ETH 6.15% $3,452.71 21.9228 $75,693.02 ETH 6.14% $4,062.09 18.6213 $75,641.41 ETH 5.09% $3,873.74 16.182 $62,685.05 ETH 4.79% $0.019783 2,978,334.8685 $58,920.91 ETH 3.62% $1.97 22,642.6585 $44,606.04 ETH 3.61% $3.49 12,722.7939 $44,402.55 ETH 3.41% $0.000012 3,504,867,973.3183 $41,953.27 ETH 3.26% $0.548477 73,139.3586 $40,115.26 ETH 3.09% $7.27 5,240.4005 $38,097.71 ETH 3.09% $0.306735 123,827.043 $37,982.09 ETH 3.02% $4.62 8,044.691 $37,166.47 ETH 2.96% $14.38 2,536.5911 $36,476.18 ETH 2.96% $1.1 33,272.9411 $36,433.87 ETH 2.82% $2,918.33 11.8949 $34,713.14 ETH 2.55% $0.005653 5,542,491.9042 $31,333.15 ETH 2.48% $0.017963 1,702,965.2958 $30,589.94 ETH 2.33% $0.049103 584,892.5017 $28,720.08 ETH 2.13% $321.42 81.6321 $26,238.2 ETH 2.02% $1 24,842.2646 $24,842.26 ETH 1.89% $0.214456 108,564.9292 $23,282.4 ETH 1.89% $2.17 10,700.1516 $23,219.33 ETH 1.81% $6.79 3,276.0367 $22,244.29 ETH 1.61% $0.01394 1,421,883.9678 $19,821.32 ETH 1.41% $99.43 174.942 $17,394.15 ETH 0.75% $1.1 8,446.7718 $9,257.66 ETH 0.12% $0.473221 3,092.0982 $1,463.25 ETH 0.06% $9.27 78.5994 $728.62 ETH 0.03% $2.42 171.9523 $416.12 ETH 0.03% $0.101341 3,592.1077 $364.03 ETH 0.03% $8.15 37.9283 $309.12 ETH 0.01% $65,011 0.00228069 $148.27 ETH <0.01% $0.999037 62.8567 $62.8 ETH <0.01% $1.62 19.8917 $32.22 ETH <0.01% $0.291707 105.3462 $30.73 ETH <0.01% $1 10.6546 $10.67 ETH <0.01% $0.999981 5.8709 $5.87 ETH <0.01% $0.084495 50.8714 $4.3 ETH <0.01% $0.999331 3.0768 $3.07 ETH <0.01% $18.36 0.1334 $2.45 ETH <0.01% $0.781945 0.9333 $0.7297 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.
Address QR Code
My Address - Private Name Tag or Note
My Name Tag:
Private Name Tags (up to 35 characters) can be used for easy identification of addressesPrivate Note:
A private note (up to 500 characters) can be attached to this address.
Please DO NOT store any passwords or private keys here.Compiler specific version warnings:
The compiled contract might be susceptible to VerbatimInvalidDeduplication (low-severity), FullInlinerNonExpressionSplitArgumentEvaluationOrder (low-severity), MissingSideEffectsOnSelectorAccess (low-severity) Solidity Compiler Bugs.
Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.Connect a Wallet
Connecting wallet for read function is optional, useful if you want to call certain functions or simply use your wallet's node.Before You Copy
This website uses cookies to improve your experience. By continuing to use this website, you agree to its Terms and Privacy Policy.