More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 254 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Claim Fee | 13404868 | 20 hrs ago | IN | 0 ETH | 0.00001921 | ||||
Repay Weekly Len... | 13368167 | 41 hrs ago | IN | 0 ETH | 0.00000744 | ||||
Repay Weekly Len... | 13368162 | 41 hrs ago | IN | 0 ETH | 0.00001339 | ||||
Claim Fee | 13363002 | 44 hrs ago | IN | 0 ETH | 0.00002029 | ||||
Claim Fee | 13321614 | 2 days ago | IN | 0 ETH | 0.00001507 | ||||
Claim Fee | 13280240 | 3 days ago | IN | 0 ETH | 0.00002327 | ||||
Claim Fee | 13238496 | 4 days ago | IN | 0 ETH | 0.00002273 | ||||
Claim Fee | 13196539 | 5 days ago | IN | 0 ETH | 0.00002262 | ||||
Claim Fee | 13154762 | 6 days ago | IN | 0 ETH | 0.00002849 | ||||
Claim Fee | 13112865 | 7 days ago | IN | 0 ETH | 0.00007748 | ||||
Unpause | 13092030 | 8 days ago | IN | 0 ETH | 0.00000367 | ||||
Pause | 13091387 | 8 days ago | IN | 0 ETH | 0.0000173 | ||||
Repay Weekly Len... | 13091381 | 8 days ago | IN | 0 ETH | 0.00001032 | ||||
Repay Weekly Len... | 13077625 | 8 days ago | IN | 0 ETH | 0.00001058 | ||||
Claim Fee | 13071665 | 8 days ago | IN | 0 ETH | 0.00001597 | ||||
Claim Fee | 13031471 | 9 days ago | IN | 0 ETH | 0.00002101 | ||||
Claim Fee | 12990879 | 10 days ago | IN | 0 ETH | 0.00003365 | ||||
Claim Fee | 12950470 | 11 days ago | IN | 0 ETH | 0.0000573 | ||||
Claim Fee | 12909850 | 12 days ago | IN | 0 ETH | 0.00013478 | ||||
Claim Fee | 12869417 | 13 days ago | IN | 0 ETH | 0.00003654 | ||||
Claim Fee | 12828121 | 14 days ago | IN | 0 ETH | 0.00005488 | ||||
Claim Fee | 12786626 | 15 days ago | IN | 0 ETH | 0.00002457 | ||||
Claim Fee | 12745146 | 16 days ago | IN | 0 ETH | 0.00001982 | ||||
Claim Fee | 12703674 | 17 days ago | IN | 0 ETH | 0.00001599 | ||||
Claim Fee | 12661737 | 18 days ago | IN | 0 ETH | 0.00005497 |
Latest 25 internal transactions (View All)
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440836 | 1 min ago | 0 ETH | ||||
13440799 | 3 mins ago | 0 ETH | ||||
13440799 | 3 mins ago | 0 ETH | ||||
13440799 | 3 mins ago | 0 ETH | ||||
13440799 | 3 mins ago | 0 ETH | ||||
13440799 | 3 mins ago | 0 ETH | ||||
13440799 | 3 mins ago | 0 ETH | ||||
13440799 | 3 mins ago | 0 ETH | ||||
13440799 | 3 mins ago | 0 ETH | ||||
13440514 | 12 mins ago | 0 ETH | ||||
13440514 | 12 mins ago | 0 ETH | ||||
13440514 | 12 mins ago | 0 ETH | ||||
13440514 | 12 mins ago | 0 ETH |
Loading...
Loading
Contract Name:
WooPPV2
Compiler Version
v0.8.14+commit.80d49f37
Optimization Enabled:
Yes with 20000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity =0.8.14; /* ░██╗░░░░░░░██╗░█████╗░░█████╗░░░░░░░███████╗██╗ ░██║░░██╗░░██║██╔══██╗██╔══██╗░░░░░░██╔════╝██║ ░╚██╗████╗██╔╝██║░░██║██║░░██║█████╗█████╗░░██║ ░░████╔═████║░██║░░██║██║░░██║╚════╝██╔══╝░░██║ ░░╚██╔╝░╚██╔╝░╚█████╔╝╚█████╔╝░░░░░░██║░░░░░██║ ░░░╚═╝░░░╚═╝░░░╚════╝░░╚════╝░░░░░░░╚═╝░░░░░╚═╝ * * MIT License * =========== * * Copyright (c) 2020 WooTrade * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ import "./interfaces/IWooracleV2_2.sol"; import "./interfaces/IWooPPV2.sol"; import "./interfaces/AggregatorV3Interface.sol"; import "./interfaces/IWooLendingManager.sol"; import {TransferHelper} from "@uniswap/v3-periphery/contracts/libraries/TransferHelper.sol"; // OpenZeppelin contracts import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol"; import {ReentrancyGuard} from "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import {IERC20} from "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import {Pausable} from "@openzeppelin/contracts/security/Pausable.sol"; import {IERC20Metadata} from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol"; // REMOVE IT IN PROD // import "hardhat/console.sol"; /// @title Woo pool for token swap, version 2. /// @notice the implementation class for interface IWooPPV2, mainly for query and swap tokens. contract WooPPV2 is Ownable, ReentrancyGuard, Pausable, IWooPPV2 { /* ----- Type declarations ----- */ struct DecimalInfo { uint64 priceDec; // 10**(price_decimal) uint64 quoteDec; // 10**(quote_decimal) uint64 baseDec; // 10**(base_decimal) } struct TokenInfo { uint192 reserve; // balance reserve uint16 feeRate; // 1 in 100000; 10 = 1bp = 0.01%; max = 65535 uint128 maxGamma; // max range of `balance * k` uint128 maxNotionalSwap; // max volume per swap } /* ----- State variables ----- */ address constant ETH_PLACEHOLDER_ADDR = 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE; uint256 public unclaimedFee; // NOTE: in quote token // wallet address --> is admin mapping(address => bool) public isAdmin; // wallet address --> is pause role mapping(address => bool) public isPauseRole; // token address --> fee rate mapping(address => TokenInfo) public tokenInfos; /// @inheritdoc IWooPPV2 address public immutable override quoteToken; IWooracleV2_2 public wooracle; address public feeAddr; mapping(address => IWooLendingManager) public lendManagers; /* ----- Modifiers ----- */ modifier onlyAdmin() { require(msg.sender == owner() || isAdmin[msg.sender], "WooPPV2: !admin"); _; } modifier onlyAdminOrPauseRole() { require(msg.sender == owner() || isAdmin[msg.sender] || isPauseRole[msg.sender], "WooPPV2: !isPauseRole"); _; } constructor(address _quoteToken) { quoteToken = _quoteToken; } function init(address _wooracle, address _feeAddr) external onlyOwner { require(address(wooracle) == address(0), "WooPPV2: INIT_INVALID"); wooracle = IWooracleV2_2(_wooracle); feeAddr = _feeAddr; } /* ----- External Functions ----- */ /// @inheritdoc IWooPPV2 function tryQuery( address fromToken, address toToken, uint256 fromAmount ) external view override returns (uint256 toAmount) { if (fromToken == quoteToken) { toAmount = _tryQuerySellQuote(toToken, fromAmount); } else if (toToken == quoteToken) { toAmount = _tryQuerySellBase(fromToken, fromAmount); } else { (toAmount, ) = _tryQueryBaseToBase(fromToken, toToken, fromAmount); } } /// @inheritdoc IWooPPV2 function query( address fromToken, address toToken, uint256 fromAmount ) external view override returns (uint256 toAmount) { if (fromToken == quoteToken) { toAmount = _tryQuerySellQuote(toToken, fromAmount); } else if (toToken == quoteToken) { toAmount = _tryQuerySellBase(fromToken, fromAmount); } else { uint256 swapFee; (toAmount, swapFee) = _tryQueryBaseToBase(fromToken, toToken, fromAmount); require(swapFee <= tokenInfos[quoteToken].reserve, "WooPPV2: INSUFF_QUOTE_FOR_SWAPFEE"); } require(toAmount <= tokenInfos[toToken].reserve, "WooPPV2: INSUFF_BALANCE"); } /// @inheritdoc IWooPPV2 function swap( address fromToken, address toToken, uint256 fromAmount, uint256 minToAmount, address to, address rebateTo ) external override returns (uint256 realToAmount) { if (fromToken == quoteToken) { // case 1: quoteToken --> baseToken realToAmount = _sellQuote(toToken, fromAmount, minToAmount, to, rebateTo); } else if (toToken == quoteToken) { // case 2: fromToken --> quoteToken realToAmount = _sellBase(fromToken, fromAmount, minToAmount, to, rebateTo); } else { // case 3: fromToken --> toToken (base to base) realToAmount = _swapBaseToBase(fromToken, toToken, fromAmount, minToAmount, to, rebateTo); } } /// @dev OKAY to be public method function claimFee() external nonReentrant { require(feeAddr != address(0), "WooPPV2: !feeAddr"); uint256 amountToTransfer = unclaimedFee; unclaimedFee = 0; TransferHelper.safeTransfer(quoteToken, feeAddr, amountToTransfer); } /// @inheritdoc IWooPPV2 /// @dev pool size = tokenInfo.reserve function poolSize(address token) public view override returns (uint256) { return tokenInfos[token].reserve; } /// @dev User pool balance (substracted unclaimed fee) function balance(address token) public view returns (uint256) { return token == quoteToken ? _rawBalance(token) - unclaimedFee : _rawBalance(token); } function decimalInfo(address baseToken) public view returns (DecimalInfo memory) { return DecimalInfo({ priceDec: uint64(10)**(IWooracleV2_2(wooracle).decimals(baseToken)), // 8 quoteDec: uint64(10)**(IERC20Metadata(quoteToken).decimals()), // 18 or 6 baseDec: uint64(10)**(IERC20Metadata(baseToken).decimals()) // 18 or 8 }); } /* ----- Admin Functions ----- */ function setWooracle(address _wooracle) external onlyAdmin { wooracle = IWooracleV2_2(_wooracle); emit WooracleUpdated(_wooracle); } function setFeeAddr(address _feeAddr) external onlyAdmin { feeAddr = _feeAddr; emit FeeAddrUpdated(_feeAddr); } function setFeeRate(address token, uint16 rate) external onlyAdmin { require(rate <= 1e5, "!rate"); tokenInfos[token].feeRate = rate; } function setMaxGamma(address token, uint128 maxGamma) external onlyAdmin { tokenInfos[token].maxGamma = maxGamma; } function setMaxNotionalSwap(address token, uint128 maxNotionalSwap) external onlyAdmin { tokenInfos[token].maxNotionalSwap = maxNotionalSwap; } function setTokenInfo( address token, uint16 _feeRate, uint128 _maxGamma, uint128 _maxNotionalSwap ) external onlyAdmin { tokenInfos[token].feeRate = _feeRate; tokenInfos[token].maxGamma = _maxGamma; tokenInfos[token].maxNotionalSwap = _maxNotionalSwap; } function pause() external onlyAdminOrPauseRole { super._pause(); } function unpause() external onlyAdmin { super._unpause(); } function setAdmin(address addr, bool flag) external onlyAdmin { require(addr != address(0), "WooPPV2: !admin"); isAdmin[addr] = flag; emit AdminUpdated(addr, flag); } function setPauseRole(address addr, bool flag) external onlyAdmin { isPauseRole[addr] = flag; emit PauseRoleUpdated(addr, flag); } function deposit(address token, uint256 amount) public override nonReentrant onlyAdmin { uint256 balanceBefore = balance(token); TransferHelper.safeTransferFrom(token, msg.sender, address(this), amount); uint256 amountReceived = balance(token) - balanceBefore; require(amountReceived >= amount, "AMOUNT_INSUFF"); tokenInfos[token].reserve = uint192(tokenInfos[token].reserve + amount); emit Deposit(token, msg.sender, amount); } function depositAll(address token) external onlyAdmin { deposit(token, IERC20(token).balanceOf(msg.sender)); } function repayWeeklyLending(address wantToken) external nonReentrant onlyAdmin returns (uint256 repaidAmount) { IWooLendingManager lendManager = lendManagers[wantToken]; lendManager.accureInterest(); uint256 amount = lendManager.weeklyRepayment(); address repaidToken = lendManager.want(); if (amount > 0) { tokenInfos[repaidToken].reserve = uint192(tokenInfos[repaidToken].reserve - amount); TransferHelper.safeApprove(repaidToken, address(lendManager), amount); repaidAmount = lendManager.repayWeekly(); TransferHelper.safeApprove(repaidToken, address(lendManager), 0); } emit Withdraw(repaidToken, address(lendManager), amount); } function repayPrincipal(address repaidToken, uint256 principalAmount) external nonReentrant onlyAdmin returns (uint256 repaidAmount) { IWooLendingManager lendManager = lendManagers[repaidToken]; lendManager.accureInterest(); uint256 interest = lendManager.borrowedInterest(); uint256 perfFee = (lendManager.perfRate() * interest) / 10000; uint256 amount = principalAmount + interest + perfFee; if (amount > 0) { tokenInfos[repaidToken].reserve = uint192(tokenInfos[repaidToken].reserve - amount); TransferHelper.safeApprove(repaidToken, address(lendManager), amount); repaidAmount = lendManager.repayPrincipal(principalAmount); TransferHelper.safeApprove(repaidToken, address(lendManager), 0); } emit Withdraw(repaidToken, address(lendManager), amount); } /// NOTE: Used for legacy lending manager only support `repay(amount)` method. /// e.g. lending managers on arbitrum, OP and etc /// https://arbiscan.io/address/0x5c7ff24fa7af62bc25ad6747a6193183b4bb7bc5#code function repayLegacy(address repaidToken, uint256 amount) external nonReentrant onlyAdmin { IWooLendingManager lendManager = lendManagers[repaidToken]; if (amount > 0) { tokenInfos[repaidToken].reserve = uint192(tokenInfos[repaidToken].reserve - amount); TransferHelper.safeApprove(repaidToken, address(lendManager), amount); lendManager.repay(amount); TransferHelper.safeApprove(repaidToken, address(lendManager), 0); } emit Withdraw(repaidToken, address(lendManager), amount); } function withdraw(address token, uint256 amount) public nonReentrant onlyAdmin { require(tokenInfos[token].reserve >= amount, "WooPPV2: !amount"); tokenInfos[token].reserve = uint192(tokenInfos[token].reserve - amount); TransferHelper.safeTransfer(token, owner(), amount); emit Withdraw(token, owner(), amount); } function withdrawAll(address token) external onlyAdmin { withdraw(token, poolSize(token)); } function skim(address token) public nonReentrant onlyAdmin { TransferHelper.safeTransfer(token, owner(), balance(token) - tokenInfos[token].reserve); } function skimMulTokens(address[] memory tokens) external onlyAdmin { unchecked { uint256 len = tokens.length; for (uint256 i = 0; i < len; i++) { skim(tokens[i]); } } } function sync(address token) external nonReentrant onlyAdmin { tokenInfos[token].reserve = uint192(balance(token)); } /* ----- Owner Functions ----- */ function setLendManager(IWooLendingManager _lendManager) external onlyOwner { lendManagers[_lendManager.want()] = _lendManager; isAdmin[address(_lendManager)] = true; emit AdminUpdated(address(_lendManager), true); } function migrateToNewPool(address token, address newPool) external onlyOwner { require(token != address(0), "WooPPV2: !token"); require(newPool != address(0), "WooPPV2: !newPool"); tokenInfos[token].reserve = 0; uint256 bal = balance(token); TransferHelper.safeApprove(token, newPool, bal); WooPPV2(newPool).depositAll(token); emit Migrate(token, newPool, bal); } function inCaseTokenGotStuck(address stuckToken) external onlyOwner { if (stuckToken == ETH_PLACEHOLDER_ADDR) { TransferHelper.safeTransferETH(msg.sender, address(this).balance); } else { uint256 amount = IERC20(stuckToken).balanceOf(address(this)); TransferHelper.safeTransfer(stuckToken, msg.sender, amount); } } /* ----- Private Functions ----- */ function _tryQuerySellBase(address baseToken, uint256 baseAmount) private view whenNotPaused returns (uint256 quoteAmount) { IWooracleV2_2.State memory state = IWooracleV2_2(wooracle).state(baseToken); (quoteAmount, ) = _calcQuoteAmountSellBase(baseToken, baseAmount, state); uint256 fee = (quoteAmount * tokenInfos[baseToken].feeRate) / 1e5; quoteAmount = quoteAmount - fee; } function _tryQuerySellQuote(address baseToken, uint256 quoteAmount) private view whenNotPaused returns (uint256 baseAmount) { uint256 swapFee = (quoteAmount * tokenInfos[baseToken].feeRate) / 1e5; quoteAmount = quoteAmount - swapFee; IWooracleV2_2.State memory state = IWooracleV2_2(wooracle).state(baseToken); (baseAmount, ) = _calcBaseAmountSellQuote(baseToken, quoteAmount, state); } function _tryQueryBaseToBase( address baseToken1, address baseToken2, uint256 base1Amount ) private view whenNotPaused returns (uint256 base2Amount, uint256 swapFee) { if ( baseToken1 == address(0) || baseToken2 == address(0) || baseToken1 == quoteToken || baseToken2 == quoteToken ) { return (0, 0); } IWooracleV2_2.State memory state1 = IWooracleV2_2(wooracle).state(baseToken1); IWooracleV2_2.State memory state2 = IWooracleV2_2(wooracle).state(baseToken2); uint64 spread = _maxUInt64(state1.spread, state2.spread) / 2; uint16 feeRate = _maxUInt16(tokenInfos[baseToken1].feeRate, tokenInfos[baseToken2].feeRate); state1.spread = spread; state2.spread = spread; (uint256 quoteAmount, ) = _calcQuoteAmountSellBase(baseToken1, base1Amount, state1); swapFee = (quoteAmount * feeRate) / 1e5; quoteAmount = quoteAmount - swapFee; (base2Amount, ) = _calcBaseAmountSellQuote(baseToken2, quoteAmount, state2); } function _sellBase( address baseToken, uint256 baseAmount, uint256 minQuoteAmount, address to, address rebateTo ) private nonReentrant whenNotPaused returns (uint256 quoteAmount) { require(baseToken != address(0), "WooPPV2: !baseToken"); require(to != address(0), "WooPPV2: !to"); require(baseToken != quoteToken, "WooPPV2: baseToken==quoteToken"); require(balance(baseToken) - tokenInfos[baseToken].reserve >= baseAmount, "WooPPV2: !BASE"); { uint256 newPrice; IWooracleV2_2.State memory state = IWooracleV2_2(wooracle).state(baseToken); (quoteAmount, newPrice) = _calcQuoteAmountSellBase(baseToken, baseAmount, state); IWooracleV2_2(wooracle).postPrice(baseToken, uint128(newPrice)); // console.log('Post new price:', newPrice, newPrice/1e8); } uint256 swapFee = (quoteAmount * tokenInfos[baseToken].feeRate) / 1e5; quoteAmount = quoteAmount - swapFee; require(quoteAmount >= minQuoteAmount, "WooPPV2: quoteAmount_LT_minQuoteAmount"); unclaimedFee = unclaimedFee + swapFee; tokenInfos[baseToken].reserve = uint192(tokenInfos[baseToken].reserve + baseAmount); tokenInfos[quoteToken].reserve = uint192(tokenInfos[quoteToken].reserve - quoteAmount - swapFee); if (to != address(this)) { TransferHelper.safeTransfer(quoteToken, to, quoteAmount); } emit WooSwap( baseToken, quoteToken, baseAmount, quoteAmount, msg.sender, to, rebateTo, quoteAmount + swapFee, swapFee ); } function _sellQuote( address baseToken, uint256 quoteAmount, uint256 minBaseAmount, address to, address rebateTo ) private nonReentrant whenNotPaused returns (uint256 baseAmount) { require(baseToken != address(0), "WooPPV2: !baseToken"); require(to != address(0), "WooPPV2: !to"); require(baseToken != quoteToken, "WooPPV2: baseToken==quoteToken"); require(balance(quoteToken) - tokenInfos[quoteToken].reserve >= quoteAmount, "WooPPV2: !QUOTE"); uint256 swapFee = (quoteAmount * tokenInfos[baseToken].feeRate) / 1e5; quoteAmount = quoteAmount - swapFee; unclaimedFee = unclaimedFee + swapFee; { uint256 newPrice; IWooracleV2_2.State memory state = IWooracleV2_2(wooracle).state(baseToken); (baseAmount, newPrice) = _calcBaseAmountSellQuote(baseToken, quoteAmount, state); IWooracleV2_2(wooracle).postPrice(baseToken, uint128(newPrice)); // console.log('Post new price:', newPrice, newPrice/1e8); require(baseAmount >= minBaseAmount, "WooPPV2: baseAmount_LT_minBaseAmount"); } tokenInfos[baseToken].reserve = uint192(tokenInfos[baseToken].reserve - baseAmount); tokenInfos[quoteToken].reserve = uint192(tokenInfos[quoteToken].reserve + quoteAmount); if (to != address(this)) { TransferHelper.safeTransfer(baseToken, to, baseAmount); } emit WooSwap( quoteToken, baseToken, quoteAmount + swapFee, baseAmount, msg.sender, to, rebateTo, quoteAmount + swapFee, swapFee ); } function _swapBaseToBase( address baseToken1, address baseToken2, uint256 base1Amount, uint256 minBase2Amount, address to, address rebateTo ) private nonReentrant whenNotPaused returns (uint256 base2Amount) { require(baseToken1 != address(0) && baseToken1 != quoteToken, "WooPPV2: !baseToken1"); require(baseToken2 != address(0) && baseToken2 != quoteToken, "WooPPV2: !baseToken2"); require(baseToken1 != baseToken2, "WooPPV2: base1==base2"); require(to != address(0), "WooPPV2: !to"); require(balance(baseToken1) - tokenInfos[baseToken1].reserve >= base1Amount, "WooPPV2: !BASE1_BALANCE"); IWooracleV2_2.State memory state1 = IWooracleV2_2(wooracle).state(baseToken1); IWooracleV2_2.State memory state2 = IWooracleV2_2(wooracle).state(baseToken2); uint256 swapFee; uint256 quoteAmount; { uint64 spread = _maxUInt64(state1.spread, state2.spread) / 2; uint16 feeRate = _maxUInt16(tokenInfos[baseToken1].feeRate, tokenInfos[baseToken2].feeRate); state1.spread = spread; state2.spread = spread; uint256 newBase1Price; (quoteAmount, newBase1Price) = _calcQuoteAmountSellBase(baseToken1, base1Amount, state1); IWooracleV2_2(wooracle).postPrice(baseToken1, uint128(newBase1Price)); // console.log('Post new base1 price:', newBase1Price, newBase1Price/1e8); swapFee = (quoteAmount * feeRate) / 1e5; } quoteAmount = quoteAmount - swapFee; unclaimedFee = unclaimedFee + swapFee; tokenInfos[quoteToken].reserve = uint192(tokenInfos[quoteToken].reserve - swapFee); tokenInfos[baseToken1].reserve = uint192(tokenInfos[baseToken1].reserve + base1Amount); { uint256 newBase2Price; (base2Amount, newBase2Price) = _calcBaseAmountSellQuote(baseToken2, quoteAmount, state2); IWooracleV2_2(wooracle).postPrice(baseToken2, uint128(newBase2Price)); // console.log('Post new base2 price:', newBase2Price, newBase2Price/1e8); require(base2Amount >= minBase2Amount, "WooPPV2: base2Amount_LT_minBase2Amount"); } tokenInfos[baseToken2].reserve = uint192(tokenInfos[baseToken2].reserve - base2Amount); if (to != address(this)) { TransferHelper.safeTransfer(baseToken2, to, base2Amount); } emit WooSwap( baseToken1, baseToken2, base1Amount, base2Amount, msg.sender, to, rebateTo, quoteAmount + swapFee, swapFee ); } /// @dev Get the pool's balance of the specified token /// @dev This function is gas optimized to avoid a redundant extcodesize check in addition to the returndatasize /// @dev forked and curtesy by Uniswap v3 core function _rawBalance(address token) private view returns (uint256) { (bool success, bytes memory data) = token.staticcall( abi.encodeWithSelector(IERC20.balanceOf.selector, address(this)) ); require(success && data.length >= 32, "WooPPV2: !BALANCE"); return abi.decode(data, (uint256)); } function _calcQuoteAmountSellBase( address baseToken, uint256 baseAmount, IWooracleV2_2.State memory state ) private view returns (uint256 quoteAmount, uint256 newPrice) { require(state.woFeasible, "WooPPV2: !ORACLE_FEASIBLE"); require(state.price > 0, "WooPPV2: !ORACE_PRICE"); DecimalInfo memory decs = decimalInfo(baseToken); // gamma = k * price * base_amount; and decimal 18 uint256 gamma; { uint256 notionalSwap = (baseAmount * state.price * decs.quoteDec) / decs.baseDec / decs.priceDec; require(notionalSwap <= tokenInfos[baseToken].maxNotionalSwap, "WooPPV2: !maxNotionalValue"); gamma = (baseAmount * state.price * state.coeff) / decs.priceDec / decs.baseDec; require(gamma <= tokenInfos[baseToken].maxGamma, "WooPPV2: !gamma"); // Formula: quoteAmount = baseAmount * oracle.price * (1 - oracle.k * baseAmount * oracle.price - oracle.spread) quoteAmount = (((baseAmount * state.price * decs.quoteDec) / decs.priceDec) * (uint256(1e18) - gamma - state.spread)) / 1e18 / decs.baseDec; } // newPrice = oracle.price * (1 - k * oracle.price * baseAmount) newPrice = ((uint256(1e18) - gamma) * state.price) / 1e18; } function _calcBaseAmountSellQuote( address baseToken, uint256 quoteAmount, IWooracleV2_2.State memory state ) private view returns (uint256 baseAmount, uint256 newPrice) { require(state.woFeasible, "WooPPV2: !ORACLE_FEASIBLE"); require(state.price > 0, "WooPPV2: !ORACE_PRICE"); DecimalInfo memory decs = decimalInfo(baseToken); // gamma = k * quote_amount; and decimal 18 uint256 gamma; { require(quoteAmount <= tokenInfos[baseToken].maxNotionalSwap, "WooPPV2: !maxNotionalValue"); gamma = (quoteAmount * state.coeff) / decs.quoteDec; require(gamma <= tokenInfos[baseToken].maxGamma, "WooPPV2: !gamma"); // Formula: baseAmount = quoteAmount / oracle.price * (1 - oracle.k * quoteAmount - oracle.spread) baseAmount = (((quoteAmount * decs.baseDec * decs.priceDec) / state.price) * (uint256(1e18) - gamma - state.spread)) / 1e18 / decs.quoteDec; } // new_price = oracle.price / (1 - k * quoteAmount) newPrice = (uint256(1e18) * state.price) / (uint256(1e18) - gamma); } function _maxUInt16(uint16 a, uint16 b) private pure returns (uint16) { return a > b ? a : b; } function _maxUInt64(uint64 a, uint64 b) private pure returns (uint64) { return a > b ? a : b; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { require(owner() == _msgSender(), "Ownable: caller is not the owner"); } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { _requireNotPaused(); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { _requirePaused(); _; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Throws if the contract is paused. */ function _requireNotPaused() internal view virtual { require(!paused(), "Pausable: paused"); } /** * @dev Throws if the contract is not paused. */ function _requirePaused() internal view virtual { require(paused(), "Pausable: not paused"); } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be _NOT_ENTERED require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == _ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts 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: 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) (token/ERC20/IERC20.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 amount) external returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.9.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) (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 // OpenZeppelin Contracts v4.4.1 (utils/Context.sol) pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.6.0; import '@openzeppelin/contracts/token/ERC20/IERC20.sol'; library TransferHelper { /// @notice Transfers tokens from the targeted address to the given destination /// @notice Errors with 'STF' if transfer fails /// @param token The contract address of the token to be transferred /// @param from The originating address from which the tokens will be transferred /// @param to The destination address of the transfer /// @param value The amount to be transferred function safeTransferFrom( address token, address from, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transferFrom.selector, from, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'STF'); } /// @notice Transfers tokens from msg.sender to a recipient /// @dev Errors with ST if transfer fails /// @param token The contract address of the token which will be transferred /// @param to The recipient of the transfer /// @param value The value of the transfer function safeTransfer( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.transfer.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'ST'); } /// @notice Approves the stipulated contract to spend the given allowance in the given token /// @dev Errors with 'SA' if transfer fails /// @param token The contract address of the token to be approved /// @param to The target of the approval /// @param value The amount of the given token the target will be allowed to spend function safeApprove( address token, address to, uint256 value ) internal { (bool success, bytes memory data) = token.call(abi.encodeWithSelector(IERC20.approve.selector, to, value)); require(success && (data.length == 0 || abi.decode(data, (bool))), 'SA'); } /// @notice Transfers ETH to the recipient address /// @dev Fails with `STE` /// @param to The destination of the transfer /// @param value The value to be transferred function safeTransferETH(address to, uint256 value) internal { (bool success, ) = to.call{value: value}(new bytes(0)); require(success, 'STE'); } }
// SPDX-License-Identifier: MIT pragma solidity =0.8.14; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); /// getRoundData and latestRoundData should both raise "No data present" /// if they do not have data to report, instead of returning unset values /// which could be misinterpreted as actual reported values. function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
// SPDX-License-Identifier: MIT pragma solidity =0.8.14; /* ░██╗░░░░░░░██╗░█████╗░░█████╗░░░░░░░███████╗██╗ ░██║░░██╗░░██║██╔══██╗██╔══██╗░░░░░░██╔════╝██║ ░╚██╗████╗██╔╝██║░░██║██║░░██║█████╗█████╗░░██║ ░░████╔═████║░██║░░██║██║░░██║╚════╝██╔══╝░░██║ ░░╚██╔╝░╚██╔╝░╚█████╔╝╚█████╔╝░░░░░░██║░░░░░██║ ░░░╚═╝░░░╚═╝░░░╚════╝░░╚════╝░░░░░░░╚═╝░░░░░╚═╝ * * MIT License * =========== * * Copyright (c) 2022 WooTrade * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /// @title Interface for WooLendingManager interface IWooLendingManager { function want() external returns (address); function repayWeekly() external returns (uint256 repaidAmount); function repayAll() external returns (uint256 repaidAmount); function repay(uint256 amount) external; /// @notice Borrow the fund from super charger and then deposit directly into WooPP. /// @param amount the borrowing amount function borrow(uint256 amount) external; function accureInterest() external; function weeklyRepayment() external view returns (uint256 repayAmount); function weeklyRepaymentBreakdown() external view returns ( uint256 repayAmount, uint256 principal, uint256 interest, uint256 perfFee ); function borrowedInterest() external view returns (uint256); function perfRate() external view returns (uint256); function repayPrincipal(uint256 _principal) external returns (uint256 repaidAmount); }
// SPDX-License-Identifier: MIT pragma solidity =0.8.14; /* ░██╗░░░░░░░██╗░█████╗░░█████╗░░░░░░░███████╗██╗ ░██║░░██╗░░██║██╔══██╗██╔══██╗░░░░░░██╔════╝██║ ░╚██╗████╗██╔╝██║░░██║██║░░██║█████╗█████╗░░██║ ░░████╔═████║░██║░░██║██║░░██║╚════╝██╔══╝░░██║ ░░╚██╔╝░╚██╔╝░╚█████╔╝╚█████╔╝░░░░░░██║░░░░░██║ ░░░╚═╝░░░╚═╝░░░╚════╝░░╚════╝░░░░░░░╚═╝░░░░░╚═╝ * * MIT License * =========== * * Copyright (c) 2020 WooTrade * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /// @title Woo private pool for swap. /// @notice Use this contract to directly interfact with woo's synthetic proactive /// marketing making pool. /// @author woo.network interface IWooPPV2 { /* ----- Events ----- */ event Deposit(address indexed token, address indexed sender, uint256 amount); event Withdraw(address indexed token, address indexed receiver, uint256 amount); event Migrate(address indexed token, address indexed receiver, uint256 amount); event AdminUpdated(address indexed addr, bool flag); event PauseRoleUpdated(address indexed addr, bool flag); event FeeAddrUpdated(address indexed newFeeAddr); event WooracleUpdated(address indexed newWooracle); event WooSwap( address indexed fromToken, address indexed toToken, uint256 fromAmount, uint256 toAmount, address from, address indexed to, address rebateTo, uint256 swapVol, uint256 swapFee ); /* ----- External Functions ----- */ /// @notice The quote token address (immutable). /// @return address of quote token function quoteToken() external view returns (address); /// @notice Gets the pool size of the specified token (swap liquidity). /// @param token the token address /// @return the pool size function poolSize(address token) external view returns (uint256); /// @notice Query the amount to swap `fromToken` to `toToken`, without checking the pool reserve balance. /// @param fromToken the from token /// @param toToken the to token /// @param fromAmount the amount of `fromToken` to swap /// @return toAmount the swapped amount of `toToken` function tryQuery( address fromToken, address toToken, uint256 fromAmount ) external view returns (uint256 toAmount); /// @notice Query the amount to swap `fromToken` to `toToken`, with checking the pool reserve balance. /// @dev tx reverts when 'toToken' balance is insufficient. /// @param fromToken the from token /// @param toToken the to token /// @param fromAmount the amount of `fromToken` to swap /// @return toAmount the swapped amount of `toToken` function query( address fromToken, address toToken, uint256 fromAmount ) external view returns (uint256 toAmount); /// @notice Swap `fromToken` to `toToken`. /// @param fromToken the from token /// @param toToken the to token /// @param fromAmount the amount of `fromToken` to swap /// @param minToAmount the minimum amount of `toToken` to receive /// @param to the destination address /// @param rebateTo the rebate address (optional, can be address ZERO) /// @return realToAmount the amount of toToken to receive function swap( address fromToken, address toToken, uint256 fromAmount, uint256 minToAmount, address to, address rebateTo ) external returns (uint256 realToAmount); /// @notice Deposit the specified token into the liquidity pool of WooPPV2. /// @param token the token to deposit /// @param amount the deposit amount function deposit(address token, uint256 amount) external; }
// SPDX-License-Identifier: MIT pragma solidity =0.8.14; /* ░██╗░░░░░░░██╗░█████╗░░█████╗░░░░░░░███████╗██╗ ░██║░░██╗░░██║██╔══██╗██╔══██╗░░░░░░██╔════╝██║ ░╚██╗████╗██╔╝██║░░██║██║░░██║█████╗█████╗░░██║ ░░████╔═████║░██║░░██║██║░░██║╚════╝██╔══╝░░██║ ░░╚██╔╝░╚██╔╝░╚█████╔╝╚█████╔╝░░░░░░██║░░░░░██║ ░░░╚═╝░░░╚═╝░░░╚════╝░░╚════╝░░░░░░░╚═╝░░░░░╚═╝ * * MIT License * =========== * * Copyright (c) 2020 WooTrade * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ /// @title The oracle V2.2 interface by Woo.Network. /// @notice update and posted the latest price info by Woo. interface IWooracleV2_2 { struct State { uint128 price; uint64 spread; uint64 coeff; bool woFeasible; } // /// @notice Wooracle spread value // function woSpread(address base) external view returns (uint64); // /// @notice Wooracle coeff value // function woCoeff(address base) external view returns (uint64); // /// @notice Wooracle state for the specified base token // function woState(address base) external view returns (State memory); // /// @notice Chainlink oracle address for the specified base token // function cloAddress(address base) external view returns (address clo); // /// @notice Wooracle price of the base token // function woPrice(address base) external view returns (uint128 price, uint256 timestamp); /// @notice ChainLink price of the base token / quote token function cloPrice(address base) external view returns (uint256 price, uint256 timestamp); /// @notice Returns Woooracle price if available, otherwise fallback to ChainLink function price(address base) external view returns (uint256 priceNow, bool feasible); /// @notice Updates the Wooracle price for the specified base token function postPrice(address base, uint128 _price) external; /// Updates the state of the given base token. /// @param _base baseToken address /// @param _price the new prices /// @param _spread the new spreads /// @param _coeff the new slippage coefficent function postState( address _base, uint128 _price, uint64 _spread, uint64 _coeff ) external; /// @notice State of the specified base token. function state(address base) external view returns (State memory); /// @notice The price decimal for the specified base token (e.g. 8) function decimals(address base) external view returns (uint8); /// @notice The quote token for calculating WooPP query price function quoteToken() external view returns (address); /// @notice last updated timestamp function timestamp() external view returns (uint256); /// @notice Flag for Wooracle price feasible function isWoFeasible(address base) external view returns (bool); // /// @notice Flag for account admin // function isAdmin(address account) external view returns (bool); }
{ "optimizer": { "enabled": true, "runs": 20000 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_quoteToken","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"flag","type":"bool"}],"name":"AdminUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Deposit","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newFeeAddr","type":"address"}],"name":"FeeAddrUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Migrate","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"bool","name":"flag","type":"bool"}],"name":"PauseRoleUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"fromToken","type":"address"},{"indexed":true,"internalType":"address","name":"toToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"fromAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toAmount","type":"uint256"},{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"address","name":"rebateTo","type":"address"},{"indexed":false,"internalType":"uint256","name":"swapVol","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"swapFee","type":"uint256"}],"name":"WooSwap","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newWooracle","type":"address"}],"name":"WooracleUpdated","type":"event"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"balance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"baseToken","type":"address"}],"name":"decimalInfo","outputs":[{"components":[{"internalType":"uint64","name":"priceDec","type":"uint64"},{"internalType":"uint64","name":"quoteDec","type":"uint64"},{"internalType":"uint64","name":"baseDec","type":"uint64"}],"internalType":"struct WooPPV2.DecimalInfo","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"deposit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"depositAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeAddr","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"stuckToken","type":"address"}],"name":"inCaseTokenGotStuck","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wooracle","type":"address"},{"internalType":"address","name":"_feeAddr","type":"address"}],"name":"init","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isAdmin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isPauseRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"lendManagers","outputs":[{"internalType":"contract IWooLendingManager","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"address","name":"newPool","type":"address"}],"name":"migrateToNewPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"poolSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"uint256","name":"fromAmount","type":"uint256"}],"name":"query","outputs":[{"internalType":"uint256","name":"toAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"quoteToken","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"repaidToken","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"repayLegacy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"repaidToken","type":"address"},{"internalType":"uint256","name":"principalAmount","type":"uint256"}],"name":"repayPrincipal","outputs":[{"internalType":"uint256","name":"repaidAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"wantToken","type":"address"}],"name":"repayWeeklyLending","outputs":[{"internalType":"uint256","name":"repaidAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"flag","type":"bool"}],"name":"setAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_feeAddr","type":"address"}],"name":"setFeeAddr","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint16","name":"rate","type":"uint16"}],"name":"setFeeRate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IWooLendingManager","name":"_lendManager","type":"address"}],"name":"setLendManager","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"maxGamma","type":"uint128"}],"name":"setMaxGamma","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint128","name":"maxNotionalSwap","type":"uint128"}],"name":"setMaxNotionalSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"flag","type":"bool"}],"name":"setPauseRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint16","name":"_feeRate","type":"uint16"},{"internalType":"uint128","name":"_maxGamma","type":"uint128"},{"internalType":"uint128","name":"_maxNotionalSwap","type":"uint128"}],"name":"setTokenInfo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wooracle","type":"address"}],"name":"setWooracle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"skim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokens","type":"address[]"}],"name":"skimMulTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"uint256","name":"fromAmount","type":"uint256"},{"internalType":"uint256","name":"minToAmount","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"address","name":"rebateTo","type":"address"}],"name":"swap","outputs":[{"internalType":"uint256","name":"realToAmount","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"sync","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"tokenInfos","outputs":[{"internalType":"uint192","name":"reserve","type":"uint192"},{"internalType":"uint16","name":"feeRate","type":"uint16"},{"internalType":"uint128","name":"maxGamma","type":"uint128"},{"internalType":"uint128","name":"maxNotionalSwap","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"fromToken","type":"address"},{"internalType":"address","name":"toToken","type":"address"},{"internalType":"uint256","name":"fromAmount","type":"uint256"}],"name":"tryQuery","outputs":[{"internalType":"uint256","name":"toAmount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unclaimedFee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"}],"name":"withdrawAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wooracle","outputs":[{"internalType":"contract IWooracleV2_2","name":"","type":"address"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60a06040523480156200001157600080fd5b5060405162005f2138038062005f218339810160408190526200003491620000af565b6200003f336200005f565b600180556002805460ff191690556001600160a01b0316608052620000e1565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b600060208284031215620000c257600080fd5b81516001600160a01b0381168114620000da57600080fd5b9392505050565b608051615d6e620001b36000396000818161033f015281816112300152818161127d015281816115a30152818161187801528181611cff01528181611d4901528181611fa2015281816126a0015281816126ea01528181612742015281816131b601528181613237015281816135a3015281816135df01528181613681015281816137f101528181613bbd01528181613c0501528181613c8b01528181613cbd01528181613d4701528181613ddd01528181614252015281816142a8015281816149d50152614a110152615d6e6000f3fe608060405234801561001057600080fd5b50600436106102e85760003560e01c8063a1ae849011610191578063e1a4e72a116100e3578063f2fde38b11610097578063fa09e63011610071578063fa09e63014610730578063fa75d16014610743578063fc60fb5d1461078657600080fd5b8063f2fde38b146106f7578063f3fef3a31461070a578063f58a435f1461071d57600080fd5b8063e4d43ec1116100c8578063e4d43ec1146106c8578063ebc80f13146106d1578063f09a4016146106e457600080fd5b8063e1a4e72a146106a2578063e3d670d7146106b557600080fd5b8063b2e693d311610145578063bc8530f91161011f578063bc8530f914610669578063ce824f191461067c578063d6285b7f1461068f57600080fd5b8063b2e693d314610549578063ba46ae7214610572578063bc25cf771461065657600080fd5b8063a584119411610176578063a584119414610510578063a8a4ff6a14610523578063b2855b4f1461053657600080fd5b8063a1ae8490146104b7578063a26db1a7146104ca57600080fd5b8063637e10cb1161024a5780637f0eec02116101fe578063966fb4c3116101d8578063966fb4c31461048957806399d32fc41461049c5780639f0d5f27146104a457600080fd5b80637f0eec021461045d5780638456cb59146104705780638da5cb5b1461047857600080fd5b8063686f30b01161022f578063686f30b014610421578063715018a6146104345780637dc203821461043c57600080fd5b8063637e10cb146103fb57806368078eed1461040e57600080fd5b80633f4ba83a116102a15780634b0bddd2116102865780634b0bddd2146103ca5780635905d23c146103dd5780635c975abb146103f057600080fd5b80633f4ba83a146103af57806347e7ef24146103b757600080fd5b8063217a4b70116102d2578063217a4b701461033a57806324d7806c1461037957806339e7fddc1461039c57600080fd5b80622259b4146102ed5780630426d97514610325575b600080fd5b6103106102fb3660046155f9565b60056020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b610338610333366004615616565b610799565b005b6103617f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b03909116815260200161031c565b6103106103873660046155f9565b60046020526000908152604090205460ff1681565b600854610361906001600160a01b031681565b61033861096c565b6103386103c536600461564f565b6109ea565b6103386103d8366004615689565b610bc9565b6103386103eb366004615689565b610d11565b60025460ff16610310565b61033861040936600461564f565b610dfb565b61033861041c3660046156c9565b611016565b61033861042f36600461571c565b611149565b61033861121a565b61044f61044a36600461574a565b61122c565b60405190815260200161031c565b61033861046b366004615838565b6112dc565b61033861138c565b6000546001600160a01b0316610361565b6103386104973660046158ea565b611422565b610338611531565b6103386104b23660046155f9565b6115dc565b6103386104c53660046155f9565b6116da565b6104dd6104d83660046155f9565b6117b0565b60408051825167ffffffffffffffff9081168252602080850151821690830152928201519092169082015260600161031c565b61033861051e3660046155f9565b611991565b61033861053136600461571c565b611a7c565b6103386105443660046155f9565b611b3f565b6103616105573660046155f9565b6009602052600090815260409020546001600160a01b031681565b6106006105803660046155f9565b6006602052600090815260409020805460019091015477ffffffffffffffffffffffffffffffffffffffffffffffff8216917801000000000000000000000000000000000000000000000000900461ffff16906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041684565b6040805177ffffffffffffffffffffffffffffffffffffffffffffffff909516855261ffff90931660208501526fffffffffffffffffffffffffffffffff9182169284019290925216606082015260800161031c565b6103386106643660046155f9565b611c15565b600754610361906001600160a01b031681565b61044f61068a366004615944565b611cfb565b61033861069d3660046155f9565b611da0565b6103386106b03660046155f9565b611ecb565b61044f6106c33660046155f9565b611f9e565b61044f60035481565b61044f6106df3660046155f9565b612003565b6103386106f2366004615616565b61234e565b6103386107053660046155f9565b6123f5565b61033861071836600461564f565b612482565b61044f61072b366004615944565b61269c565b61033861073e3660046155f9565b612889565b61044f6107513660046155f9565b6001600160a01b031660009081526006602052604090205477ffffffffffffffffffffffffffffffffffffffffffffffff1690565b61044f61079436600461564f565b61293a565b6107a1612cd0565b6001600160a01b0382166107fc5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a2021746f6b656e000000000000000000000000000000000060448201526064015b60405180910390fd5b6001600160a01b0381166108525760405162461bcd60e51b815260206004820152601160248201527f576f6f505056323a20216e6577506f6f6c00000000000000000000000000000060448201526064016107f3565b6001600160a01b038216600090815260066020526040812080547fffffffffffffffff00000000000000000000000000000000000000000000000016905561089983611f9e565b90506108a6838383612d2a565b6040517f9f0d5f270000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152831690639f0d5f2790602401600060405180830381600087803b15801561090257600080fd5b505af1158015610916573d6000803e3d6000fd5b50505050816001600160a01b0316836001600160a01b03167f18df02dcc52b9c494f391df09661519c0069bd8540141946280399408205ca1a8360405161095f91815260200190565b60405180910390a3505050565b6000546001600160a01b031633148061099457503360009081526004602052604090205460ff165b6109e05760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6109e8612e73565b565b6109f2612ee3565b6000546001600160a01b0316331480610a1a57503360009081526004602052604090205460ff165b610a665760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6000610a7183611f9e565b9050610a7f83333085612f3c565b600081610a8b85611f9e565b610a9591906159b4565b905082811015610ae75760405162461bcd60e51b815260206004820152600d60248201527f414d4f554e545f494e535546460000000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038416600090815260066020526040902054610b2590849077ffffffffffffffffffffffffffffffffffffffffffffffff166159cb565b6001600160a01b03851660008181526006602090815260409182902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff95909516949094179093555185815233927f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62910160405180910390a35050610bc560018055565b5050565b6000546001600160a01b0316331480610bf157503360009081526004602052604090205460ff165b610c3d5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038216610c935760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b03821660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f235bc17e7930760029e9f4d860a2a8089976de5b381cf8380fc11c1d88a1113391015b60405180910390a25050565b6000546001600160a01b0316331480610d3957503360009081526004602052604090205460ff165b610d855760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b03821660008181526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f949c0260fa3a6145f57958b7bf0efeb5edb4d3e1e573353a16e69aea2450883d9101610d05565b610e03612ee3565b6000546001600160a01b0316331480610e2b57503360009081526004602052604090205460ff165b610e775760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b03808316600090815260096020526040902054168115610fbf576001600160a01b038316600090815260066020526040902054610ed690839077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b038416600090815260066020526040902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff92909216919091179055610f40838284612d2a565b6040517f371fd8e6000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0382169063371fd8e690602401600060405180830381600087803b158015610f9b57600080fd5b505af1158015610faf573d6000803e3d6000fd5b50505050610fbf83826000612d2a565b806001600160a01b0316836001600160a01b03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb8460405161100491815260200190565b60405180910390a350610bc560018055565b6000546001600160a01b031633148061103e57503360009081526004602052604090205460ff165b61108a5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b620186a08161ffff1611156110e15760405162461bcd60e51b815260206004820152600560248201527f217261746500000000000000000000000000000000000000000000000000000060448201526064016107f3565b6001600160a01b039091166000908152600660205260409020805461ffff9092167801000000000000000000000000000000000000000000000000027fffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055565b6000546001600160a01b031633148061117157503360009081526004602052604090205460ff165b6111bd5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b0391909116600090815260066020526040902060010180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff909216919091179055565b611222612cd0565b6109e8600061308e565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b03160361127b5761127486868686866130f6565b90506112d2565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b0316036112c1576112748786868686613731565b6112cf878787878787613d20565b90505b9695505050505050565b6000546001600160a01b031633148061130457503360009081526004602052604090205460ff165b6113505760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b805160005b818110156113875761137f838281518110611372576113726159e3565b6020026020010151611c15565b600101611355565b505050565b6000546001600160a01b03163314806113b457503360009081526004602052604090205460ff165b806113ce57503360009081526005602052604090205460ff165b61141a5760405162461bcd60e51b815260206004820152601560248201527f576f6f505056323a202169735061757365526f6c65000000000000000000000060448201526064016107f3565b6109e86145fa565b6000546001600160a01b031633148061144a57503360009081526004602052604090205460ff165b6114965760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b039093166000908152600660205260409020805461ffff9093167801000000000000000000000000000000000000000000000000027fffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffff9093169290921782556fffffffffffffffffffffffffffffffff92831670010000000000000000000000000000000002921691909117600190910155565b611539612ee3565b6008546001600160a01b03166115915760405162461bcd60e51b815260206004820152601160248201527f576f6f505056323a20216665654164647200000000000000000000000000000060448201526064016107f3565b6003805460009091556008546115d2907f0000000000000000000000000000000000000000000000000000000000000000906001600160a01b031683614655565b506109e860018055565b6000546001600160a01b031633148061160457503360009081526004602052604090205460ff165b6116505760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201526116d79082906001600160a01b038216906370a0823190602401602060405180830381865afa1580156116b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c59190615a12565b50565b6000546001600160a01b031633148061170257503360009081526004602052604090205460ff165b61174e5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b600780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f59ddfdd1bf7e3ea08a07e8aaa1fe2ce9c840fab69fe5ede6ea727a45eb42fc6690600090a250565b6040805160608082018352600080835260208301819052828401528251908101928390526007547fd449a832000000000000000000000000000000000000000000000000000000009093526001600160a01b0384811660648301529192909182911663d449a83260848301602060405180830381865afa158015611838573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185c9190615a2b565b61186790600a615b6a565b67ffffffffffffffff1681526020017f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f89190615a2b565b61190390600a615b6a565b67ffffffffffffffff168152602001836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611950573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119749190615a2b565b61197f90600a615b6a565b67ffffffffffffffff16905292915050565b611999612ee3565b6000546001600160a01b03163314806119c157503360009081526004602052604090205460ff165b611a0d5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b611a1681611f9e565b6001600160a01b038216600090815260066020526040902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff929092169190911790556001805550565b6000546001600160a01b0316331480611aa457503360009081526004602052604090205460ff165b611af05760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b03909116600090815260066020526040902060010180546fffffffffffffffffffffffffffffffff928316700100000000000000000000000000000000029216919091179055565b6000546001600160a01b0316331480611b6757503360009081526004602052604090205460ff165b611bb35760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b600880547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f76f97b3f5ffcc8d8d9577d141751a7bed446b46d837fbc81b5c01c165bbfbbf490600090a250565b611c1d612ee3565b6000546001600160a01b0316331480611c4557503360009081526004602052604090205460ff165b611c915760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b611cf281611ca76000546001600160a01b031690565b6001600160a01b03841660009081526006602052604090205477ffffffffffffffffffffffffffffffffffffffffffffffff16611ce385611f9e565b611ced91906159b4565b614655565b6116d760018055565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b031603611d4757611d408383614797565b9050611d99565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b031603611d8a57611d4084836148a3565b611d958484846149a5565b5090505b9392505050565b611da8612cd0565b8060096000836001600160a01b0316631f1fcd516040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e119190615b83565b6001600160a01b0390811682526020808301939093526040918201600090812080547fffffffffffffffffffffffff000000000000000000000000000000000000000016958316959095179094558416808452600483529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915590519081527f235bc17e7930760029e9f4d860a2a8089976de5b381cf8380fc11c1d88a11133910160405180910390a250565b611ed3612cd0565b7fffffffffffffffffffffffff11111111111111111111111111111111111111126001600160a01b03821601611f0d576116d73347614c53565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611f6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f919190615a12565b9050610bc5823383614655565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b031614611fe757611fe282614d10565b611ffd565b600354611ff383614d10565b611ffd91906159b4565b92915050565b600061200d612ee3565b6000546001600160a01b031633148061203557503360009081526004602052604090205460ff165b6120815760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038083166000908152600960205260408082205481517fa373ed4e0000000000000000000000000000000000000000000000000000000081529151931692839263a373ed4e926004808201939182900301818387803b1580156120ea57600080fd5b505af11580156120fe573d6000803e3d6000fd5b505050506000816001600160a01b031663f077cbab6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612142573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121669190615a12565b90506000826001600160a01b0316631f1fcd516040518163ffffffff1660e01b81526004016020604051808303816000875af11580156121aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ce9190615b83565b905081156122f0576001600160a01b03811660009081526006602052604090205461221490839077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b038216600090815260066020526040902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff9290921691909117905561227e818484612d2a565b826001600160a01b031663c1ae359a6040518163ffffffff1660e01b81526004016020604051808303816000875af11580156122be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e29190615a12565b93506122f081846000612d2a565b826001600160a01b0316816001600160a01b03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb8460405161233591815260200190565b60405180910390a350505061234960018055565b919050565b612356612cd0565b6007546001600160a01b0316156123af5760405162461bcd60e51b815260206004820152601560248201527f576f6f505056323a20494e49545f494e56414c4944000000000000000000000060448201526064016107f3565b600780546001600160a01b039384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560088054929093169116179055565b6123fd612cd0565b6001600160a01b0381166124795760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107f3565b6116d78161308e565b61248a612ee3565b6000546001600160a01b03163314806124b257503360009081526004602052604090205460ff165b6124fe5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b03821660009081526006602052604090205477ffffffffffffffffffffffffffffffffffffffffffffffff168111156125805760405162461bcd60e51b815260206004820152601060248201527f576f6f505056323a2021616d6f756e740000000000000000000000000000000060448201526064016107f3565b6001600160a01b0382166000908152600660205260409020546125be90829077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b0383166000908152600660205260409020805477ffffffffffffffffffffffffffffffffffffffffffffffff929092167fffffffffffffffff00000000000000000000000000000000000000000000000090921691909117905561263b826126356000546001600160a01b031690565b83614655565b6000546001600160a01b03166001600160a01b0316826001600160a01b03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb8360405161268b91815260200190565b60405180910390a3610bc560018055565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b0316036126e8576126e18383614797565b9050612807565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b03160361272b576126e184836148a3565b60006127388585856149a5565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016600090815260066020526040902054919350915077ffffffffffffffffffffffffffffffffffffffffffffffff168111156128055760405162461bcd60e51b815260206004820152602160248201527f576f6f505056323a20494e535546465f51554f54455f464f525f53574150464560448201527f450000000000000000000000000000000000000000000000000000000000000060648201526084016107f3565b505b6001600160a01b03831660009081526006602052604090205477ffffffffffffffffffffffffffffffffffffffffffffffff16811115611d995760405162461bcd60e51b815260206004820152601760248201527f576f6f505056323a20494e535546465f42414c414e434500000000000000000060448201526064016107f3565b6000546001600160a01b03163314806128b157503360009081526004602052604090205460ff165b6128fd5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6116d781610718836001600160a01b031660009081526006602052604090205477ffffffffffffffffffffffffffffffffffffffffffffffff1690565b6000612944612ee3565b6000546001600160a01b031633148061296c57503360009081526004602052604090205460ff165b6129b85760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038084166000908152600960205260408082205481517fa373ed4e0000000000000000000000000000000000000000000000000000000081529151931692839263a373ed4e926004808201939182900301818387803b158015612a2157600080fd5b505af1158015612a35573d6000803e3d6000fd5b505050506000816001600160a01b03166352c49c446040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9d9190615a12565b9050600061271082846001600160a01b031663e5e2abf56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b079190615a12565b612b119190615ba0565b612b1b9190615c0c565b9050600081612b2a84886159cb565b612b3491906159cb565b90508015612c76576001600160a01b038716600090815260066020526040902054612b7a90829077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b038816600090815260066020526040902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff92909216919091179055612be4878583612d2a565b6040517f3560df8c000000000000000000000000000000000000000000000000000000008152600481018790526001600160a01b03851690633560df8c906024016020604051808303816000875af1158015612c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c689190615a12565b9450612c7687856000612d2a565b836001600160a01b0316876001600160a01b03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb83604051612cbb91815260200190565b60405180910390a350505050611ffd60018055565b6000546001600160a01b031633146109e85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107f3565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151600092839290871691612db49190615c20565b6000604051808303816000865af19150503d8060008114612df1576040519150601f19603f3d011682016040523d82523d6000602084013e612df6565b606091505b5091509150818015612e20575080511580612e20575080806020019051810190612e209190615c5b565b612e6c5760405162461bcd60e51b815260206004820152600260248201527f534100000000000000000000000000000000000000000000000000000000000060448201526064016107f3565b5050505050565b612e7b614e51565b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600260015403612f355760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107f3565b6002600155565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691612fce9190615c20565b6000604051808303816000865af19150503d806000811461300b576040519150601f19603f3d011682016040523d82523d6000602084013e613010565b606091505b509150915081801561303a57508051158061303a57508080602001905181019061303a9190615c5b565b6130865760405162461bcd60e51b815260206004820152600360248201527f535446000000000000000000000000000000000000000000000000000000000060448201526064016107f3565b505050505050565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000613100612ee3565b613108614ea3565b6001600160a01b03861661315e5760405162461bcd60e51b815260206004820152601360248201527f576f6f505056323a202162617365546f6b656e0000000000000000000000000060448201526064016107f3565b6001600160a01b0383166131b45760405162461bcd60e51b815260206004820152600c60248201527f576f6f505056323a2021746f000000000000000000000000000000000000000060448201526064016107f3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b0316036132355760405162461bcd60e51b815260206004820152601e60248201527f576f6f505056323a2062617365546f6b656e3d3d71756f7465546f6b656e000060448201526064016107f3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b038116600090815260066020526040902054869177ffffffffffffffffffffffffffffffffffffffffffffffff9091169061329790611f9e565b6132a191906159b4565b10156132ef5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202151554f5445000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038616600090815260066020526040812054620186a090613337907801000000000000000000000000000000000000000000000000900461ffff1688615ba0565b6133419190615c0c565b905061334d81876159b4565b95508060035461335d91906159cb565b6003556007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015260009283929116906331e658a590602401608060405180830381865afa1580156133c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133eb9190615c90565b90506133f8898983614ef6565b6007546040517fd5bade070000000000000000000000000000000000000000000000000000000081526001600160a01b038d811660048301526fffffffffffffffffffffffffffffffff84166024830152939750919450919091169063d5bade0790604401600060405180830381600087803b15801561347757600080fd5b505af115801561348b573d6000803e3d6000fd5b50505050868410156135045760405162461bcd60e51b8152602060048201526024808201527f576f6f505056323a2062617365416d6f756e745f4c545f6d696e42617365416d60448201527f6f756e740000000000000000000000000000000000000000000000000000000060648201526084016107f3565b50506001600160a01b03871660009081526006602052604090205461354490839077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b0388811660009081526006602052604080822080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff9586161790557f0000000000000000000000000000000000000000000000000000000000000000909216815220546135d5918891166159cb565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166000908152600660205260409020805477ffffffffffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffff000000000000000000000000000000000000000000000000909316929092179091558416301461366b5761366b878584614655565b836001600160a01b0316876001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03167f0e8e403c2d36126272b08c75823e988381d9dc47f2f0a9a080d95f891d95c469848a6136d691906159cb565b8633896136e3898f6159cb565b6040805195865260208601949094526001600160a01b039283168585015291166060840152608083015260a08201879052519081900360c00190a45061372860018055565b95945050505050565b600061373b612ee3565b613743614ea3565b6001600160a01b0386166137995760405162461bcd60e51b815260206004820152601360248201527f576f6f505056323a202162617365546f6b656e0000000000000000000000000060448201526064016107f3565b6001600160a01b0383166137ef5760405162461bcd60e51b815260206004820152600c60248201527f576f6f505056323a2021746f000000000000000000000000000000000000000060448201526064016107f3565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b0316036138705760405162461bcd60e51b815260206004820152601e60248201527f576f6f505056323a2062617365546f6b656e3d3d71756f7465546f6b656e000060448201526064016107f3565b6001600160a01b038616600090815260066020526040902054859077ffffffffffffffffffffffffffffffffffffffffffffffff166138ae88611f9e565b6138b891906159b4565b10156139065760405162461bcd60e51b815260206004820152600e60248201527f576f6f505056323a20214241534500000000000000000000000000000000000060448201526064016107f3565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b03888116600483015260009283929116906331e658a590602401608060405180830381865afa15801561396d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139919190615c90565b905061399e888883615204565b6007546040517fd5bade070000000000000000000000000000000000000000000000000000000081526001600160a01b038c811660048301526fffffffffffffffffffffffffffffffff84166024830152939650919450919091169063d5bade0790604401600060405180830381600087803b158015613a1d57600080fd5b505af1158015613a31573d6000803e3d6000fd5b505050506001600160a01b038816600090815260066020526040812054909250620186a09150613a81907801000000000000000000000000000000000000000000000000900461ffff1684615ba0565b613a8b9190615c0c565b9050613a9781836159b4565b915084821015613b0f5760405162461bcd60e51b815260206004820152602660248201527f576f6f505056323a2071756f7465416d6f756e745f4c545f6d696e51756f746560448201527f416d6f756e74000000000000000000000000000000000000000000000000000060648201526084016107f3565b80600354613b1d91906159cb565b6003556001600160a01b038716600090815260066020526040902054613b5e90879077ffffffffffffffffffffffffffffffffffffffffffffffff166159cb565b6001600160a01b0388811660009081526006602052604080822080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff9586161790557f0000000000000000000000000000000000000000000000000000000000000000909216815220548291613bf1918591166159b4565b613bfb91906159b4565b6001600160a01b037f000000000000000000000000000000000000000000000000000000000000000081166000908152600660205260409020805477ffffffffffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffff0000000000000000000000000000000000000000000000009093169290921790915584163014613cb157613cb17f00000000000000000000000000000000000000000000000000000000000000008584614655565b836001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316886001600160a01b03167f0e8e403c2d36126272b08c75823e988381d9dc47f2f0a9a080d95f891d95c46989863389888a6136e391906159cb565b6000613d2a612ee3565b613d32614ea3565b6001600160a01b03871615801590613d7c57507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316876001600160a01b031614155b613dc85760405162461bcd60e51b815260206004820152601460248201527f576f6f505056323a202162617365546f6b656e3100000000000000000000000060448201526064016107f3565b6001600160a01b03861615801590613e1257507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316866001600160a01b031614155b613e5e5760405162461bcd60e51b815260206004820152601460248201527f576f6f505056323a202162617365546f6b656e3200000000000000000000000060448201526064016107f3565b856001600160a01b0316876001600160a01b031603613ebf5760405162461bcd60e51b815260206004820152601560248201527f576f6f505056323a2062617365313d3d6261736532000000000000000000000060448201526064016107f3565b6001600160a01b038316613f155760405162461bcd60e51b815260206004820152600c60248201527f576f6f505056323a2021746f000000000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038716600090815260066020526040902054859077ffffffffffffffffffffffffffffffffffffffffffffffff16613f5389611f9e565b613f5d91906159b4565b1015613fab5760405162461bcd60e51b815260206004820152601760248201527f576f6f505056323a202142415345315f42414c414e434500000000000000000060448201526064016107f3565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015260009216906331e658a590602401608060405180830381865afa15801561400f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140339190615c90565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152929350600092909116906331e658a590602401608060405180830381865afa15801561409c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140c09190615c90565b9050600080600060026140db866020015186602001516155a3565b6140e59190615d11565b6001600160a01b03808e1660009081526006602052604080822054928f1682528120549293509161413e9161ffff78010000000000000000000000000000000000000000000000009182900481169291909104166155cd565b67ffffffffffffffff83166020808901829052870152905060006141638e8d89615204565b8092508195505050600760009054906101000a90046001600160a01b03166001600160a01b031663d5bade078f836040518363ffffffff1660e01b81526004016141d49291906001600160a01b039290921682526fffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b1580156141ee57600080fd5b505af1158015614202573d6000803e3d6000fd5b50505050620186a08261ffff168561421a9190615ba0565b6142249190615c0c565b9450505050818161423591906159b4565b90508160035461424591906159cb565b6003556001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000166000908152600660205260409020546142a690839077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0390811660009081526006602052604080822080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff958616179055918e1681522054614337918b91166159cb565b6001600160a01b038c16600090815260066020526040812080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff93909316929092179091556143a28b8386614ef6565b6007546040517fd5bade070000000000000000000000000000000000000000000000000000000081526001600160a01b038f811660048301526fffffffffffffffffffffffffffffffff84166024830152939950919350919091169063d5bade0790604401600060405180830381600087803b15801561442157600080fd5b505af1158015614435573d6000803e3d6000fd5b50505050888610156144af5760405162461bcd60e51b815260206004820152602660248201527f576f6f505056323a206261736532416d6f756e745f4c545f6d696e426173653260448201527f416d6f756e74000000000000000000000000000000000000000000000000000060648201526084016107f3565b506001600160a01b038a166000908152600660205260409020546144ee90869077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b038b8116600090815260066020526040902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff93909316929092179091553090881614614563576145638a8887614655565b866001600160a01b03168a6001600160a01b03168c6001600160a01b03167f0e8e403c2d36126272b08c75823e988381d9dc47f2f0a9a080d95f891d95c4698c89338c89896145b291906159cb565b6040805195865260208601949094526001600160a01b039283168585015291166060840152608083015260a08201889052519081900360c00190a4505050506112d260018055565b614602614ea3565b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612ec63390565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916146df9190615c20565b6000604051808303816000865af19150503d806000811461471c576040519150601f19603f3d011682016040523d82523d6000602084013e614721565b606091505b509150915081801561474b57508051158061474b57508080602001905181019061474b9190615c5b565b612e6c5760405162461bcd60e51b815260206004820152600260248201527f535400000000000000000000000000000000000000000000000000000000000060448201526064016107f3565b60006147a1614ea3565b6001600160a01b038316600090815260066020526040812054620186a0906147e9907801000000000000000000000000000000000000000000000000900461ffff1685615ba0565b6147f39190615c0c565b90506147ff81846159b4565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152929550600092909116906331e658a590602401608060405180830381865afa158015614868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061488c9190615c90565b9050614899858583614ef6565b5095945050505050565b60006148ad614ea3565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260009216906331e658a590602401608060405180830381865afa158015614911573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149359190615c90565b9050614942848483615204565b506001600160a01b03851660009081526006602052604081205491935090620186a09061498f907801000000000000000000000000000000000000000000000000900461ffff1685615ba0565b6149999190615c0c565b905061372881846159b4565b6000806149b0614ea3565b6001600160a01b03851615806149cd57506001600160a01b038416155b80614a0957507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b0316145b80614a4557507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316846001600160a01b0316145b15614a5557506000905080614c4b565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015260009216906331e658a590602401608060405180830381865afa158015614ab9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614add9190615c90565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152929350600092909116906331e658a590602401608060405180830381865afa158015614b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b6a9190615c90565b905060006002614b82846020015184602001516155a3565b614b8c9190615d11565b6001600160a01b03808a1660009081526006602052604080822054928b16825281205492935091614be59161ffff78010000000000000000000000000000000000000000000000009182900481169291909104166155cd565b67ffffffffffffffff8316602080870182905285015290506000614c0a8a8987615204565b509050620186a0614c1f61ffff841683615ba0565b614c299190615c0c565b9550614c3586826159b4565b9050614c42898286614ef6565b50965050505050505b935093915050565b604080516000808252602082019092526001600160a01b038416908390604051614c7d9190615c20565b60006040518083038185875af1925050503d8060008114614cba576040519150601f19603f3d011682016040523d82523d6000602084013e614cbf565b606091505b50509050806113875760405162461bcd60e51b815260206004820152600360248201527f535445000000000000000000000000000000000000000000000000000000000060448201526064016107f3565b604080513060248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a08231000000000000000000000000000000000000000000000000000000001790529051600091829182916001600160a01b03861691614d959190615c20565b600060405180830381855afa9150503d8060008114614dd0576040519150601f19603f3d011682016040523d82523d6000602084013e614dd5565b606091505b5091509150818015614de957506020815110155b614e355760405162461bcd60e51b815260206004820152601160248201527f576f6f505056323a202142414c414e434500000000000000000000000000000060448201526064016107f3565b80806020019051810190614e499190615a12565b949350505050565b60025460ff166109e85760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107f3565b60025460ff16156109e85760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107f3565b6000808260600151614f4a5760405162461bcd60e51b815260206004820152601960248201527f576f6f505056323a20214f5241434c455f4645415349424c450000000000000060448201526064016107f3565b82516fffffffffffffffffffffffffffffffff16614faa5760405162461bcd60e51b815260206004820152601560248201527f576f6f505056323a20214f524143455f5052494345000000000000000000000060448201526064016107f3565b6000614fb5866117b0565b6001600160a01b0387166000908152600660205260408120600101549192509070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1686111561504a5760405162461bcd60e51b815260206004820152601a60248201527f576f6f505056323a20216d61784e6f74696f6e616c56616c756500000000000060448201526064016107f3565b816020015167ffffffffffffffff16856040015167ffffffffffffffff16876150739190615ba0565b61507d9190615c0c565b6001600160a01b0388166000908152600660205260409020600101549091506fffffffffffffffffffffffffffffffff168111156150fd5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202167616d6d61000000000000000000000000000000000060448201526064016107f3565b816020015167ffffffffffffffff16670de0b6b3a7640000866020015167ffffffffffffffff1683670de0b6b3a764000061513891906159b4565b61514291906159b4565b87600001516fffffffffffffffffffffffffffffffff16856000015167ffffffffffffffff16866040015167ffffffffffffffff168b6151829190615ba0565b61518c9190615ba0565b6151969190615c0c565b6151a09190615ba0565b6151aa9190615c0c565b6151b49190615c0c565b93506151c881670de0b6b3a76400006159b4565b85516151ee906fffffffffffffffffffffffffffffffff16670de0b6b3a7640000615ba0565b6151f89190615c0c565b92505050935093915050565b60008082606001516152585760405162461bcd60e51b815260206004820152601960248201527f576f6f505056323a20214f5241434c455f4645415349424c450000000000000060448201526064016107f3565b82516fffffffffffffffffffffffffffffffff166152b85760405162461bcd60e51b815260206004820152601560248201527f576f6f505056323a20214f524143455f5052494345000000000000000000000060448201526064016107f3565b60006152c3866117b0565b9050600080826000015167ffffffffffffffff16836040015167ffffffffffffffff16846020015167ffffffffffffffff1688600001516fffffffffffffffffffffffffffffffff168a6153179190615ba0565b6153219190615ba0565b61532b9190615c0c565b6153359190615c0c565b6001600160a01b03891660009081526006602052604090206001015490915070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff168111156153c95760405162461bcd60e51b815260206004820152601a60248201527f576f6f505056323a20216d61784e6f74696f6e616c56616c756500000000000060448201526064016107f3565b826040015167ffffffffffffffff16836000015167ffffffffffffffff16876040015167ffffffffffffffff1688600001516fffffffffffffffffffffffffffffffff168a6154189190615ba0565b6154229190615ba0565b61542c9190615c0c565b6154369190615c0c565b6001600160a01b0389166000908152600660205260409020600101549092506fffffffffffffffffffffffffffffffff168211156154b65760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202167616d6d61000000000000000000000000000000000060448201526064016107f3565b826040015167ffffffffffffffff16670de0b6b3a7640000876020015167ffffffffffffffff1684670de0b6b3a76400006154f191906159b4565b6154fb91906159b4565b856000015167ffffffffffffffff16866020015167ffffffffffffffff168a600001516fffffffffffffffffffffffffffffffff168c61553b9190615ba0565b6155459190615ba0565b61554f9190615c0c565b6155599190615ba0565b6155639190615c0c565b61556d9190615c0c565b8651909550670de0b6b3a764000091506fffffffffffffffffffffffffffffffff1661559983836159b4565b6151ee9190615ba0565b60008167ffffffffffffffff168367ffffffffffffffff16116155c65781611d99565b5090919050565b60008161ffff168361ffff16116155c65781611d99565b6001600160a01b03811681146116d757600080fd5b60006020828403121561560b57600080fd5b8135611d99816155e4565b6000806040838503121561562957600080fd5b8235615634816155e4565b91506020830135615644816155e4565b809150509250929050565b6000806040838503121561566257600080fd5b823561566d816155e4565b946020939093013593505050565b80151581146116d757600080fd5b6000806040838503121561569c57600080fd5b82356156a7816155e4565b915060208301356156448161567b565b803561ffff8116811461234957600080fd5b600080604083850312156156dc57600080fd5b82356156e7816155e4565b91506156f5602084016156b7565b90509250929050565b6fffffffffffffffffffffffffffffffff811681146116d757600080fd5b6000806040838503121561572f57600080fd5b823561573a816155e4565b91506020830135615644816156fe565b60008060008060008060c0878903121561576357600080fd5b863561576e816155e4565b9550602087013561577e816155e4565b94506040870135935060608701359250608087013561579c816155e4565b915060a08701356157ac816155e4565b809150509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715615830576158306157ba565b604052919050565b6000602080838503121561584b57600080fd5b823567ffffffffffffffff8082111561586357600080fd5b818501915085601f83011261587757600080fd5b813581811115615889576158896157ba565b8060051b915061589a8483016157e9565b81815291830184019184810190888411156158b457600080fd5b938501935b838510156158de57843592506158ce836155e4565b82825293850193908501906158b9565b98975050505050505050565b6000806000806080858703121561590057600080fd5b843561590b816155e4565b9350615919602086016156b7565b92506040850135615929816156fe565b91506060850135615939816156fe565b939692955090935050565b60008060006060848603121561595957600080fd5b8335615964816155e4565b92506020840135615974816155e4565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156159c6576159c6615985565b500390565b600082198211156159de576159de615985565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215615a2457600080fd5b5051919050565b600060208284031215615a3d57600080fd5b815160ff81168114611d9957600080fd5b600181815b80851115615a8f578167ffffffffffffffff04821115615a7557615a75615985565b80851615615a8257918102915b93841c9390800290615a53565b509250929050565b600082615aa657506001611ffd565b81615ab357506000611ffd565b8160018114615ac95760028114615ad357615b08565b6001915050611ffd565b60ff841115615ae457615ae4615985565b6001841b915067ffffffffffffffff821115615b0257615b02615985565b50611ffd565b5060208310610133831016604e8410600b8410161715615b3e575081810a67ffffffffffffffff811115611fe257611fe2615985565b615b488383615a4e565b8067ffffffffffffffff04821115615b6257615b62615985565b029392505050565b6000611d9960ff841667ffffffffffffffff8416615a97565b600060208284031215615b9557600080fd5b8151611d99816155e4565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615bd857615bd8615985565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c1b57615c1b615bdd565b500490565b6000825160005b81811015615c415760208186018101518583015201615c27565b81811115615c50576000828501525b509190910192915050565b600060208284031215615c6d57600080fd5b8151611d998161567b565b805167ffffffffffffffff8116811461234957600080fd5b600060808284031215615ca257600080fd5b6040516080810181811067ffffffffffffffff82111715615cc557615cc56157ba565b6040528251615cd3816156fe565b8152615ce160208401615c78565b6020820152615cf260408401615c78565b60408201526060830151615d058161567b565b60608201529392505050565b600067ffffffffffffffff80841680615d2c57615d2c615bdd565b9216919091049291505056fea2646970667358221220ecce7c86f0918a5fcc95e2d46ba8dde19c958d88c07360898bbfd509fd7eb31464736f6c634300080e0033000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102e85760003560e01c8063a1ae849011610191578063e1a4e72a116100e3578063f2fde38b11610097578063fa09e63011610071578063fa09e63014610730578063fa75d16014610743578063fc60fb5d1461078657600080fd5b8063f2fde38b146106f7578063f3fef3a31461070a578063f58a435f1461071d57600080fd5b8063e4d43ec1116100c8578063e4d43ec1146106c8578063ebc80f13146106d1578063f09a4016146106e457600080fd5b8063e1a4e72a146106a2578063e3d670d7146106b557600080fd5b8063b2e693d311610145578063bc8530f91161011f578063bc8530f914610669578063ce824f191461067c578063d6285b7f1461068f57600080fd5b8063b2e693d314610549578063ba46ae7214610572578063bc25cf771461065657600080fd5b8063a584119411610176578063a584119414610510578063a8a4ff6a14610523578063b2855b4f1461053657600080fd5b8063a1ae8490146104b7578063a26db1a7146104ca57600080fd5b8063637e10cb1161024a5780637f0eec02116101fe578063966fb4c3116101d8578063966fb4c31461048957806399d32fc41461049c5780639f0d5f27146104a457600080fd5b80637f0eec021461045d5780638456cb59146104705780638da5cb5b1461047857600080fd5b8063686f30b01161022f578063686f30b014610421578063715018a6146104345780637dc203821461043c57600080fd5b8063637e10cb146103fb57806368078eed1461040e57600080fd5b80633f4ba83a116102a15780634b0bddd2116102865780634b0bddd2146103ca5780635905d23c146103dd5780635c975abb146103f057600080fd5b80633f4ba83a146103af57806347e7ef24146103b757600080fd5b8063217a4b70116102d2578063217a4b701461033a57806324d7806c1461037957806339e7fddc1461039c57600080fd5b80622259b4146102ed5780630426d97514610325575b600080fd5b6103106102fb3660046155f9565b60056020526000908152604090205460ff1681565b60405190151581526020015b60405180910390f35b610338610333366004615616565b610799565b005b6103617f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff81565b6040516001600160a01b03909116815260200161031c565b6103106103873660046155f9565b60046020526000908152604090205460ff1681565b600854610361906001600160a01b031681565b61033861096c565b6103386103c536600461564f565b6109ea565b6103386103d8366004615689565b610bc9565b6103386103eb366004615689565b610d11565b60025460ff16610310565b61033861040936600461564f565b610dfb565b61033861041c3660046156c9565b611016565b61033861042f36600461571c565b611149565b61033861121a565b61044f61044a36600461574a565b61122c565b60405190815260200161031c565b61033861046b366004615838565b6112dc565b61033861138c565b6000546001600160a01b0316610361565b6103386104973660046158ea565b611422565b610338611531565b6103386104b23660046155f9565b6115dc565b6103386104c53660046155f9565b6116da565b6104dd6104d83660046155f9565b6117b0565b60408051825167ffffffffffffffff9081168252602080850151821690830152928201519092169082015260600161031c565b61033861051e3660046155f9565b611991565b61033861053136600461571c565b611a7c565b6103386105443660046155f9565b611b3f565b6103616105573660046155f9565b6009602052600090815260409020546001600160a01b031681565b6106006105803660046155f9565b6006602052600090815260409020805460019091015477ffffffffffffffffffffffffffffffffffffffffffffffff8216917801000000000000000000000000000000000000000000000000900461ffff16906fffffffffffffffffffffffffffffffff8082169170010000000000000000000000000000000090041684565b6040805177ffffffffffffffffffffffffffffffffffffffffffffffff909516855261ffff90931660208501526fffffffffffffffffffffffffffffffff9182169284019290925216606082015260800161031c565b6103386106643660046155f9565b611c15565b600754610361906001600160a01b031681565b61044f61068a366004615944565b611cfb565b61033861069d3660046155f9565b611da0565b6103386106b03660046155f9565b611ecb565b61044f6106c33660046155f9565b611f9e565b61044f60035481565b61044f6106df3660046155f9565b612003565b6103386106f2366004615616565b61234e565b6103386107053660046155f9565b6123f5565b61033861071836600461564f565b612482565b61044f61072b366004615944565b61269c565b61033861073e3660046155f9565b612889565b61044f6107513660046155f9565b6001600160a01b031660009081526006602052604090205477ffffffffffffffffffffffffffffffffffffffffffffffff1690565b61044f61079436600461564f565b61293a565b6107a1612cd0565b6001600160a01b0382166107fc5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a2021746f6b656e000000000000000000000000000000000060448201526064015b60405180910390fd5b6001600160a01b0381166108525760405162461bcd60e51b815260206004820152601160248201527f576f6f505056323a20216e6577506f6f6c00000000000000000000000000000060448201526064016107f3565b6001600160a01b038216600090815260066020526040812080547fffffffffffffffff00000000000000000000000000000000000000000000000016905561089983611f9e565b90506108a6838383612d2a565b6040517f9f0d5f270000000000000000000000000000000000000000000000000000000081526001600160a01b038481166004830152831690639f0d5f2790602401600060405180830381600087803b15801561090257600080fd5b505af1158015610916573d6000803e3d6000fd5b50505050816001600160a01b0316836001600160a01b03167f18df02dcc52b9c494f391df09661519c0069bd8540141946280399408205ca1a8360405161095f91815260200190565b60405180910390a3505050565b6000546001600160a01b031633148061099457503360009081526004602052604090205460ff165b6109e05760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6109e8612e73565b565b6109f2612ee3565b6000546001600160a01b0316331480610a1a57503360009081526004602052604090205460ff165b610a665760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6000610a7183611f9e565b9050610a7f83333085612f3c565b600081610a8b85611f9e565b610a9591906159b4565b905082811015610ae75760405162461bcd60e51b815260206004820152600d60248201527f414d4f554e545f494e535546460000000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038416600090815260066020526040902054610b2590849077ffffffffffffffffffffffffffffffffffffffffffffffff166159cb565b6001600160a01b03851660008181526006602090815260409182902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff95909516949094179093555185815233927f5548c837ab068cf56a2c2479df0882a4922fd203edb7517321831d95078c5f62910160405180910390a35050610bc560018055565b5050565b6000546001600160a01b0316331480610bf157503360009081526004602052604090205460ff165b610c3d5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038216610c935760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b03821660008181526004602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f235bc17e7930760029e9f4d860a2a8089976de5b381cf8380fc11c1d88a1113391015b60405180910390a25050565b6000546001600160a01b0316331480610d3957503360009081526004602052604090205460ff165b610d855760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b03821660008181526005602090815260409182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001685151590811790915591519182527f949c0260fa3a6145f57958b7bf0efeb5edb4d3e1e573353a16e69aea2450883d9101610d05565b610e03612ee3565b6000546001600160a01b0316331480610e2b57503360009081526004602052604090205460ff165b610e775760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b03808316600090815260096020526040902054168115610fbf576001600160a01b038316600090815260066020526040902054610ed690839077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b038416600090815260066020526040902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff92909216919091179055610f40838284612d2a565b6040517f371fd8e6000000000000000000000000000000000000000000000000000000008152600481018390526001600160a01b0382169063371fd8e690602401600060405180830381600087803b158015610f9b57600080fd5b505af1158015610faf573d6000803e3d6000fd5b50505050610fbf83826000612d2a565b806001600160a01b0316836001600160a01b03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb8460405161100491815260200190565b60405180910390a350610bc560018055565b6000546001600160a01b031633148061103e57503360009081526004602052604090205460ff165b61108a5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b620186a08161ffff1611156110e15760405162461bcd60e51b815260206004820152600560248201527f217261746500000000000000000000000000000000000000000000000000000060448201526064016107f3565b6001600160a01b039091166000908152600660205260409020805461ffff9092167801000000000000000000000000000000000000000000000000027fffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffff909216919091179055565b6000546001600160a01b031633148061117157503360009081526004602052604090205460ff165b6111bd5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b0391909116600090815260066020526040902060010180547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166fffffffffffffffffffffffffffffffff909216919091179055565b611222612cd0565b6109e8600061308e565b60007f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316876001600160a01b03160361127b5761127486868686866130f6565b90506112d2565b7f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316866001600160a01b0316036112c1576112748786868686613731565b6112cf878787878787613d20565b90505b9695505050505050565b6000546001600160a01b031633148061130457503360009081526004602052604090205460ff165b6113505760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b805160005b818110156113875761137f838281518110611372576113726159e3565b6020026020010151611c15565b600101611355565b505050565b6000546001600160a01b03163314806113b457503360009081526004602052604090205460ff165b806113ce57503360009081526005602052604090205460ff165b61141a5760405162461bcd60e51b815260206004820152601560248201527f576f6f505056323a202169735061757365526f6c65000000000000000000000060448201526064016107f3565b6109e86145fa565b6000546001600160a01b031633148061144a57503360009081526004602052604090205460ff165b6114965760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b039093166000908152600660205260409020805461ffff9093167801000000000000000000000000000000000000000000000000027fffffffffffff0000ffffffffffffffffffffffffffffffffffffffffffffffff9093169290921782556fffffffffffffffffffffffffffffffff92831670010000000000000000000000000000000002921691909117600190910155565b611539612ee3565b6008546001600160a01b03166115915760405162461bcd60e51b815260206004820152601160248201527f576f6f505056323a20216665654164647200000000000000000000000000000060448201526064016107f3565b6003805460009091556008546115d2907f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff906001600160a01b031683614655565b506109e860018055565b6000546001600160a01b031633148061160457503360009081526004602052604090205460ff165b6116505760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523360048201526116d79082906001600160a01b038216906370a0823190602401602060405180830381865afa1580156116b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103c59190615a12565b50565b6000546001600160a01b031633148061170257503360009081526004602052604090205460ff165b61174e5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b600780547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f59ddfdd1bf7e3ea08a07e8aaa1fe2ce9c840fab69fe5ede6ea727a45eb42fc6690600090a250565b6040805160608082018352600080835260208301819052828401528251908101928390526007547fd449a832000000000000000000000000000000000000000000000000000000009093526001600160a01b0384811660648301529192909182911663d449a83260848301602060405180830381865afa158015611838573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185c9190615a2b565b61186790600a615b6a565b67ffffffffffffffff1681526020017f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa1580156118d4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118f89190615a2b565b61190390600a615b6a565b67ffffffffffffffff168152602001836001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015611950573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119749190615a2b565b61197f90600a615b6a565b67ffffffffffffffff16905292915050565b611999612ee3565b6000546001600160a01b03163314806119c157503360009081526004602052604090205460ff165b611a0d5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b611a1681611f9e565b6001600160a01b038216600090815260066020526040902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff929092169190911790556001805550565b6000546001600160a01b0316331480611aa457503360009081526004602052604090205460ff165b611af05760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b03909116600090815260066020526040902060010180546fffffffffffffffffffffffffffffffff928316700100000000000000000000000000000000029216919091179055565b6000546001600160a01b0316331480611b6757503360009081526004602052604090205460ff165b611bb35760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b600880547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b0383169081179091556040517f76f97b3f5ffcc8d8d9577d141751a7bed446b46d837fbc81b5c01c165bbfbbf490600090a250565b611c1d612ee3565b6000546001600160a01b0316331480611c4557503360009081526004602052604090205460ff165b611c915760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b611cf281611ca76000546001600160a01b031690565b6001600160a01b03841660009081526006602052604090205477ffffffffffffffffffffffffffffffffffffffffffffffff16611ce385611f9e565b611ced91906159b4565b614655565b6116d760018055565b60007f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316846001600160a01b031603611d4757611d408383614797565b9050611d99565b7f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316836001600160a01b031603611d8a57611d4084836148a3565b611d958484846149a5565b5090505b9392505050565b611da8612cd0565b8060096000836001600160a01b0316631f1fcd516040518163ffffffff1660e01b81526004016020604051808303816000875af1158015611ded573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611e119190615b83565b6001600160a01b0390811682526020808301939093526040918201600090812080547fffffffffffffffffffffffff000000000000000000000000000000000000000016958316959095179094558416808452600483529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016600190811790915590519081527f235bc17e7930760029e9f4d860a2a8089976de5b381cf8380fc11c1d88a11133910160405180910390a250565b611ed3612cd0565b7fffffffffffffffffffffffff11111111111111111111111111111111111111126001600160a01b03821601611f0d576116d73347614c53565b6040517f70a082310000000000000000000000000000000000000000000000000000000081523060048201526000906001600160a01b038316906370a0823190602401602060405180830381865afa158015611f6d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f919190615a12565b9050610bc5823383614655565b60007f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316826001600160a01b031614611fe757611fe282614d10565b611ffd565b600354611ff383614d10565b611ffd91906159b4565b92915050565b600061200d612ee3565b6000546001600160a01b031633148061203557503360009081526004602052604090205460ff165b6120815760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038083166000908152600960205260408082205481517fa373ed4e0000000000000000000000000000000000000000000000000000000081529151931692839263a373ed4e926004808201939182900301818387803b1580156120ea57600080fd5b505af11580156120fe573d6000803e3d6000fd5b505050506000816001600160a01b031663f077cbab6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612142573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121669190615a12565b90506000826001600160a01b0316631f1fcd516040518163ffffffff1660e01b81526004016020604051808303816000875af11580156121aa573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906121ce9190615b83565b905081156122f0576001600160a01b03811660009081526006602052604090205461221490839077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b038216600090815260066020526040902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff9290921691909117905561227e818484612d2a565b826001600160a01b031663c1ae359a6040518163ffffffff1660e01b81526004016020604051808303816000875af11580156122be573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122e29190615a12565b93506122f081846000612d2a565b826001600160a01b0316816001600160a01b03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb8460405161233591815260200190565b60405180910390a350505061234960018055565b919050565b612356612cd0565b6007546001600160a01b0316156123af5760405162461bcd60e51b815260206004820152601560248201527f576f6f505056323a20494e49545f494e56414c4944000000000000000000000060448201526064016107f3565b600780546001600160a01b039384167fffffffffffffffffffffffff00000000000000000000000000000000000000009182161790915560088054929093169116179055565b6123fd612cd0565b6001600160a01b0381166124795760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016107f3565b6116d78161308e565b61248a612ee3565b6000546001600160a01b03163314806124b257503360009081526004602052604090205460ff165b6124fe5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b03821660009081526006602052604090205477ffffffffffffffffffffffffffffffffffffffffffffffff168111156125805760405162461bcd60e51b815260206004820152601060248201527f576f6f505056323a2021616d6f756e740000000000000000000000000000000060448201526064016107f3565b6001600160a01b0382166000908152600660205260409020546125be90829077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b0383166000908152600660205260409020805477ffffffffffffffffffffffffffffffffffffffffffffffff929092167fffffffffffffffff00000000000000000000000000000000000000000000000090921691909117905561263b826126356000546001600160a01b031690565b83614655565b6000546001600160a01b03166001600160a01b0316826001600160a01b03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb8360405161268b91815260200190565b60405180910390a3610bc560018055565b60007f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316846001600160a01b0316036126e8576126e18383614797565b9050612807565b7f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316836001600160a01b03160361272b576126e184836148a3565b60006127388585856149a5565b6001600160a01b037f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff16600090815260066020526040902054919350915077ffffffffffffffffffffffffffffffffffffffffffffffff168111156128055760405162461bcd60e51b815260206004820152602160248201527f576f6f505056323a20494e535546465f51554f54455f464f525f53574150464560448201527f450000000000000000000000000000000000000000000000000000000000000060648201526084016107f3565b505b6001600160a01b03831660009081526006602052604090205477ffffffffffffffffffffffffffffffffffffffffffffffff16811115611d995760405162461bcd60e51b815260206004820152601760248201527f576f6f505056323a20494e535546465f42414c414e434500000000000000000060448201526064016107f3565b6000546001600160a01b03163314806128b157503360009081526004602052604090205460ff165b6128fd5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6116d781610718836001600160a01b031660009081526006602052604090205477ffffffffffffffffffffffffffffffffffffffffffffffff1690565b6000612944612ee3565b6000546001600160a01b031633148061296c57503360009081526004602052604090205460ff165b6129b85760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202161646d696e000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038084166000908152600960205260408082205481517fa373ed4e0000000000000000000000000000000000000000000000000000000081529151931692839263a373ed4e926004808201939182900301818387803b158015612a2157600080fd5b505af1158015612a35573d6000803e3d6000fd5b505050506000816001600160a01b03166352c49c446040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a79573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9d9190615a12565b9050600061271082846001600160a01b031663e5e2abf56040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ae3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b079190615a12565b612b119190615ba0565b612b1b9190615c0c565b9050600081612b2a84886159cb565b612b3491906159cb565b90508015612c76576001600160a01b038716600090815260066020526040902054612b7a90829077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b038816600090815260066020526040902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff92909216919091179055612be4878583612d2a565b6040517f3560df8c000000000000000000000000000000000000000000000000000000008152600481018790526001600160a01b03851690633560df8c906024016020604051808303816000875af1158015612c44573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c689190615a12565b9450612c7687856000612d2a565b836001600160a01b0316876001600160a01b03167f9b1bfa7fa9ee420a16e124f794c35ac9f90472acc99140eb2f6447c714cad8eb83604051612cbb91815260200190565b60405180910390a350505050611ffd60018055565b6000546001600160a01b031633146109e85760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107f3565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b3000000000000000000000000000000000000000000000000000000001790529151600092839290871691612db49190615c20565b6000604051808303816000865af19150503d8060008114612df1576040519150601f19603f3d011682016040523d82523d6000602084013e612df6565b606091505b5091509150818015612e20575080511580612e20575080806020019051810190612e209190615c5b565b612e6c5760405162461bcd60e51b815260206004820152600260248201527f534100000000000000000000000000000000000000000000000000000000000060448201526064016107f3565b5050505050565b612e7b614e51565b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600260015403612f355760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107f3565b6002600155565b604080516001600160a01b0385811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd000000000000000000000000000000000000000000000000000000001790529151600092839290881691612fce9190615c20565b6000604051808303816000865af19150503d806000811461300b576040519150601f19603f3d011682016040523d82523d6000602084013e613010565b606091505b509150915081801561303a57508051158061303a57508080602001905181019061303a9190615c5b565b6130865760405162461bcd60e51b815260206004820152600360248201527f535446000000000000000000000000000000000000000000000000000000000060448201526064016107f3565b505050505050565b600080546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000613100612ee3565b613108614ea3565b6001600160a01b03861661315e5760405162461bcd60e51b815260206004820152601360248201527f576f6f505056323a202162617365546f6b656e0000000000000000000000000060448201526064016107f3565b6001600160a01b0383166131b45760405162461bcd60e51b815260206004820152600c60248201527f576f6f505056323a2021746f000000000000000000000000000000000000000060448201526064016107f3565b7f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316866001600160a01b0316036132355760405162461bcd60e51b815260206004820152601e60248201527f576f6f505056323a2062617365546f6b656e3d3d71756f7465546f6b656e000060448201526064016107f3565b7f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b038116600090815260066020526040902054869177ffffffffffffffffffffffffffffffffffffffffffffffff9091169061329790611f9e565b6132a191906159b4565b10156132ef5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202151554f5445000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038616600090815260066020526040812054620186a090613337907801000000000000000000000000000000000000000000000000900461ffff1688615ba0565b6133419190615c0c565b905061334d81876159b4565b95508060035461335d91906159cb565b6003556007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015260009283929116906331e658a590602401608060405180830381865afa1580156133c7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133eb9190615c90565b90506133f8898983614ef6565b6007546040517fd5bade070000000000000000000000000000000000000000000000000000000081526001600160a01b038d811660048301526fffffffffffffffffffffffffffffffff84166024830152939750919450919091169063d5bade0790604401600060405180830381600087803b15801561347757600080fd5b505af115801561348b573d6000803e3d6000fd5b50505050868410156135045760405162461bcd60e51b8152602060048201526024808201527f576f6f505056323a2062617365416d6f756e745f4c545f6d696e42617365416d60448201527f6f756e740000000000000000000000000000000000000000000000000000000060648201526084016107f3565b50506001600160a01b03871660009081526006602052604090205461354490839077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b0388811660009081526006602052604080822080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff9586161790557f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff909216815220546135d5918891166159cb565b6001600160a01b037f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff81166000908152600660205260409020805477ffffffffffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffff000000000000000000000000000000000000000000000000909316929092179091558416301461366b5761366b878584614655565b836001600160a01b0316876001600160a01b03167f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b03167f0e8e403c2d36126272b08c75823e988381d9dc47f2f0a9a080d95f891d95c469848a6136d691906159cb565b8633896136e3898f6159cb565b6040805195865260208601949094526001600160a01b039283168585015291166060840152608083015260a08201879052519081900360c00190a45061372860018055565b95945050505050565b600061373b612ee3565b613743614ea3565b6001600160a01b0386166137995760405162461bcd60e51b815260206004820152601360248201527f576f6f505056323a202162617365546f6b656e0000000000000000000000000060448201526064016107f3565b6001600160a01b0383166137ef5760405162461bcd60e51b815260206004820152600c60248201527f576f6f505056323a2021746f000000000000000000000000000000000000000060448201526064016107f3565b7f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316866001600160a01b0316036138705760405162461bcd60e51b815260206004820152601e60248201527f576f6f505056323a2062617365546f6b656e3d3d71756f7465546f6b656e000060448201526064016107f3565b6001600160a01b038616600090815260066020526040902054859077ffffffffffffffffffffffffffffffffffffffffffffffff166138ae88611f9e565b6138b891906159b4565b10156139065760405162461bcd60e51b815260206004820152600e60248201527f576f6f505056323a20214241534500000000000000000000000000000000000060448201526064016107f3565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b03888116600483015260009283929116906331e658a590602401608060405180830381865afa15801561396d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906139919190615c90565b905061399e888883615204565b6007546040517fd5bade070000000000000000000000000000000000000000000000000000000081526001600160a01b038c811660048301526fffffffffffffffffffffffffffffffff84166024830152939650919450919091169063d5bade0790604401600060405180830381600087803b158015613a1d57600080fd5b505af1158015613a31573d6000803e3d6000fd5b505050506001600160a01b038816600090815260066020526040812054909250620186a09150613a81907801000000000000000000000000000000000000000000000000900461ffff1684615ba0565b613a8b9190615c0c565b9050613a9781836159b4565b915084821015613b0f5760405162461bcd60e51b815260206004820152602660248201527f576f6f505056323a2071756f7465416d6f756e745f4c545f6d696e51756f746560448201527f416d6f756e74000000000000000000000000000000000000000000000000000060648201526084016107f3565b80600354613b1d91906159cb565b6003556001600160a01b038716600090815260066020526040902054613b5e90879077ffffffffffffffffffffffffffffffffffffffffffffffff166159cb565b6001600160a01b0388811660009081526006602052604080822080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff9586161790557f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff909216815220548291613bf1918591166159b4565b613bfb91906159b4565b6001600160a01b037f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff81166000908152600660205260409020805477ffffffffffffffffffffffffffffffffffffffffffffffff939093167fffffffffffffffff0000000000000000000000000000000000000000000000009093169290921790915584163014613cb157613cb17f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff8584614655565b836001600160a01b03167f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316886001600160a01b03167f0e8e403c2d36126272b08c75823e988381d9dc47f2f0a9a080d95f891d95c46989863389888a6136e391906159cb565b6000613d2a612ee3565b613d32614ea3565b6001600160a01b03871615801590613d7c57507f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316876001600160a01b031614155b613dc85760405162461bcd60e51b815260206004820152601460248201527f576f6f505056323a202162617365546f6b656e3100000000000000000000000060448201526064016107f3565b6001600160a01b03861615801590613e1257507f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316866001600160a01b031614155b613e5e5760405162461bcd60e51b815260206004820152601460248201527f576f6f505056323a202162617365546f6b656e3200000000000000000000000060448201526064016107f3565b856001600160a01b0316876001600160a01b031603613ebf5760405162461bcd60e51b815260206004820152601560248201527f576f6f505056323a2062617365313d3d6261736532000000000000000000000060448201526064016107f3565b6001600160a01b038316613f155760405162461bcd60e51b815260206004820152600c60248201527f576f6f505056323a2021746f000000000000000000000000000000000000000060448201526064016107f3565b6001600160a01b038716600090815260066020526040902054859077ffffffffffffffffffffffffffffffffffffffffffffffff16613f5389611f9e565b613f5d91906159b4565b1015613fab5760405162461bcd60e51b815260206004820152601760248201527f576f6f505056323a202142415345315f42414c414e434500000000000000000060448201526064016107f3565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b03898116600483015260009216906331e658a590602401608060405180830381865afa15801561400f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140339190615c90565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b038a81166004830152929350600092909116906331e658a590602401608060405180830381865afa15801561409c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906140c09190615c90565b9050600080600060026140db866020015186602001516155a3565b6140e59190615d11565b6001600160a01b03808e1660009081526006602052604080822054928f1682528120549293509161413e9161ffff78010000000000000000000000000000000000000000000000009182900481169291909104166155cd565b67ffffffffffffffff83166020808901829052870152905060006141638e8d89615204565b8092508195505050600760009054906101000a90046001600160a01b03166001600160a01b031663d5bade078f836040518363ffffffff1660e01b81526004016141d49291906001600160a01b039290921682526fffffffffffffffffffffffffffffffff16602082015260400190565b600060405180830381600087803b1580156141ee57600080fd5b505af1158015614202573d6000803e3d6000fd5b50505050620186a08261ffff168561421a9190615ba0565b6142249190615c0c565b9450505050818161423591906159b4565b90508160035461424591906159cb565b6003556001600160a01b037f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff166000908152600660205260409020546142a690839077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b7f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0390811660009081526006602052604080822080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff958616179055918e1681522054614337918b91166159cb565b6001600160a01b038c16600090815260066020526040812080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff93909316929092179091556143a28b8386614ef6565b6007546040517fd5bade070000000000000000000000000000000000000000000000000000000081526001600160a01b038f811660048301526fffffffffffffffffffffffffffffffff84166024830152939950919350919091169063d5bade0790604401600060405180830381600087803b15801561442157600080fd5b505af1158015614435573d6000803e3d6000fd5b50505050888610156144af5760405162461bcd60e51b815260206004820152602660248201527f576f6f505056323a206261736532416d6f756e745f4c545f6d696e426173653260448201527f416d6f756e74000000000000000000000000000000000000000000000000000060648201526084016107f3565b506001600160a01b038a166000908152600660205260409020546144ee90869077ffffffffffffffffffffffffffffffffffffffffffffffff166159b4565b6001600160a01b038b8116600090815260066020526040902080547fffffffffffffffff0000000000000000000000000000000000000000000000001677ffffffffffffffffffffffffffffffffffffffffffffffff93909316929092179091553090881614614563576145638a8887614655565b866001600160a01b03168a6001600160a01b03168c6001600160a01b03167f0e8e403c2d36126272b08c75823e988381d9dc47f2f0a9a080d95f891d95c4698c89338c89896145b291906159cb565b6040805195865260208601949094526001600160a01b039283168585015291166060840152608083015260a08201889052519081900360c00190a4505050506112d260018055565b614602614ea3565b600280547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612ec63390565b604080516001600160a01b038481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb0000000000000000000000000000000000000000000000000000000017905291516000928392908716916146df9190615c20565b6000604051808303816000865af19150503d806000811461471c576040519150601f19603f3d011682016040523d82523d6000602084013e614721565b606091505b509150915081801561474b57508051158061474b57508080602001905181019061474b9190615c5b565b612e6c5760405162461bcd60e51b815260206004820152600260248201527f535400000000000000000000000000000000000000000000000000000000000060448201526064016107f3565b60006147a1614ea3565b6001600160a01b038316600090815260066020526040812054620186a0906147e9907801000000000000000000000000000000000000000000000000900461ffff1685615ba0565b6147f39190615c0c565b90506147ff81846159b4565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b038781166004830152929550600092909116906331e658a590602401608060405180830381865afa158015614868573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061488c9190615c90565b9050614899858583614ef6565b5095945050505050565b60006148ad614ea3565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b03858116600483015260009216906331e658a590602401608060405180830381865afa158015614911573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906149359190615c90565b9050614942848483615204565b506001600160a01b03851660009081526006602052604081205491935090620186a09061498f907801000000000000000000000000000000000000000000000000900461ffff1685615ba0565b6149999190615c0c565b905061372881846159b4565b6000806149b0614ea3565b6001600160a01b03851615806149cd57506001600160a01b038416155b80614a0957507f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316856001600160a01b0316145b80614a4557507f000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff6001600160a01b0316846001600160a01b0316145b15614a5557506000905080614c4b565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b03878116600483015260009216906331e658a590602401608060405180830381865afa158015614ab9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614add9190615c90565b6007546040517f31e658a50000000000000000000000000000000000000000000000000000000081526001600160a01b038881166004830152929350600092909116906331e658a590602401608060405180830381865afa158015614b46573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190614b6a9190615c90565b905060006002614b82846020015184602001516155a3565b614b8c9190615d11565b6001600160a01b03808a1660009081526006602052604080822054928b16825281205492935091614be59161ffff78010000000000000000000000000000000000000000000000009182900481169291909104166155cd565b67ffffffffffffffff8316602080870182905285015290506000614c0a8a8987615204565b509050620186a0614c1f61ffff841683615ba0565b614c299190615c0c565b9550614c3586826159b4565b9050614c42898286614ef6565b50965050505050505b935093915050565b604080516000808252602082019092526001600160a01b038416908390604051614c7d9190615c20565b60006040518083038185875af1925050503d8060008114614cba576040519150601f19603f3d011682016040523d82523d6000602084013e614cbf565b606091505b50509050806113875760405162461bcd60e51b815260206004820152600360248201527f535445000000000000000000000000000000000000000000000000000000000060448201526064016107f3565b604080513060248083019190915282518083039091018152604490910182526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f70a08231000000000000000000000000000000000000000000000000000000001790529051600091829182916001600160a01b03861691614d959190615c20565b600060405180830381855afa9150503d8060008114614dd0576040519150601f19603f3d011682016040523d82523d6000602084013e614dd5565b606091505b5091509150818015614de957506020815110155b614e355760405162461bcd60e51b815260206004820152601160248201527f576f6f505056323a202142414c414e434500000000000000000000000000000060448201526064016107f3565b80806020019051810190614e499190615a12565b949350505050565b60025460ff166109e85760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016107f3565b60025460ff16156109e85760405162461bcd60e51b815260206004820152601060248201527f5061757361626c653a207061757365640000000000000000000000000000000060448201526064016107f3565b6000808260600151614f4a5760405162461bcd60e51b815260206004820152601960248201527f576f6f505056323a20214f5241434c455f4645415349424c450000000000000060448201526064016107f3565b82516fffffffffffffffffffffffffffffffff16614faa5760405162461bcd60e51b815260206004820152601560248201527f576f6f505056323a20214f524143455f5052494345000000000000000000000060448201526064016107f3565b6000614fb5866117b0565b6001600160a01b0387166000908152600660205260408120600101549192509070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff1686111561504a5760405162461bcd60e51b815260206004820152601a60248201527f576f6f505056323a20216d61784e6f74696f6e616c56616c756500000000000060448201526064016107f3565b816020015167ffffffffffffffff16856040015167ffffffffffffffff16876150739190615ba0565b61507d9190615c0c565b6001600160a01b0388166000908152600660205260409020600101549091506fffffffffffffffffffffffffffffffff168111156150fd5760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202167616d6d61000000000000000000000000000000000060448201526064016107f3565b816020015167ffffffffffffffff16670de0b6b3a7640000866020015167ffffffffffffffff1683670de0b6b3a764000061513891906159b4565b61514291906159b4565b87600001516fffffffffffffffffffffffffffffffff16856000015167ffffffffffffffff16866040015167ffffffffffffffff168b6151829190615ba0565b61518c9190615ba0565b6151969190615c0c565b6151a09190615ba0565b6151aa9190615c0c565b6151b49190615c0c565b93506151c881670de0b6b3a76400006159b4565b85516151ee906fffffffffffffffffffffffffffffffff16670de0b6b3a7640000615ba0565b6151f89190615c0c565b92505050935093915050565b60008082606001516152585760405162461bcd60e51b815260206004820152601960248201527f576f6f505056323a20214f5241434c455f4645415349424c450000000000000060448201526064016107f3565b82516fffffffffffffffffffffffffffffffff166152b85760405162461bcd60e51b815260206004820152601560248201527f576f6f505056323a20214f524143455f5052494345000000000000000000000060448201526064016107f3565b60006152c3866117b0565b9050600080826000015167ffffffffffffffff16836040015167ffffffffffffffff16846020015167ffffffffffffffff1688600001516fffffffffffffffffffffffffffffffff168a6153179190615ba0565b6153219190615ba0565b61532b9190615c0c565b6153359190615c0c565b6001600160a01b03891660009081526006602052604090206001015490915070010000000000000000000000000000000090046fffffffffffffffffffffffffffffffff168111156153c95760405162461bcd60e51b815260206004820152601a60248201527f576f6f505056323a20216d61784e6f74696f6e616c56616c756500000000000060448201526064016107f3565b826040015167ffffffffffffffff16836000015167ffffffffffffffff16876040015167ffffffffffffffff1688600001516fffffffffffffffffffffffffffffffff168a6154189190615ba0565b6154229190615ba0565b61542c9190615c0c565b6154369190615c0c565b6001600160a01b0389166000908152600660205260409020600101549092506fffffffffffffffffffffffffffffffff168211156154b65760405162461bcd60e51b815260206004820152600f60248201527f576f6f505056323a202167616d6d61000000000000000000000000000000000060448201526064016107f3565b826040015167ffffffffffffffff16670de0b6b3a7640000876020015167ffffffffffffffff1684670de0b6b3a76400006154f191906159b4565b6154fb91906159b4565b856000015167ffffffffffffffff16866020015167ffffffffffffffff168a600001516fffffffffffffffffffffffffffffffff168c61553b9190615ba0565b6155459190615ba0565b61554f9190615c0c565b6155599190615ba0565b6155639190615c0c565b61556d9190615c0c565b8651909550670de0b6b3a764000091506fffffffffffffffffffffffffffffffff1661559983836159b4565b6151ee9190615ba0565b60008167ffffffffffffffff168367ffffffffffffffff16116155c65781611d99565b5090919050565b60008161ffff168361ffff16116155c65781611d99565b6001600160a01b03811681146116d757600080fd5b60006020828403121561560b57600080fd5b8135611d99816155e4565b6000806040838503121561562957600080fd5b8235615634816155e4565b91506020830135615644816155e4565b809150509250929050565b6000806040838503121561566257600080fd5b823561566d816155e4565b946020939093013593505050565b80151581146116d757600080fd5b6000806040838503121561569c57600080fd5b82356156a7816155e4565b915060208301356156448161567b565b803561ffff8116811461234957600080fd5b600080604083850312156156dc57600080fd5b82356156e7816155e4565b91506156f5602084016156b7565b90509250929050565b6fffffffffffffffffffffffffffffffff811681146116d757600080fd5b6000806040838503121561572f57600080fd5b823561573a816155e4565b91506020830135615644816156fe565b60008060008060008060c0878903121561576357600080fd5b863561576e816155e4565b9550602087013561577e816155e4565b94506040870135935060608701359250608087013561579c816155e4565b915060a08701356157ac816155e4565b809150509295509295509295565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715615830576158306157ba565b604052919050565b6000602080838503121561584b57600080fd5b823567ffffffffffffffff8082111561586357600080fd5b818501915085601f83011261587757600080fd5b813581811115615889576158896157ba565b8060051b915061589a8483016157e9565b81815291830184019184810190888411156158b457600080fd5b938501935b838510156158de57843592506158ce836155e4565b82825293850193908501906158b9565b98975050505050505050565b6000806000806080858703121561590057600080fd5b843561590b816155e4565b9350615919602086016156b7565b92506040850135615929816156fe565b91506060850135615939816156fe565b939692955090935050565b60008060006060848603121561595957600080fd5b8335615964816155e4565b92506020840135615974816155e4565b929592945050506040919091013590565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000828210156159c6576159c6615985565b500390565b600082198211156159de576159de615985565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600060208284031215615a2457600080fd5b5051919050565b600060208284031215615a3d57600080fd5b815160ff81168114611d9957600080fd5b600181815b80851115615a8f578167ffffffffffffffff04821115615a7557615a75615985565b80851615615a8257918102915b93841c9390800290615a53565b509250929050565b600082615aa657506001611ffd565b81615ab357506000611ffd565b8160018114615ac95760028114615ad357615b08565b6001915050611ffd565b60ff841115615ae457615ae4615985565b6001841b915067ffffffffffffffff821115615b0257615b02615985565b50611ffd565b5060208310610133831016604e8410600b8410161715615b3e575081810a67ffffffffffffffff811115611fe257611fe2615985565b615b488383615a4e565b8067ffffffffffffffff04821115615b6257615b62615985565b029392505050565b6000611d9960ff841667ffffffffffffffff8416615a97565b600060208284031215615b9557600080fd5b8151611d99816155e4565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615bd857615bd8615985565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615c1b57615c1b615bdd565b500490565b6000825160005b81811015615c415760208186018101518583015201615c27565b81811115615c50576000828501525b509190910192915050565b600060208284031215615c6d57600080fd5b8151611d998161567b565b805167ffffffffffffffff8116811461234957600080fd5b600060808284031215615ca257600080fd5b6040516080810181811067ffffffffffffffff82111715615cc557615cc56157ba565b6040528251615cd3816156fe565b8152615ce160208401615c78565b6020820152615cf260408401615c78565b60408201526060830151615d058161567b565b60608201529392505050565b600067ffffffffffffffff80841680615d2c57615d2c615bdd565b9216919091049291505056fea2646970667358221220ecce7c86f0918a5fcc95e2d46ba8dde19c958d88c07360898bbfd509fd7eb31464736f6c634300080e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff
-----Decoded View---------------
Arg [0] : _quoteToken (address): 0x176211869cA2b568f2A7D4EE941E073a821EE1ff
-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000176211869ca2b568f2a7d4ee941e073a821ee1ff
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|---|---|---|---|---|
AVAX | 10.65% | $0.999843 | 1,740,047.2314 | $1,739,774.58 | |
AVAX | 8.77% | $106,732 | 13.4183 | $1,432,158.84 | |
AVAX | 5.06% | $49.05 | 16,842.0548 | $826,034.6 | |
AVAX | 3.01% | $3,945.5 | 124.7039 | $492,019.38 | |
AVAX | 1.46% | $0.999787 | 239,024.246 | $238,973.33 | |
BSC | 11.36% | $725.49 | 2,556.8957 | $1,855,006.12 | |
BSC | 3.30% | $0.999972 | 539,138.3637 | $539,123.27 | |
BSC | 0.49% | $3,934.93 | 20.1639 | $79,343.64 | |
BSC | 0.23% | $106,424.4 | 0.3511 | $37,361.65 | |
ARB | 5.82% | $1 | 948,305.8139 | $950,202.43 | |
ARB | 3.31% | $3,945.8 | 137.016 | $540,637.79 | |
ARB | 1.88% | $1 | 305,975.42 | $306,587.37 | |
ARB | 1.86% | $106,292 | 2.8598 | $303,979.17 | |
ARB | 1.18% | $1 | 193,155.7306 | $193,542.04 | |
ARB | 0.51% | $0.976975 | 85,860.1212 | $83,883.19 | |
POL | 4.25% | $1 | 693,389.6106 | $694,083 | |
POL | 3.00% | $106,091 | 4.6218 | $490,329.96 | |
POL | 1.63% | $3,934.93 | 67.866 | $267,047.96 | |
POL | 1.34% | $0.576661 | 380,595.7764 | $219,474.65 | |
POL | 1.33% | $1 | 217,709.1973 | $217,709.2 | |
POL | 1.26% | $1 | 205,608.3988 | $205,814.01 | |
OP | 4.78% | $1 | 780,325.5904 | $781,105.92 | |
OP | 2.66% | $3,945.5 | 110.1227 | $434,489.18 | |
OP | 1.99% | $2.38 | 136,335.2147 | $324,915.54 | |
OP | 1.34% | $0.999959 | 218,913.1498 | $218,904.17 | |
OP | 1.03% | $106,228 | 1.5874 | $168,630.04 | |
OP | 0.90% | $1 | 146,583.7999 | $146,730.38 | |
BASE | 3.50% | $1 | 571,225.7399 | $571,796.97 | |
BASE | 2.31% | $106,441 | 3.5486 | $377,720.35 | |
BASE | 2.11% | $3,939.5 | 87.2939 | $343,894.26 | |
BASE | 0.48% | $0.99982 | 78,709.0625 | $78,694.89 | |
MANTLE | 1.28% | $1 | 208,697.8711 | $209,115.27 | |
MANTLE | 0.97% | $3,939.3 | 40.1747 | $158,260.37 | |
MANTLE | 0.87% | $1 | 141,122.0644 | $141,404.31 | |
MANTLE | 0.86% | $4,143.54 | 33.9557 | $140,696.69 | |
MANTLE | 0.53% | $1.22 | 70,528.0042 | $86,044.17 | |
MANTLE | <0.01% | $0.12437 | 1 | $0.1243 | |
LINEA | 2.04% | $106,256 | 3.136 | $333,220.88 | |
LINEA | 0.51% | $1 | 83,975.387 | $84,059.36 | |
LINEA | 0.14% | $0.999972 | 22,249.5297 | $22,248.91 | |
LINEA | <0.01% | $3,946.74 | 0.3258 | $1,285.72 |
[ Download: CSV Export ]
[ 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.