Polygon Sponsored slots available. Book your slot here!
Contract Overview
Balance:
0 MATIC
MATIC Value:
$0.00
My Name Tag:
Not Available, login to update
Txn Hash |
Method
|
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x89868c5d7294bdc3fbc92b9db5b7c00d937a85e0f88121bfccc4960a5c988488 | 0x60c06040 | 23512052 | 503 days 15 hrs ago | 0x236eccab8cdcfedb099de85c4060024ba3ce4d46 | IN | Create: SigmaUnboundTokenSellerV1 | 0 MATIC | 0.06197457 |
[ Download CSV Export ]
Contract Name:
SigmaUnboundTokenSellerV1
Compiler Version
v0.6.12+commit.27d51765
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; interface IIndexPool { /** * @dev Token record data structure * @param bound is token bound to pool * @param ready has token been initialized * @param lastDenormUpdate timestamp of last denorm change * @param denorm denormalized weight * @param desiredDenorm desired denormalized weight (used for incremental changes) * @param index index of address in tokens array * @param balance token balance */ struct Record { bool bound; bool ready; uint40 lastDenormUpdate; uint96 denorm; uint96 desiredDenorm; uint8 index; uint256 balance; } /* ========== EVENTS ========== */ /** @dev Emitted when tokens are swapped. */ event LOG_SWAP( address indexed caller, address indexed tokenIn, address indexed tokenOut, uint256 tokenAmountIn, uint256 tokenAmountOut ); /** @dev Emitted when underlying tokens are deposited for pool tokens. */ event LOG_JOIN( address indexed caller, address indexed tokenIn, uint256 tokenAmountIn ); /** @dev Emitted when pool tokens are burned for underlying. */ event LOG_EXIT( address indexed caller, address indexed tokenOut, uint256 tokenAmountOut ); /** @dev Emitted when a token's weight updates. */ event LOG_DENORM_UPDATED(address indexed token, uint256 newDenorm); /** @dev Emitted when a token's desired weight is set. */ event LOG_DESIRED_DENORM_SET(address indexed token, uint256 desiredDenorm); /** @dev Emitted when a token is unbound from the pool. */ event LOG_TOKEN_REMOVED(address token); /** @dev Emitted when a token is unbound from the pool. */ event LOG_TOKEN_ADDED( address indexed token, uint256 desiredDenorm, uint256 minimumBalance ); /** @dev Emitted when a token's minimum balance is updated. */ event LOG_MINIMUM_BALANCE_UPDATED(address token, uint256 minimumBalance); /** @dev Emitted when a token reaches its minimum balance. */ event LOG_TOKEN_READY(address indexed token); /** @dev Emitted when public trades are enabled or disabled. */ event LOG_PUBLIC_SWAP_TOGGLED(bool isPublic); /** @dev Emitted when the swap fee is updated. */ event LOG_SWAP_FEE_UPDATED(uint256 swapFee); /** @dev Emitted when exit fee recipient is updated. */ event LOG_EXIT_FEE_RECIPIENT_UPDATED(address exitFeeRecipient); /** @dev Emitted when controller is updated. */ event LOG_CONTROLLER_UPDATED(address exitFeeRecipient); function configure( address controller, string calldata name, string calldata symbol ) external; function initialize( address[] calldata tokens, uint256[] calldata balances, uint96[] calldata denorms, address tokenProvider, address unbindHandler, address exitFeeRecipient ) external; function setSwapFee(uint256 swapFee) external; function setController(address controller) external; function delegateCompLikeToken(address token, address delegatee) external; function setExitFeeRecipient(address) external; function setPublicSwap(bool enabled) external; function reweighTokens( address[] calldata tokens, uint96[] calldata desiredDenorms ) external; function reindexTokens( address[] calldata tokens, uint96[] calldata desiredDenorms, uint256[] calldata minimumBalances ) external; function setMinimumBalance(address token, uint256 minimumBalance) external; function joinPool(uint256 poolAmountOut, uint256[] calldata maxAmountsIn) external; function joinswapExternAmountIn( address tokenIn, uint256 tokenAmountIn, uint256 minPoolAmountOut ) external returns (uint256/* poolAmountOut */); function joinswapPoolAmountOut( address tokenIn, uint256 poolAmountOut, uint256 maxAmountIn ) external returns (uint256/* tokenAmountIn */); function exitPool(uint256 poolAmountIn, uint256[] calldata minAmountsOut) external; function exitswapPoolAmountIn( address tokenOut, uint256 poolAmountIn, uint256 minAmountOut ) external returns (uint256/* tokenAmountOut */); function exitswapExternAmountOut( address tokenOut, uint256 tokenAmountOut, uint256 maxPoolAmountIn ) external returns (uint256/* poolAmountIn */); function gulp(address token) external; function swapExactAmountIn( address tokenIn, uint256 tokenAmountIn, address tokenOut, uint256 minAmountOut, uint256 maxPrice ) external returns (uint256/* tokenAmountOut */, uint256/* spotPriceAfter */); function swapExactAmountOut( address tokenIn, uint256 maxAmountIn, address tokenOut, uint256 tokenAmountOut, uint256 maxPrice ) external returns (uint256 /* tokenAmountIn */, uint256 /* spotPriceAfter */); function isPublicSwap() external view returns (bool); function getSwapFee() external view returns (uint256/* swapFee */); function getExitFee() external view returns (uint256/* exitFee */); function getController() external view returns (address); function getExitFeeRecipient() external view returns (address); function isBound(address t) external view returns (bool); function getNumTokens() external view returns (uint256); function getCurrentTokens() external view returns (address[] memory tokens); function getCurrentDesiredTokens() external view returns (address[] memory tokens); function getDenormalizedWeight(address token) external view returns (uint256/* denorm */); function getTokenRecord(address token) external view returns (Record memory record); function getTotalDenormalizedWeight() external view returns (uint256); function getBalance(address token) external view returns (uint256); function getMinimumBalance(address token) external view returns (uint256); function getUsedBalance(address token) external view returns (uint256); function getSpotPrice(address tokenIn, address tokenOut) external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; interface IUnboundTokenSeller { /* ========== Events ========== */ event PremiumPercentSet(uint8 premium); event NewTokensToSell(address indexed token, uint256 amountReceived); event SwappedTokens( address indexed tokenSold, address indexed tokenBought, uint256 soldAmount, uint256 boughtAmount ); /* ========== Mutative ========== */ function initialize(address controller_, address pool, uint8 premiumPercent) external; function handleUnbindToken(address token, uint256 amount) external; function setPremiumPercent(uint8 premiumPercent) external; function executeSwapTokensForExactTokens( address tokenIn, address tokenOut, uint256 amountOut, address[] calldata path ) external returns (uint256); function executeSwapExactTokensForTokens( address tokenIn, address tokenOut, uint256 amountIn, address[] calldata path ) external returns (uint256); function swapExactTokensForTokens( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut ) external returns (uint256); function swapTokensForExactTokens( address tokenIn, address tokenOut, uint256 amountOut, uint256 maxAmountIn ) external returns (uint256); /* ========== Views ========== */ function getPremiumPercent() external view returns (uint8); function calcInGivenOut( address tokenIn, address tokenOut, uint256 amountOut ) external view returns (uint256); function calcOutGivenIn( address tokenIn, address tokenOut, uint256 amountIn ) external view returns (uint256); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; /* ========== External Interfaces ========== */ import "@indexed-finance/uniswap-v2-oracle/contracts/interfaces/IIndexedUniswapV2Oracle.sol"; import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; /* ========== External Libraries ========== */ import "@indexed-finance/uniswap-v2-oracle/contracts/lib/PriceLibrary.sol"; import "@openzeppelin/contracts/token/ERC20/SafeERC20.sol"; /* ========== Internal Interfaces ========== */ import "./interfaces/IIndexPool.sol"; import "./interfaces/IUnboundTokenSeller.sol"; /** * @title SigmaUnboundTokenSellerV1 * @author d1ll0n * @dev Contract for swapping undesired tokens to desired tokens for * an index pool. * * This contract is deployed as a proxy for each index pool. * * When tokens are unbound from a pool, they are transferred to this * contract and sold on UniSwap or to anyone who calls the contract * in exchange for any token which is currently bound to its index pool * and which has a desired weight about zero. * * It uses a short-term uniswap price oracle to price swaps and has a * configurable premium rate which is used to decrease the expected * output from a swap and to reward callers for triggering a sale. * * The contract does not track the tokens it has received in order to * reduce gas spent by the pool contract. Tokens must be tracked via * events, meaning this is not well suited for trades with other smart * contracts. */ contract SigmaUnboundTokenSellerV1 is IUnboundTokenSeller { using SafeERC20 for IERC20; using PriceLibrary for PriceLibrary.TwoWayAveragePrice; /* ========== Constants ========== */ uint32 internal constant SHORT_TWAP_MIN_TIME_ELAPSED = 20 minutes; uint32 internal constant SHORT_TWAP_MAX_TIME_ELAPSED = 2 days; IUniswapV2Router02 internal immutable _uniswapRouter; IIndexedUniswapV2Oracle public immutable oracle; /* ========== Events ========== */ event PremiumPercentSet(uint8 premium); event NewTokensToSell( address indexed token, uint256 amountReceived ); /** * @param tokenSold Token sent to caller * @param tokenBought Token received from caller and sent to pool * @param soldAmount Amount of `tokenSold` paid to caller * @param boughtAmount Amount of `tokenBought` sent to pool */ event SwappedTokens( address indexed tokenSold, address indexed tokenBought, uint256 soldAmount, uint256 boughtAmount ); /* ========== Storage ========== */ address public controller; // Pool the contract is selling tokens for. IIndexPool internal _pool; // Premium on the amount paid in swaps. // Half goes to the caller, half is used to increase payments. uint8 internal _premiumPercent; // Reentrance lock bool internal _mutex; /* ========== Modifiers ========== */ modifier _control_ { require(msg.sender == controller, "ERR_NOT_CONTROLLER"); _; } modifier _lock_ { require(!_mutex, "ERR_REENTRY"); _mutex = true; _; _mutex = false; } modifier _desired_(address token) { IIndexPool.Record memory record = _pool.getTokenRecord(token); require(record.desiredDenorm > 0, "ERR_UNDESIRED_TOKEN"); _; } /* ========== Constructor ========== */ constructor( IUniswapV2Router02 uniswapRouter, IIndexedUniswapV2Oracle oracle_ ) public { _uniswapRouter = uniswapRouter; oracle = oracle_; } /** * @dev Initialize the proxy contract with the acceptable premium rate * and the address of the pool it is for. */ function initialize(address controller_, address pool, uint8 premiumPercent) external override { require(address(_pool) == address(0), "ERR_INITIALIZED"); require(pool != address(0), "ERR_NULL_ADDRESS"); require( premiumPercent > 0 && premiumPercent < 20, "ERR_PREMIUM" ); _premiumPercent = premiumPercent; _pool = IIndexPool(pool); controller = controller_; } /* ========== Controls ========== */ /** * @dev Receive `amount` of `token` from the pool. */ function handleUnbindToken(address token, uint256 amount) external override { require(msg.sender == address(_pool), "ERR_ONLY_POOL"); emit NewTokensToSell(token, amount); } /** * @dev Set the premium rate as a percent. */ function setPremiumPercent(uint8 premiumPercent) external override _control_ { require( premiumPercent > 0 && premiumPercent < 20, "ERR_PREMIUM" ); _premiumPercent = premiumPercent; emit PremiumPercentSet(premiumPercent); } /* ========== Token Swaps ========== */ /** * @dev Execute a trade with UniSwap to sell some tokens held by the contract * for some tokens desired by the pool and pays the caller the difference between * the maximum input value and the actual paid amount. * * @param tokenIn Token to sell to UniSwap * @param tokenOut Token to receive from UniSwapx * @param amountOut Exact amount of `tokenOut` to receive from UniSwap * @param path Swap path to execute */ function executeSwapTokensForExactTokens( address tokenIn, address tokenOut, uint256 amountOut, address[] calldata path ) external override _lock_ returns (uint256 premiumPaidToCaller) { // calcOutGivenIn uses tokenIn as the token the pool is receiving and // tokenOut as the token the pool is paying, whereas this function is // the reverse. uint256 maxAmountIn = calcOutGivenIn(tokenOut, tokenIn, amountOut); // Approve UniSwap to transfer the input tokens IERC20(tokenIn).safeApprove(address(_uniswapRouter), maxAmountIn); // Verify that the first token in the path is the input token and that // the last is the output token. require( path[0] == tokenIn && path[path.length - 1] == tokenOut, "ERR_PATH_TOKENS" ); // Execute the swap. uint256[] memory amounts = _uniswapRouter.swapTokensForExactTokens( amountOut, maxAmountIn, path, address(_pool), block.timestamp ); // Get the actual amount paid uint256 amountIn = amounts[0]; // If we did not swap the full amount, remove the UniSwap allowance. if (amountIn < maxAmountIn) { IERC20(tokenIn).safeApprove(address(_uniswapRouter), 0); premiumPaidToCaller = maxAmountIn - amountIn; // Transfer the difference between what the contract was willing to pay and // what it actually paid to the caller. IERC20(tokenIn).safeTransfer(msg.sender, premiumPaidToCaller); } // Update the pool's balance of the token. _pool.gulp(tokenOut); emit SwappedTokens( tokenIn, tokenOut, amountIn, amountOut ); } /** * @dev Executes a trade with UniSwap to sell some tokens held by the contract * for some tokens desired by the pool and pays the caller any tokens received * above the minimum acceptable output. * * @param tokenIn Token to sell to UniSwap * @param tokenOut Token to receive from UniSwap * @param amountIn Exact amount of `tokenIn` to give UniSwap * @param path Swap path to execute */ function executeSwapExactTokensForTokens( address tokenIn, address tokenOut, uint256 amountIn, address[] calldata path ) external override _lock_ returns (uint256 premiumPaidToCaller) { // calcInGivenOut uses tokenIn as the token the pool is receiving and // tokenOut as the token the pool is paying, whereas this function is // the reverse. uint256 minAmountOut = calcInGivenOut(tokenOut, tokenIn, amountIn); // Approve UniSwap to transfer the input tokens IERC20(tokenIn).safeApprove(address(_uniswapRouter), amountIn); // Verify that the first token in the path is the input token and that // the last is the output token. require( path[0] == tokenIn && path[path.length - 1] == tokenOut, "ERR_PATH_TOKENS" ); // Execute the swap. uint256[] memory amounts = _uniswapRouter.swapExactTokensForTokens( amountIn, minAmountOut, path, address(this), block.timestamp ); // Get the actual amount paid uint256 amountOut = amounts[amounts.length - 1]; if (amountOut > minAmountOut) { // Transfer any tokens received beyond the minimum acceptable payment // to the caller as a reward. premiumPaidToCaller = amountOut - minAmountOut; IERC20(tokenOut).safeTransfer(msg.sender, premiumPaidToCaller); } // Transfer the received tokens to the pool IERC20(tokenOut).safeTransfer(address(_pool), minAmountOut); // Update the pool's balance of the token. _pool.gulp(tokenOut); emit SwappedTokens( tokenIn, tokenOut, amountIn, amountOut ); } /** * @dev Swap exactly `amountIn` of `tokenIn` for at least `minAmountOut` * of `tokenOut`. * * @param tokenIn Token to sell to pool * @param tokenOut Token to buy from pool * @param amountIn Amount of `tokenIn` to sell to pool * @param minAmountOut Minimum amount of `tokenOut` to buy from pool */ function swapExactTokensForTokens( address tokenIn, address tokenOut, uint256 amountIn, uint256 minAmountOut ) external override _lock_ returns (uint256 amountOut) { amountOut = calcOutGivenIn(tokenIn, tokenOut, amountIn); // Verify the amount is above the provided minimum. require(amountOut >= minAmountOut, "ERR_MIN_AMOUNT_OUT"); // Transfer the input tokens to the pool IERC20(tokenIn).safeTransferFrom(msg.sender, address(_pool), amountIn); _pool.gulp(tokenIn); // Transfer the output tokens to the caller IERC20(tokenOut).safeTransfer(msg.sender, amountOut); emit SwappedTokens( tokenOut, tokenIn, amountOut, amountIn ); } /** * @dev Swap up to `maxAmountIn` of `tokenIn` for exactly `amountOut` * of `tokenOut`. * * @param tokenIn Token to sell to pool * @param tokenOut Token to buy from pool * @param amountOut Amount of `tokenOut` to buy from pool * @param maxAmountIn Maximum amount of `tokenIn` to sell to pool */ function swapTokensForExactTokens( address tokenIn, address tokenOut, uint256 amountOut, uint256 maxAmountIn ) external override _lock_ returns (uint256 amountIn) { amountIn = calcInGivenOut(tokenIn, tokenOut, amountOut); require(amountIn <= maxAmountIn, "ERR_MAX_AMOUNT_IN"); // Transfer the input tokens to the pool IERC20(tokenIn).safeTransferFrom(msg.sender, address(_pool), amountIn); _pool.gulp(tokenIn); // Transfer the output tokens to the caller IERC20(tokenOut).safeTransfer(msg.sender, amountOut); emit SwappedTokens( tokenOut, tokenIn, amountOut, amountIn ); } /* ========== Swap Queries ========== */ function getPremiumPercent() external view override returns (uint8) { return _premiumPercent; } /** * @dev Calculate the amount of `tokenIn` the pool will accept for * `amountOut` of `tokenOut`. */ function calcInGivenOut( address tokenIn, address tokenOut, uint256 amountOut ) public view override _desired_(tokenIn) returns (uint256 amountIn) { require( IERC20(tokenOut).balanceOf(address(this)) >= amountOut, "ERR_INSUFFICIENT_BALANCE" ); ( PriceLibrary.TwoWayAveragePrice memory avgPriceIn, PriceLibrary.TwoWayAveragePrice memory avgPriceOut ) = _getAveragePrices(tokenIn, tokenOut); // Compute the average weth value for `amountOut` of `tokenOut` uint144 avgOutValue = avgPriceOut.computeAverageEthForTokens(amountOut); // Compute the minimum weth value the contract must receive for `avgOutValue` uint256 minInValue = _minimumReceivedValue(avgOutValue); // Compute the average amount of `tokenIn` worth `minInValue` weth amountIn = avgPriceIn.computeAverageTokensForEth(minInValue); } /** * @dev Calculate the amount of `tokenOut` the pool will give for * `amountIn` of `tokenIn`. */ function calcOutGivenIn( address tokenIn, address tokenOut, uint256 amountIn ) public view override _desired_(tokenIn) returns (uint256 amountOut) { ( PriceLibrary.TwoWayAveragePrice memory avgPriceIn, PriceLibrary.TwoWayAveragePrice memory avgPriceOut ) = _getAveragePrices(tokenIn, tokenOut); // Compute the average weth value for `amountIn` of `tokenIn` uint144 avgInValue = avgPriceIn.computeAverageEthForTokens(amountIn); // Compute the maximum weth value the contract will give for `avgInValue` uint256 maxOutValue = _maximumPaidValue(avgInValue); // Compute the average amount of `tokenOut` worth `maxOutValue` weth amountOut = avgPriceOut.computeAverageTokensForEth(maxOutValue); require( IERC20(tokenOut).balanceOf(address(this)) >= amountOut, "ERR_INSUFFICIENT_BALANCE" ); } /* ========== Internal Functions ========== */ function _getAveragePrices(address token1, address token2) internal view returns ( PriceLibrary.TwoWayAveragePrice memory avgPrice1, PriceLibrary.TwoWayAveragePrice memory avgPrice2 ) { address[] memory tokens = new address[](2); tokens[0] = token1; tokens[1] = token2; PriceLibrary.TwoWayAveragePrice[] memory prices = oracle.computeTwoWayAveragePrices( tokens, SHORT_TWAP_MIN_TIME_ELAPSED, SHORT_TWAP_MAX_TIME_ELAPSED ); avgPrice1 = prices[0]; avgPrice2 = prices[1]; } function _maximumPaidValue(uint256 valueReceived) internal view returns (uint256 maxPaidValue) { maxPaidValue = (100 * valueReceived) / (100 - _premiumPercent); } function _minimumReceivedValue(uint256 valuePaid) internal view returns (uint256 minValueReceived) { minValueReceived = (valuePaid * (100 - _premiumPercent)) / 100; } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; /* ========== Libraries ========== */ import "../lib/PriceLibrary.sol"; import "../lib/FixedPoint.sol"; interface IIndexedUniswapV2Oracle { /* ========== Mutative Functions ========== */ function updatePrice(address token) external returns (bool); function updatePrices(address[] calldata tokens) external returns (bool[] memory); /* ========== Meta Price Queries ========== */ function hasPriceObservationInWindow(address token, uint256 priceKey) external view returns (bool); function getPriceObservationInWindow( address token, uint256 priceKey ) external view returns (PriceLibrary.PriceObservation memory); function getPriceObservationsInRange( address token, uint256 timeFrom, uint256 timeTo ) external view returns (PriceLibrary.PriceObservation[] memory prices); /* ========== Price Update Queries ========== */ function canUpdatePrice(address token) external view returns (bool); function canUpdatePrices(address[] calldata tokens) external view returns (bool[] memory); /* ========== Price Queries: Singular ========== */ function computeTwoWayAveragePrice( address token, uint256 minTimeElapsed, uint256 maxTimeElapsed ) external view returns (PriceLibrary.TwoWayAveragePrice memory); function computeAverageTokenPrice( address token, uint256 minTimeElapsed, uint256 maxTimeElapsed ) external view returns (FixedPoint.uq112x112 memory); function computeAverageEthPrice( address token, uint256 minTimeElapsed, uint256 maxTimeElapsed ) external view returns (FixedPoint.uq112x112 memory); /* ========== Price Queries: Multiple ========== */ function computeTwoWayAveragePrices( address[] calldata tokens, uint256 minTimeElapsed, uint256 maxTimeElapsed ) external view returns (PriceLibrary.TwoWayAveragePrice[] memory); function computeAverageTokenPrices( address[] calldata tokens, uint256 minTimeElapsed, uint256 maxTimeElapsed ) external view returns (FixedPoint.uq112x112[] memory); function computeAverageEthPrices( address[] calldata tokens, uint256 minTimeElapsed, uint256 maxTimeElapsed ) external view returns (FixedPoint.uq112x112[] memory); /* ========== Value Queries: Singular ========== */ function computeAverageEthForTokens( address token, uint256 tokenAmount, uint256 minTimeElapsed, uint256 maxTimeElapsed ) external view returns (uint144); function computeAverageTokensForEth( address token, uint256 wethAmount, uint256 minTimeElapsed, uint256 maxTimeElapsed ) external view returns (uint144); /* ========== Value Queries: Multiple ========== */ function computeAverageEthForTokens( address[] calldata tokens, uint256[] calldata tokenAmounts, uint256 minTimeElapsed, uint256 maxTimeElapsed ) external view returns (uint144[] memory); function computeAverageTokensForEth( address[] calldata tokens, uint256[] calldata wethAmounts, uint256 minTimeElapsed, uint256 maxTimeElapsed ) external view returns (uint144[] memory); }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; pragma experimental ABIEncoderV2; /* ========== Internal Libraries ========== */ import "./FixedPoint.sol"; import "./UniswapV2OracleLibrary.sol"; import "./UniswapV2Library.sol"; library PriceLibrary { using FixedPoint for FixedPoint.uq112x112; using FixedPoint for FixedPoint.uq144x112; /* ========= Structs ========= */ struct PriceObservation { uint32 timestamp; uint224 priceCumulativeLast; uint224 ethPriceCumulativeLast; } /** * @dev Average prices for a token in terms of weth and weth in terms of the token. * * Note: The average weth price is not equivalent to the reciprocal of the average * token price. See the UniSwap whitepaper for more info. */ struct TwoWayAveragePrice { uint224 priceAverage; uint224 ethPriceAverage; } /* ========= View Functions ========= */ function pairInitialized( address uniswapFactory, address token, address weth ) internal view returns (bool) { address pair = UniswapV2Library.pairFor(uniswapFactory, token, weth); (uint112 reserve0, uint112 reserve1,) = IUniswapV2Pair(pair).getReserves(); return reserve0 != 0 && reserve1 != 0; } function observePrice( address uniswapFactory, address tokenIn, address quoteToken ) internal view returns (uint32 /* timestamp */, uint224 /* priceCumulativeLast */) { (address token0, address token1) = UniswapV2Library.sortTokens(tokenIn, quoteToken); address pair = UniswapV2Library.calculatePair(uniswapFactory, token0, token1); if (token0 == tokenIn) { (uint256 price0Cumulative, uint32 blockTimestamp) = UniswapV2OracleLibrary.currentCumulativePrice0(pair); return (blockTimestamp, uint224(price0Cumulative)); } else { (uint256 price1Cumulative, uint32 blockTimestamp) = UniswapV2OracleLibrary.currentCumulativePrice1(pair); return (blockTimestamp, uint224(price1Cumulative)); } } /** * @dev Query the current cumulative price of a token in terms of weth * and the current cumulative price of weth in terms of the token. */ function observeTwoWayPrice( address uniswapFactory, address token, address weth ) internal view returns (PriceObservation memory) { (address token0, address token1) = UniswapV2Library.sortTokens(token, weth); address pair = UniswapV2Library.calculatePair(uniswapFactory, token0, token1); // Get the sorted token prices ( uint256 price0Cumulative, uint256 price1Cumulative, uint32 blockTimestamp ) = UniswapV2OracleLibrary.currentCumulativePrices(pair); // Check which token is weth and which is the token, // then build the price observation. if (token0 == token) { return PriceObservation({ timestamp: blockTimestamp, priceCumulativeLast: uint224(price0Cumulative), ethPriceCumulativeLast: uint224(price1Cumulative) }); } else { return PriceObservation({ timestamp: blockTimestamp, priceCumulativeLast: uint224(price1Cumulative), ethPriceCumulativeLast: uint224(price0Cumulative) }); } } /* ========= Utility Functions ========= */ /** * @dev Computes the average price of a token in terms of weth * and the average price of weth in terms of a token using two * price observations. */ function computeTwoWayAveragePrice( PriceObservation memory observation1, PriceObservation memory observation2 ) internal pure returns (TwoWayAveragePrice memory) { uint32 timeElapsed = uint32(observation2.timestamp - observation1.timestamp); FixedPoint.uq112x112 memory priceAverage = UniswapV2OracleLibrary.computeAveragePrice( observation1.priceCumulativeLast, observation2.priceCumulativeLast, timeElapsed ); FixedPoint.uq112x112 memory ethPriceAverage = UniswapV2OracleLibrary.computeAveragePrice( observation1.ethPriceCumulativeLast, observation2.ethPriceCumulativeLast, timeElapsed ); return TwoWayAveragePrice({ priceAverage: priceAverage._x, ethPriceAverage: ethPriceAverage._x }); } function computeAveragePrice( uint32 timestampStart, uint224 priceCumulativeStart, uint32 timestampEnd, uint224 priceCumulativeEnd ) internal pure returns (FixedPoint.uq112x112 memory) { return UniswapV2OracleLibrary.computeAveragePrice( priceCumulativeStart, priceCumulativeEnd, uint32(timestampEnd - timestampStart) ); } /** * @dev Computes the average price of the token the price observations * are for in terms of weth. */ function computeAverageTokenPrice( PriceObservation memory observation1, PriceObservation memory observation2 ) internal pure returns (FixedPoint.uq112x112 memory) { return UniswapV2OracleLibrary.computeAveragePrice( observation1.priceCumulativeLast, observation2.priceCumulativeLast, uint32(observation2.timestamp - observation1.timestamp) ); } /** * @dev Computes the average price of weth in terms of the token * the price observations are for. */ function computeAverageEthPrice( PriceObservation memory observation1, PriceObservation memory observation2 ) internal pure returns (FixedPoint.uq112x112 memory) { return UniswapV2OracleLibrary.computeAveragePrice( observation1.ethPriceCumulativeLast, observation2.ethPriceCumulativeLast, uint32(observation2.timestamp - observation1.timestamp) ); } /** * @dev Compute the average value in weth of `tokenAmount` of the * token that the average price values are for. */ function computeAverageEthForTokens( TwoWayAveragePrice memory prices, uint256 tokenAmount ) internal pure returns (uint144) { return FixedPoint.uq112x112(prices.priceAverage).mul(tokenAmount).decode144(); } /** * @dev Compute the average value of `wethAmount` weth in terms of * the token that the average price values are for. */ function computeAverageTokensForEth( TwoWayAveragePrice memory prices, uint256 wethAmount ) internal pure returns (uint144) { return FixedPoint.uq112x112(prices.ethPriceAverage).mul(wethAmount).decode144(); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; /************************************************************************************************ From https://github.com/Uniswap/uniswap-lib/blob/master/contracts/libraries/FixedPoint.sol Copied from the github repository at commit hash 9642a0705fdaf36b477354a4167a8cd765250860. Modifications: - Removed `sqrt` function Subject to the GPL-3.0 license *************************************************************************************************/ // a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format)) library FixedPoint { // range: [0, 2**112 - 1] // resolution: 1 / 2**112 struct uq112x112 { uint224 _x; } // range: [0, 2**144 - 1] // resolution: 1 / 2**112 struct uq144x112 { uint _x; } uint8 private constant RESOLUTION = 112; uint private constant Q112 = uint(1) << RESOLUTION; uint private constant Q224 = Q112 << RESOLUTION; // encode a uint112 as a UQ112x112 function encode(uint112 x) internal pure returns (uq112x112 memory) { return uq112x112(uint224(x) << RESOLUTION); } // encodes a uint144 as a UQ144x112 function encode144(uint144 x) internal pure returns (uq144x112 memory) { return uq144x112(uint256(x) << RESOLUTION); } // divide a UQ112x112 by a uint112, returning a UQ112x112 function div(uq112x112 memory self, uint112 x) internal pure returns (uq112x112 memory) { require(x != 0, "FixedPoint: DIV_BY_ZERO"); return uq112x112(self._x / uint224(x)); } // multiply a UQ112x112 by a uint, returning a UQ144x112 // reverts on overflow function mul(uq112x112 memory self, uint y) internal pure returns (uq144x112 memory) { uint z; require( y == 0 || (z = uint(self._x) * y) / y == uint(self._x), "FixedPoint: MULTIPLICATION_OVERFLOW" ); return uq144x112(z); } // returns a UQ112x112 which represents the ratio of the numerator to the denominator // equivalent to encode(numerator).div(denominator) function fraction(uint112 numerator, uint112 denominator) internal pure returns (uq112x112 memory) { require(denominator > 0, "FixedPoint: DIV_BY_ZERO"); return uq112x112((uint224(numerator) << RESOLUTION) / denominator); } // decode a UQ112x112 into a uint112 by truncating after the radix point function decode(uq112x112 memory self) internal pure returns (uint112) { return uint112(self._x >> RESOLUTION); } // decode a UQ144x112 into a uint144 by truncating after the radix point function decode144(uq144x112 memory self) internal pure returns (uint144) { return uint144(self._x >> RESOLUTION); } // take the reciprocal of a UQ112x112 function reciprocal(uq112x112 memory self) internal pure returns (uq112x112 memory) { require(self._x != 0, "FixedPoint: ZERO_RECIPROCAL"); return uq112x112(uint224(Q224 / self._x)); } }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; /* ========== Internal Interfaces ========== */ import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol"; /* ========== Internal Libraries ========== */ import "./FixedPoint.sol"; /************************************************************************************************ Originally from https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/libraries/UniswapV2OracleLibrary.sol This source code has been modified from the original, which was copied from the github repository at commit hash 6d03bede0a97c72323fa1c379ed3fdf7231d0b26. Subject to the GPL-3.0 license *************************************************************************************************/ // library with helper methods for oracles that are concerned with computing average prices library UniswapV2OracleLibrary { using FixedPoint for *; // helper function that returns the current block timestamp within the range of uint32, i.e. [0, 2**32 - 1] function currentBlockTimestamp() internal view returns (uint32) { return uint32(block.timestamp % 2**32); } // produces the cumulative prices using counterfactuals to save gas and avoid a call to sync. function currentCumulativePrices(address pair) internal view returns ( uint256 price0Cumulative, uint256 price1Cumulative, uint32 blockTimestamp ) { blockTimestamp = currentBlockTimestamp(); price0Cumulative = IUniswapV2Pair(pair).price0CumulativeLast(); price1Cumulative = IUniswapV2Pair(pair).price1CumulativeLast(); // if time has elapsed since the last update on the pair, mock the accumulated price values ( uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast ) = IUniswapV2Pair(pair).getReserves(); require( reserve0 != 0 && reserve1 != 0, "UniswapV2OracleLibrary::currentCumulativePrices: Pair has no reserves." ); if (blockTimestampLast != blockTimestamp) { // subtraction overflow is desired uint32 timeElapsed = blockTimestamp - blockTimestampLast; // addition overflow is desired // counterfactual price0Cumulative += ( uint256(FixedPoint.fraction(reserve1, reserve0)._x) * timeElapsed ); // counterfactual price1Cumulative += ( uint256(FixedPoint.fraction(reserve0, reserve1)._x) * timeElapsed ); } } // produces the cumulative price using counterfactuals to save gas and avoid a call to sync. // only gets the first price function currentCumulativePrice0(address pair) internal view returns (uint256 price0Cumulative, uint32 blockTimestamp) { blockTimestamp = currentBlockTimestamp(); price0Cumulative = IUniswapV2Pair(pair).price0CumulativeLast(); // if time has elapsed since the last update on the pair, mock the accumulated price values ( uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast ) = IUniswapV2Pair(pair).getReserves(); require( reserve0 != 0 && reserve1 != 0, "UniswapV2OracleLibrary::currentCumulativePrice0: Pair has no reserves." ); if (blockTimestampLast != blockTimestamp) { // subtraction overflow is desired uint32 timeElapsed = blockTimestamp - blockTimestampLast; // addition overflow is desired // counterfactual price0Cumulative += ( uint256(FixedPoint.fraction(reserve1, reserve0)._x) * timeElapsed ); } } // produces the cumulative price using counterfactuals to save gas and avoid a call to sync. // only gets the second price function currentCumulativePrice1(address pair) internal view returns (uint256 price1Cumulative, uint32 blockTimestamp) { blockTimestamp = currentBlockTimestamp(); price1Cumulative = IUniswapV2Pair(pair).price1CumulativeLast(); // if time has elapsed since the last update on the pair, mock the accumulated price values ( uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast ) = IUniswapV2Pair(pair).getReserves(); require( reserve0 != 0 && reserve1 != 0, "UniswapV2OracleLibrary::currentCumulativePrice1: Pair has no reserves." ); if (blockTimestampLast != blockTimestamp) { // subtraction overflow is desired uint32 timeElapsed = blockTimestamp - blockTimestampLast; // addition overflow is desired // counterfactual price1Cumulative += ( uint256(FixedPoint.fraction(reserve0, reserve1)._x) * timeElapsed ); } } function computeAveragePrice( uint224 priceCumulativeStart, uint224 priceCumulativeEnd, uint32 timeElapsed ) internal pure returns (FixedPoint.uq112x112 memory priceAverage) { // overflow is desired. priceAverage = FixedPoint.uq112x112( uint224((priceCumulativeEnd - priceCumulativeStart) / timeElapsed) ); } }
pragma solidity >=0.5.0; interface IUniswapV2Pair { event Approval(address indexed owner, address indexed spender, uint value); event Transfer(address indexed from, address indexed to, uint value); function name() external pure returns (string memory); function symbol() external pure returns (string memory); function decimals() external pure returns (uint8); function totalSupply() external view returns (uint); function balanceOf(address owner) external view returns (uint); function allowance(address owner, address spender) external view returns (uint); function approve(address spender, uint value) external returns (bool); function transfer(address to, uint value) external returns (bool); function transferFrom(address from, address to, uint value) external returns (bool); function DOMAIN_SEPARATOR() external view returns (bytes32); function PERMIT_TYPEHASH() external pure returns (bytes32); function nonces(address owner) external view returns (uint); function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external; event Mint(address indexed sender, uint amount0, uint amount1); event Burn(address indexed sender, uint amount0, uint amount1, address indexed to); event Swap( address indexed sender, uint amount0In, uint amount1In, uint amount0Out, uint amount1Out, address indexed to ); event Sync(uint112 reserve0, uint112 reserve1); function MINIMUM_LIQUIDITY() external pure returns (uint); function factory() external view returns (address); function token0() external view returns (address); function token1() external view returns (address); function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast); function price0CumulativeLast() external view returns (uint); function price1CumulativeLast() external view returns (uint); function kLast() external view returns (uint); function mint(address to) external returns (uint liquidity); function burn(address to) external returns (uint amount0, uint amount1); function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external; function skim(address to) external; function sync() external; function initialize(address, address) external; }
// SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.6.0; /************************************************************************************************ Originally from https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol This source code has been modified from the original, which was copied from the github repository at commit hash 87edfdcaf49ccc52591502993db4c8c08ea9eec0. Subject to the GPL-3.0 license *************************************************************************************************/ library UniswapV2Library { // returns sorted token addresses, used to handle return values from pairs sorted in this order function sortTokens(address tokenA, address tokenB) internal pure returns (address token0, address token1) { require(tokenA != tokenB, "UniswapV2Library: IDENTICAL_ADDRESSES"); (token0, token1) = tokenA < tokenB ? (tokenA, tokenB) : (tokenB, tokenA); require(token0 != address(0), "UniswapV2Library: ZERO_ADDRESS"); } function calculatePair( address factory, address token0, address token1 ) internal pure returns (address pair) { pair = address( uint256( keccak256( abi.encodePacked( hex"ff", factory, keccak256(abi.encodePacked(token0, token1)), hex"96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f" // init code hash ) ) ) ); } // calculates the CREATE2 address for a pair without making any external calls function pairFor( address factory, address tokenA, address tokenB ) internal pure returns (address pair) { (address token0, address token1) = sortTokens(tokenA, tokenB); pair = calculatePair(factory, token0, token1); } }
pragma solidity >=0.6.2; import './IUniswapV2Router01.sol'; interface IUniswapV2Router02 is IUniswapV2Router01 { function removeLiquidityETHSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountETH); function removeLiquidityETHWithPermitSupportingFeeOnTransferTokens( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountETH); function swapExactTokensForTokensSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; function swapExactETHForTokensSupportingFeeOnTransferTokens( uint amountOutMin, address[] calldata path, address to, uint deadline ) external payable; function swapExactTokensForETHSupportingFeeOnTransferTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external; }
pragma solidity >=0.6.2; interface IUniswapV2Router01 { function factory() external pure returns (address); function WETH() external pure returns (address); function addLiquidity( address tokenA, address tokenB, uint amountADesired, uint amountBDesired, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB, uint liquidity); function addLiquidityETH( address token, uint amountTokenDesired, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external payable returns (uint amountToken, uint amountETH, uint liquidity); function removeLiquidity( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline ) external returns (uint amountA, uint amountB); function removeLiquidityETH( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline ) external returns (uint amountToken, uint amountETH); function removeLiquidityWithPermit( address tokenA, address tokenB, uint liquidity, uint amountAMin, uint amountBMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountA, uint amountB); function removeLiquidityETHWithPermit( address token, uint liquidity, uint amountTokenMin, uint amountETHMin, address to, uint deadline, bool approveMax, uint8 v, bytes32 r, bytes32 s ) external returns (uint amountToken, uint amountETH); function swapExactTokensForTokens( uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapTokensForExactTokens( uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline ) external returns (uint[] memory amounts); function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapExactTokensForETH(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts); function swapETHForExactTokens(uint amountOut, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts); function quote(uint amountA, uint reserveA, uint reserveB) external pure returns (uint amountB); function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) external pure returns (uint amountOut); function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) external pure returns (uint amountIn); function getAmountsOut(uint amountIn, address[] calldata path) external view returns (uint[] memory amounts); function getAmountsIn(uint amountOut, address[] calldata path) external view returns (uint[] memory amounts); }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address sender, address recipient, uint256 amount) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; import "./IERC20.sol"; import "../../math/SafeMath.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 SafeMath for uint256; using Address for address; function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove(IERC20 token, address spender, uint256 value) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' // solhint-disable-next-line max-line-length require((value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).add(value); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 newAllowance = token.allowance(address(this), spender).sub(value, "SafeERC20: decreased allowance below zero"); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional // solhint-disable-next-line max-line-length require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { return sub(a, b, "SafeMath: subtraction overflow"); } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); uint256 c = a - b; return c; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) { return 0; } uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers. Reverts on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { return div(a, b, "SafeMath: division by zero"); } /** * @dev Returns the integer division of two unsigned integers. Reverts with custom message on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); uint256 c = a / b; // assert(a == b * c + a % b); // There is no case in which this doesn't hold return c; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { return mod(a, b, "SafeMath: modulo by zero"); } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * Reverts with custom message when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b != 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.2; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies in extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return _functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); return _functionCallWithValue(target, data, value, errorMessage); } function _functionCallWithValue(address target, bytes memory data, uint256 weiValue, string memory errorMessage) private returns (bytes memory) { require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: weiValue }(data); if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "metadata": { "useLiteralContent": false }, "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IUniswapV2Router02","name":"uniswapRouter","type":"address"},{"internalType":"contract IIndexedUniswapV2Oracle","name":"oracle_","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountReceived","type":"uint256"}],"name":"NewTokensToSell","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"premium","type":"uint8"}],"name":"PremiumPercentSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"tokenSold","type":"address"},{"indexed":true,"internalType":"address","name":"tokenBought","type":"address"},{"indexed":false,"internalType":"uint256","name":"soldAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"boughtAmount","type":"uint256"}],"name":"SwappedTokens","type":"event"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"}],"name":"calcInGivenOut","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"}],"name":"calcOutGivenIn","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"controller","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"executeSwapExactTokensForTokens","outputs":[{"internalType":"uint256","name":"premiumPaidToCaller","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"address[]","name":"path","type":"address[]"}],"name":"executeSwapTokensForExactTokens","outputs":[{"internalType":"uint256","name":"premiumPaidToCaller","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getPremiumPercent","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"token","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"handleUnbindToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"controller_","type":"address"},{"internalType":"address","name":"pool","type":"address"},{"internalType":"uint8","name":"premiumPercent","type":"uint8"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"oracle","outputs":[{"internalType":"contract IIndexedUniswapV2Oracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint8","name":"premiumPercent","type":"uint8"}],"name":"setPremiumPercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountIn","type":"uint256"},{"internalType":"uint256","name":"minAmountOut","type":"uint256"}],"name":"swapExactTokensForTokens","outputs":[{"internalType":"uint256","name":"amountOut","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"tokenIn","type":"address"},{"internalType":"address","name":"tokenOut","type":"address"},{"internalType":"uint256","name":"amountOut","type":"uint256"},{"internalType":"uint256","name":"maxAmountIn","type":"uint256"}],"name":"swapTokensForExactTokens","outputs":[{"internalType":"uint256","name":"amountIn","type":"uint256"}],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c06040523480156200001157600080fd5b5060405162001ff638038062001ff6833981016040819052620000349162000053565b6001600160601b0319606092831b8116608052911b1660a052620000aa565b6000806040838503121562000066578182fd5b8251620000738162000091565b6020840151909250620000868162000091565b809150509250929050565b6001600160a01b0381168114620000a757600080fd5b50565b60805160601c60a05160601c611f09620000ed600039806105825280611091525080610a265280610afb5280610bc45280610d265280610df85250611f096000f3fe608060405234801561001057600080fd5b50600436106100b45760003560e01c806389fe039b1161007157806389fe039b14610147578063b25ccf2c1461015a578063c1704af21461016d578063e11986d114610180578063f77c479114610193578063fdf520bb1461019b576100b4565b80633bc5ebe7146100b95780634f33937f146100e25780635ea27538146100f5578063633177101461010a5780637dc0d1d01461011f57806389232a0014610134575b600080fd5b6100cc6100c7366004611687565b6101ae565b6040516100d99190611d73565b60405180910390f35b6100cc6100f03660046115ab565b610307565b6100fd6104c1565b6040516100d99190611dfd565b61011d61011836600461194b565b6104d1565b005b610127610580565b6040516100d99190611983565b61011d6101423660046116ca565b6105a4565b6100cc610155366004611687565b61066c565b6100cc6101683660046115ab565b61079f565b61011d61017b366004611712565b610959565b6100cc61018e3660046115eb565b6109c8565b610127610cb9565b6100cc6101a93660046115eb565b610cc8565b600154600090600160a81b900460ff16156101e45760405162461bcd60e51b81526004016101db90611b7e565b60405180910390fd5b6001805460ff60a81b1916600160a81b179055610202858585610307565b9050818111156102245760405162461bcd60e51b81526004016101db90611b2a565b600154610240906001600160a01b038781169133911684610f7b565b600154604051631185197d60e31b81526001600160a01b0390911690638c28cbe890610270908890600401611983565b600060405180830381600087803b15801561028a57600080fd5b505af115801561029e573d6000803e3d6000fd5b506102b7925050506001600160a01b0385163385610fd9565b846001600160a01b0316846001600160a01b0316600080516020611eb483398151915285846040516102ea929190611d7c565b60405180910390a36001805460ff60a81b19169055949350505050565b6000836103126114a4565b6001546040516364c7d66160e01b81526001600160a01b03909116906364c7d66190610342908590600401611983565b60e06040518083038186803b15801561035a57600080fd5b505afa15801561036e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906103929190611892565b9050600081608001516001600160601b0316116103c15760405162461bcd60e51b81526004016101db90611afd565b6040516370a0823160e01b815284906001600160a01b038716906370a08231906103ef903090600401611983565b60206040518083038186803b15801561040757600080fd5b505afa15801561041b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061043f9190611933565b101561045d5760405162461bcd60e51b81526004016101db90611ce6565b6104656114e0565b61046d6114e0565b6104778888610ffd565b90925090506000610488828861115c565b9050600061049e826001600160901b0316611193565b90506104aa84826111b5565b6001600160901b03169a9950505050505050505050565b600154600160a01b900460ff1690565b6000546001600160a01b031633146104fb5760405162461bcd60e51b81526004016101db90611a85565b60008160ff16118015610511575060148160ff16105b61052d5760405162461bcd60e51b81526004016101db90611ad8565b6001805460ff60a01b1916600160a01b60ff8416021790556040517fc53b2421172f8be019daf92988365a3072876f2747c0a3d4b28cd13fcc6f005e90610575908390611dfd565b60405180910390a150565b7f000000000000000000000000000000000000000000000000000000000000000081565b6001546001600160a01b0316156105cd5760405162461bcd60e51b81526004016101db90611b55565b6001600160a01b0382166105f35760405162461bcd60e51b81526004016101db90611c72565b60008160ff16118015610609575060148160ff16105b6106255760405162461bcd60e51b81526004016101db90611ad8565b600180546001600160a01b039384166001600160a01b031960ff909416600160a01b0260ff60a01b1990921691909117831617905560008054939092169216919091179055565b600154600090600160a81b900460ff16156106995760405162461bcd60e51b81526004016101db90611b7e565b6001805460ff60a81b1916600160a81b1790556106b785858561079f565b9050818110156106d95760405162461bcd60e51b81526004016101db90611bcc565b6001546106f5906001600160a01b038781169133911686610f7b565b600154604051631185197d60e31b81526001600160a01b0390911690638c28cbe890610725908890600401611983565b600060405180830381600087803b15801561073f57600080fd5b505af1158015610753573d6000803e3d6000fd5b5061076c925050506001600160a01b0385163383610fd9565b846001600160a01b0316846001600160a01b0316600080516020611eb483398151915283866040516102ea929190611d7c565b6000836107aa6114a4565b6001546040516364c7d66160e01b81526001600160a01b03909116906364c7d661906107da908590600401611983565b60e06040518083038186803b1580156107f257600080fd5b505afa158015610806573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061082a9190611892565b9050600081608001516001600160601b0316116108595760405162461bcd60e51b81526004016101db90611afd565b6108616114e0565b6108696114e0565b6108738888610ffd565b90925090506000610884838861115c565b9050600061089a826001600160901b03166111e8565b90506108a683826111b5565b6001600160901b0316965086896001600160a01b03166370a08231306040518263ffffffff1660e01b81526004016108de9190611983565b60206040518083038186803b1580156108f657600080fd5b505afa15801561090a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061092e9190611933565b101561094c5760405162461bcd60e51b81526004016101db90611ce6565b5050505050509392505050565b6001546001600160a01b031633146109835760405162461bcd60e51b81526004016101db90611ab1565b816001600160a01b03167ff93f11706ef5199cb4b091ba127aefd4e260584c810114c438e1ac3ecddecd52826040516109bc9190611d73565b60405180910390a25050565b600154600090600160a81b900460ff16156109f55760405162461bcd60e51b81526004016101db90611b7e565b6001805460ff60a81b1916600160a81b1790556000610a1586888761079f565b9050610a4b6001600160a01b0388167f00000000000000000000000000000000000000000000000000000000000000008361120b565b866001600160a01b031684846000818110610a6257fe5b9050602002016020810190610a779190611590565b6001600160a01b0316148015610ac257506001600160a01b03861684846000198101818110610aa257fe5b9050602002016020810190610ab79190611590565b6001600160a01b0316145b610ade5760405162461bcd60e51b81526004016101db90611ba3565b600154604051634401edf760e11b81526060916001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000811692638803dbee92610b3c928b9288928c928c929116904290600401611d8a565b600060405180830381600087803b158015610b5657600080fd5b505af1158015610b6a573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610b9291908101906117df565b9050600081600081518110610ba357fe5b6020026020010151905082811015610c0357610bea6001600160a01b038a167f0000000000000000000000000000000000000000000000000000000000000000600061120b565b8083039350610c036001600160a01b038a163386610fd9565b600154604051631185197d60e31b81526001600160a01b0390911690638c28cbe890610c33908b90600401611983565b600060405180830381600087803b158015610c4d57600080fd5b505af1158015610c61573d6000803e3d6000fd5b50505050876001600160a01b0316896001600160a01b0316600080516020611eb4833981519152838a604051610c98929190611d7c565b60405180910390a350506001805460ff60a81b191690555095945050505050565b6000546001600160a01b031681565b600154600090600160a81b900460ff1615610cf55760405162461bcd60e51b81526004016101db90611b7e565b6001805460ff60a81b1916600160a81b1790556000610d15868887610307565b9050610d4b6001600160a01b0388167f00000000000000000000000000000000000000000000000000000000000000008761120b565b866001600160a01b031684846000818110610d6257fe5b9050602002016020810190610d779190611590565b6001600160a01b0316148015610dc257506001600160a01b03861684846000198101818110610da257fe5b9050602002016020810190610db79190611590565b6001600160a01b0316145b610dde5760405162461bcd60e51b81526004016101db90611ba3565b6040516338ed173960e01b81526060906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906338ed173990610e3790899086908a908a9030904290600401611d8a565b600060405180830381600087803b158015610e5157600080fd5b505af1158015610e65573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610e8d91908101906117df565b9050600081600183510381518110610ea157fe5b6020026020010151905082811115610ecc578281039350610ecc6001600160a01b0389163386610fd9565b600154610ee6906001600160a01b038a8116911685610fd9565b600154604051631185197d60e31b81526001600160a01b0390911690638c28cbe890610f16908b90600401611983565b600060405180830381600087803b158015610f3057600080fd5b505af1158015610f44573d6000803e3d6000fd5b50505050876001600160a01b0316896001600160a01b0316600080516020611eb48339815191528984604051610c98929190611d7c565b610fd3846323b872dd60e01b858585604051602401610f9c939291906119b1565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091526112ce565b50505050565b610ff88363a9059cbb60e01b8484604051602401610f9c9291906119d5565b505050565b6110056114e0565b61100d6114e0565b6040805160028082526060808301845292602083019080368337019050509050848160008151811061103b57fe5b60200260200101906001600160a01b031690816001600160a01b031681525050838160018151811061106957fe5b6001600160a01b03928316602091820292909201015260405163768d2c1960e01b81526060917f0000000000000000000000000000000000000000000000000000000000000000169063768d2c19906110cf9085906104b0906202a300906004016119ee565b60006040518083038186803b1580156110e757600080fd5b505afa1580156110fb573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611123919081019061173c565b90508060008151811061113257fe5b602002602001015193508060018151811061114957fe5b6020026020010151925050509250929050565b604080516020810190915282516001600160e01b0316815260009061118a90611185908461135d565b6113bc565b90505b92915050565b60015460009060649060ff600160a01b909104811682031683025b0492915050565b600061118a61118583604051806020016040528087602001516001600160e01b031681525061135d90919063ffffffff16565b6000600160149054906101000a900460ff1660640360ff1682606402816111ae57fe5b8015806112935750604051636eb1769f60e11b81526001600160a01b0384169063dd62ed3e906112419030908690600401611997565b60206040518083038186803b15801561125957600080fd5b505afa15801561126d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112919190611933565b155b6112af5760405162461bcd60e51b81526004016101db90611d1d565b610ff88363095ea7b360e01b8484604051602401610f9c9291906119d5565b6060611323826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166113c39092919063ffffffff16565b805190915015610ff85780806020019051810190611341919061186f565b610ff85760405162461bcd60e51b81526004016101db90611c9c565b6113656114f7565b600082158061138b57505082516001600160e01b03168281029083828161138857fe5b04145b6113a75760405162461bcd60e51b81526004016101db90611bf8565b60408051602081019091529081529392505050565b5160701c90565b60606113d284846000856113da565b949350505050565b60606113e58561149e565b6114015760405162461bcd60e51b81526004016101db90611c3b565b60006060866001600160a01b0316858760405161141e9190611967565b60006040518083038185875af1925050503d806000811461145b576040519150601f19603f3d011682016040523d82523d6000602084013e611460565b606091505b509150915081156114745791506113d29050565b8051156114845780518082602001fd5b8360405162461bcd60e51b81526004016101db9190611a52565b3b151590565b6040805160e081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905260c081019190915290565b604080518082019091526000808252602082015290565b6040518060200160405280600081525090565b80356001600160a01b038116811461118d57600080fd5b600060408284031215611532578081fd5b61153c6040611e0b565b90506115488383611562565b81526115578360208401611562565b602082015292915050565b80516001600160e01b038116811461118d57600080fd5b80516001600160601b038116811461118d57600080fd5b6000602082840312156115a1578081fd5b61118a838361150a565b6000806000606084860312156115bf578182fd5b83356115ca81611e7e565b925060208401356115da81611e7e565b929592945050506040919091013590565b600080600080600060808688031215611602578081fd5b853561160d81611e7e565b9450602086013561161d81611e7e565b935060408601359250606086013567ffffffffffffffff80821115611640578283fd5b818801915088601f830112611653578283fd5b813581811115611661578384fd5b8960208083028501011115611674578384fd5b9699959850939650602001949392505050565b6000806000806080858703121561169c578384fd5b6116a6868661150a565b93506116b5866020870161150a565b93969395505050506040820135916060013590565b6000806000606084860312156116de578283fd5b6116e8858561150a565b92506116f7856020860161150a565b9150604084013561170781611ea4565b809150509250925092565b60008060408385031215611724578182fd5b61172e848461150a565b946020939093013593505050565b6000602080838503121561174e578182fd5b825167ffffffffffffffff811115611764578283fd5b8301601f81018513611774578283fd5b805161178761178282611e32565b611e0b565b818152838101908385016040808502860187018a10156117a5578788fd5b8795505b848610156117d1576117bb8a83611521565b84526001959095019492860192908101906117a9565b509098975050505050505050565b600060208083850312156117f1578182fd5b825167ffffffffffffffff811115611807578283fd5b8301601f81018513611817578283fd5b805161182561178282611e32565b8181528381019083850185840285018601891015611841578687fd5b8694505b83851015611863578051835260019490940193918501918501611845565b50979650505050505050565b600060208284031215611880578081fd5b815161188b81611e96565b9392505050565b600060e082840312156118a3578081fd5b6118ad60e0611e0b565b82516118b881611e96565b815260208301516118c881611e96565b6020820152604083015164ffffffffff811681146118e4578283fd5b60408201526118f68460608501611579565b60608201526119088460808501611579565b608082015260a083015161191b81611ea4565b60a082015260c0928301519281019290925250919050565b600060208284031215611944578081fd5b5051919050565b60006020828403121561195c578081fd5b813561188b81611ea4565b60008251611979818460208701611e52565b9190910192915050565b6001600160a01b0391909116815260200190565b6001600160a01b0392831681529116602082015260400190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03929092168252602082015260400190565b606080825284519082018190526000906020906080840190828801845b82811015611a305781516001600160a01b031684529284019290840190600101611a0b565b50505063ffffffff958616918401919091529290931660409091015292915050565b6000602082528251806020840152611a71816040850160208701611e52565b601f01601f19169190910160400192915050565b60208082526012908201527122a9292fa727aa2fa1a7a72a2927a62622a960711b604082015260600190565b6020808252600d908201526c11549497d3d3931657d413d3d3609a1b604082015260600190565b6020808252600b908201526a4552525f5052454d49554d60a81b604082015260600190565b60208082526013908201527222a9292faaa72222a9a4a922a22faa27a5a2a760691b604082015260600190565b60208082526011908201527022a9292fa6a0ac2fa0a6a7aaa72a2fa4a760791b604082015260600190565b6020808252600f908201526e11549497d253925512505312569151608a1b604082015260600190565b6020808252600b908201526a4552525f5245454e54525960a81b604082015260600190565b6020808252600f908201526e4552525f504154485f544f4b454e5360881b604082015260600190565b60208082526012908201527111549497d3525397d05353d5539517d3d55560721b604082015260600190565b60208082526023908201527f4669786564506f696e743a204d554c5449504c49434154494f4e5f4f564552466040820152624c4f5760e81b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b60208082526010908201526f4552525f4e554c4c5f4144445245535360801b604082015260600190565b6020808252602a908201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6040820152691bdd081cdd58d8d9595960b21b606082015260800190565b60208082526018908201527f4552525f494e53554646494349454e545f42414c414e43450000000000000000604082015260600190565b60208082526036908201527f5361666545524332303a20617070726f76652066726f6d206e6f6e2d7a65726f60408201527520746f206e6f6e2d7a65726f20616c6c6f77616e636560501b606082015260800190565b90815260200190565b918252602082015260400190565b868152602080820187905260a0604083018190528201859052600090869060c08401835b88811015611ddc578383016001600160a01b03611dcb828761150a565b168352935090820190600101611dae565b506001600160a01b0396909616606085015250505060800152949350505050565b60ff91909116815260200190565b60405181810167ffffffffffffffff81118282101715611e2a57600080fd5b604052919050565b600067ffffffffffffffff821115611e48578081fd5b5060209081020190565b60005b83811015611e6d578181015183820152602001611e55565b83811115610fd35750506000910152565b6001600160a01b0381168114611e9357600080fd5b50565b8015158114611e9357600080fd5b60ff81168114611e9357600080fdfe43a6165165685ef04ce68fd0b620a88554df7464167d1fd61ff8b3802a4146f5a26469706673582212200b6871363346b722b8f668c18c082cede3ddc85abe6c7eed79e9a4f7fd986a4f64736f6c634300060c0033000000000000000000000000a5e0829caced8ffdd4de3c43696c57f7d7a678ff00000000000000000000000095129751769f99cc39824a0793ef4933dd8bb74b
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000a5e0829caced8ffdd4de3c43696c57f7d7a678ff00000000000000000000000095129751769f99cc39824a0793ef4933dd8bb74b
-----Decoded View---------------
Arg [0] : uniswapRouter (address): 0xa5e0829caced8ffdd4de3c43696c57f7d7a678ff
Arg [1] : oracle_ (address): 0x95129751769f99cc39824a0793ef4933dd8bb74b
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000a5e0829caced8ffdd4de3c43696c57f7d7a678ff
Arg [1] : 00000000000000000000000095129751769f99cc39824a0793ef4933dd8bb74b
Deployed ByteCode Sourcemap
1596:12529:12:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10314:670;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11250:894;;;;;;:::i;:::-;;:::i;11032:101::-;;;:::i;:::-;;;;;;;:::i;4448:253::-;;;;;;:::i;:::-;;:::i;:::-;;1979:47;;;:::i;:::-;;;;;;;:::i;3674:412::-;;;;;;:::i;:::-;;:::i;9257:730::-;;;;;;:::i;:::-;;:::i;12258:886::-;;;;;;:::i;:::-;;:::i;4195:192::-;;;;;;:::i;:::-;;:::i;5194:1666::-;;;;;;:::i;:::-;;:::i;2622:25::-;;;:::i;7282:1645::-;;;;;;:::i;:::-;;:::i;10314:670::-;3081:6;;10493:16;;-1:-1:-1;;;3081:6:12;;;;3080:7;3072:31;;;;-1:-1:-1;;;3072:31:12;;;;;;;:::i;:::-;;;;;;;;;3118:4;3109:13;;-1:-1:-1;;;;3109:13:12;-1:-1:-1;;;3109:13:12;;;10530:44:::1;10545:7:::0;10554:8;10564:9;10530:14:::1;:44::i;:::-;10519:55;;10600:11;10588:8;:23;;10580:53;;;;-1:-1:-1::0;;;10580:53:12::1;;;;;;;:::i;:::-;10737:5;::::0;10684:70:::1;::::0;-1:-1:-1;;;;;10684:32:12;;::::1;::::0;10717:10:::1;::::0;10737:5:::1;10745:8:::0;10684:32:::1;:70::i;:::-;10760:5;::::0;:19:::1;::::0;-1:-1:-1;;;10760:19:12;;-1:-1:-1;;;;;10760:5:12;;::::1;::::0;:10:::1;::::0;:19:::1;::::0;10771:7;;10760:19:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;10833:52:12::1;::::0;-1:-1:-1;;;;;;;;10833:29:12;::::1;10863:10;10875:9:::0;10833:29:::1;:52::i;:::-;10933:7;-1:-1:-1::0;;;;;10896:83:12::1;10917:8;-1:-1:-1::0;;;;;10896:83:12::1;-1:-1:-1::0;;;;;;;;;;;10948:9:12::1;10965:8;10896:83;;;;;;;:::i;:::-;;;;;;;;3135:6:::0;:14;;-1:-1:-1;;;;3135:14:12;;;10314:670;;-1:-1:-1;;;;10314:670:12:o;11250:894::-;11413:16;11391:7;3198:31;;:::i;:::-;3232:5;;:27;;-1:-1:-1;;;3232:27:12;;-1:-1:-1;;;;;3232:5:12;;;;:20;;:27;;3253:5;;3232:27;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3198:61;;3296:1;3273:6;:20;;;-1:-1:-1;;;;;3273:24:12;;3265:56;;;;-1:-1:-1;;;3265:56:12;;;;;;;:::i;:::-;11454:41:::1;::::0;-1:-1:-1;;;11454:41:12;;11499:9;;-1:-1:-1;;;;;11454:26:12;::::1;::::0;::::1;::::0;:41:::1;::::0;11489:4:::1;::::0;11454:41:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:54;;11439:109;;;;-1:-1:-1::0;;;11439:109:12::1;;;;;;;:::i;:::-;11562:49;;:::i;:::-;11619:50;;:::i;:::-;11678:36;11696:7;11705:8;11678:17;:36::i;:::-;11554:160:::0;;-1:-1:-1;11554:160:12;-1:-1:-1;11788:19:12::1;11810:49;11554:160:::0;11849:9;11810:38:::1;:49::i;:::-;11788:71;;11947:18;11968:34;11990:11;-1:-1:-1::0;;;;;11968:34:12::1;:21;:34::i;:::-;11947:55:::0;-1:-1:-1;12090:49:12::1;:10:::0;11947:55;12090:37:::1;:49::i;:::-;-1:-1:-1::0;;;;;12079:60:12::1;::::0;11250:894;-1:-1:-1;;;;;;;;;;11250:894:12:o;11032:101::-;11113:15;;-1:-1:-1;;;11113:15:12;;;;;11032:101::o;4448:253::-;3001:10;;-1:-1:-1;;;;;3001:10:12;2987;:24;2979:55;;;;-1:-1:-1;;;2979:55:12;;;;;;;:::i;:::-;4563:1:::1;4546:14;:18;;;:41;;;;;4585:2;4568:14;:19;;;4546:41;4531:83;;;;-1:-1:-1::0;;;4531:83:12::1;;;;;;;:::i;:::-;4620:15;:32:::0;;-1:-1:-1;;;;4620:32:12::1;-1:-1:-1::0;;;4620:32:12::1;::::0;::::1;;;::::0;;4663:33:::1;::::0;::::1;::::0;::::1;::::0;4620:32;;4663:33:::1;:::i;:::-;;;;;;;;4448:253:::0;:::o;1979:47::-;;;:::o;3674:412::-;3801:5;;-1:-1:-1;;;;;3801:5:12;3793:28;3785:56;;;;-1:-1:-1;;;3785:56:12;;;;;;;:::i;:::-;-1:-1:-1;;;;;3855:18:12;;3847:47;;;;-1:-1:-1;;;3847:47:12;;;;;;;:::i;:::-;3932:1;3915:14;:18;;;:41;;;;;3954:2;3937:14;:19;;;3915:41;3900:83;;;;-1:-1:-1;;;3900:83:12;;;;;;;:::i;:::-;3989:15;:32;;-1:-1:-1;;;;;4027:24:12;;;-1:-1:-1;;;;;;3989:32:12;;;;-1:-1:-1;;;3989:32:12;-1:-1:-1;;;;3989:32:12;;;;;;;4027:24;;;;;-1:-1:-1;4057:24:12;;;;;;;;;;;;;;3674:412::o;9257:730::-;3081:6;;9436:17;;-1:-1:-1;;;3081:6:12;;;;3080:7;3072:31;;;;-1:-1:-1;;;3072:31:12;;;;;;;:::i;:::-;3118:4;3109:13;;-1:-1:-1;;;;3109:13:12;-1:-1:-1;;;3109:13:12;;;9475:43:::1;9490:7:::0;9499:8;9509;9475:14:::1;:43::i;:::-;9463:55;;9601:12;9588:9;:25;;9580:56;;;;-1:-1:-1::0;;;9580:56:12::1;;;;;;;:::i;:::-;9740:5;::::0;9687:70:::1;::::0;-1:-1:-1;;;;;9687:32:12;;::::1;::::0;9720:10:::1;::::0;9740:5:::1;9748:8:::0;9687:32:::1;:70::i;:::-;9763:5;::::0;:19:::1;::::0;-1:-1:-1;;;9763:19:12;;-1:-1:-1;;;;;9763:5:12;;::::1;::::0;:10:::1;::::0;:19:::1;::::0;9774:7;;9763:19:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;-1:-1:-1::0;9836:52:12::1;::::0;-1:-1:-1;;;;;;;;9836:29:12;::::1;9866:10;9878:9:::0;9836:29:::1;:52::i;:::-;9936:7;-1:-1:-1::0;;;;;9899:83:12::1;9920:8;-1:-1:-1::0;;;;;9899:83:12::1;-1:-1:-1::0;;;;;;;;;;;9951:9:12::1;9968:8;9899:83;;;;;;;:::i;12258:886::-:0;12420:17;12398:7;3198:31;;:::i;:::-;3232:5;;:27;;-1:-1:-1;;;3232:27:12;;-1:-1:-1;;;;;3232:5:12;;;;:20;;:27;;3253:5;;3232:27;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;3198:61;;3296:1;3273:6;:20;;;-1:-1:-1;;;;;3273:24:12;;3265:56;;;;-1:-1:-1;;;3265:56:12;;;;;;;:::i;:::-;12455:49:::1;;:::i;:::-;12512:50;;:::i;:::-;12571:36;12589:7;12598:8;12571:17;:36::i;:::-;12447:160:::0;;-1:-1:-1;12447:160:12;-1:-1:-1;12679:18:12::1;12700:47;12447:160:::0;12738:8;12700:37:::1;:47::i;:::-;12679:68;;12831:19;12853:29;12871:10;-1:-1:-1::0;;;;;12853:29:12::1;:17;:29::i;:::-;12831:51:::0;-1:-1:-1;12973:51:12::1;:11:::0;12831:51;12973:38:::1;:51::i;:::-;-1:-1:-1::0;;;;;12961:63:12::1;;;13090:9;13052:8;-1:-1:-1::0;;;;;13045:26:12::1;;13080:4;13045:41;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:54;;13030:109;;;;-1:-1:-1::0;;;13030:109:12::1;;;;;;;:::i;:::-;3327:1;;;;12258:886:::0;;;;;;;:::o;4195:192::-;4317:5;;-1:-1:-1;;;;;4317:5:12;4295:10;:28;4287:54;;;;-1:-1:-1;;;4287:54:12;;;;;;;:::i;:::-;4368:5;-1:-1:-1;;;;;4352:30:12;;4375:6;4352:30;;;;;;:::i;:::-;;;;;;;;4195:192;;:::o;5194:1666::-;3081:6;;5384:27;;-1:-1:-1;;;3081:6:12;;;;3080:7;3072:31;;;;-1:-1:-1;;;3072:31:12;;;;;;;:::i;:::-;3118:4;3109:13;;-1:-1:-1;;;;3109:13:12;-1:-1:-1;;;3109:13:12;;;;5611:44:::1;5626:8:::0;5636:7;5645:9;5611:14:::1;:44::i;:::-;5589:66:::0;-1:-1:-1;5713:65:12::1;-1:-1:-1::0;;;;;5713:27:12;::::1;5749:14;5589:66:::0;5713:27:::1;:65::i;:::-;5922:7;-1:-1:-1::0;;;;;5911:18:12::1;:4;;5916:1;5911:7;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;5911:18:12::1;;:55;;;;-1:-1:-1::0;;;;;;5933:33:12;::::1;:4:::0;;-1:-1:-1;;5938:15:12;;5933:21;;::::1;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;5933:33:12::1;;5911:55;5896:101;;;;-1:-1:-1::0;;;5896:101:12::1;;;;;;;:::i;:::-;6158:5;::::0;6055:138:::1;::::0;-1:-1:-1;;;6055:138:12;;6028:24:::1;::::0;-1:-1:-1;;;;;6055:14:12::1;:39:::0;::::1;::::0;::::1;::::0;:138:::1;::::0;6102:9;;6119:11;;6138:4;;;;6158:5;::::1;::::0;6172:15:::1;::::0;6055:138:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;6055:138:12::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;6028:165;;6233:16;6252:7;6260:1;6252:10;;;;;;;;;;;;;;6233:29;;6356:11;6345:8;:22;6341:348;;;6377:55;-1:-1:-1::0;;;;;6377:27:12;::::1;6413:14;6430:1;6377:27;:55::i;:::-;6462:22:::0;;::::1;::::0;-1:-1:-1;6620:61:12::1;-1:-1:-1::0;;;;;6620:28:12;::::1;6649:10;6462:22:::0;6620:28:::1;:61::i;:::-;6741:5;::::0;:20:::1;::::0;-1:-1:-1;;;6741:20:12;;-1:-1:-1;;;;;6741:5:12;;::::1;::::0;:10:::1;::::0;:20:::1;::::0;6752:8;;6741:20:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;6808:8;-1:-1:-1::0;;;;;6772:83:12::1;6793:7;-1:-1:-1::0;;;;;6772:83:12::1;-1:-1:-1::0;;;;;;;;;;;6824:8:12::1;6840:9;6772:83;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1::0;;3135:6:12;:14;;-1:-1:-1;;;;3135:14:12;;;-1:-1:-1;5194:1666:12;;-1:-1:-1;;;;;5194:1666:12:o;2622:25::-;;;-1:-1:-1;;;;;2622:25:12;;:::o;7282:1645::-;3081:6;;7471:27;;-1:-1:-1;;;3081:6:12;;;;3080:7;3072:31;;;;-1:-1:-1;;;3072:31:12;;;;;;;:::i;:::-;3118:4;3109:13;;-1:-1:-1;;;;3109:13:12;-1:-1:-1;;;3109:13:12;;;;7699:43:::1;7714:8:::0;7724:7;7733:8;7699:14:::1;:43::i;:::-;7676:66:::0;-1:-1:-1;7800:62:12::1;-1:-1:-1::0;;;;;7800:27:12;::::1;7836:14;7853:8:::0;7800:27:::1;:62::i;:::-;8006:7;-1:-1:-1::0;;;;;7995:18:12::1;:4;;8000:1;7995:7;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;7995:18:12::1;;:55;;;;-1:-1:-1::0;;;;;;8017:33:12;::::1;:4:::0;;-1:-1:-1;;8022:15:12;;8017:21;;::::1;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;8017:33:12::1;;7995:55;7980:101;;;;-1:-1:-1::0;;;7980:101:12::1;;;;;;;:::i;:::-;8139:137;::::0;-1:-1:-1;;;8139:137:12;;8112:24:::1;::::0;-1:-1:-1;;;;;8139:14:12::1;:39;::::0;::::1;::::0;:137:::1;::::0;8186:8;;8202:12;;8222:4;;;;8242::::1;::::0;8255:15:::1;::::0;8139:137:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;8139:137:12::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;8112:164;;8317:17;8337:7;8362:1;8345:7;:14;:18;8337:27;;;;;;;;;;;;;;8317:47;;8386:12;8374:9;:24;8370:273;;;8542:24:::0;;::::1;::::0;-1:-1:-1;8574:62:12::1;-1:-1:-1::0;;;;;8574:29:12;::::1;8604:10;8542:24:::0;8574:29:::1;:62::i;:::-;8734:5;::::0;8696:59:::1;::::0;-1:-1:-1;;;;;8696:29:12;;::::1;::::0;8734:5:::1;8742:12:::0;8696:29:::1;:59::i;:::-;8808:5;::::0;:20:::1;::::0;-1:-1:-1;;;8808:20:12;;-1:-1:-1;;;;;8808:5:12;;::::1;::::0;:10:::1;::::0;:20:::1;::::0;8819:8;;8808:20:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;8875:8;-1:-1:-1::0;;;;;8839:83:12::1;8860:7;-1:-1:-1::0;;;;;8839:83:12::1;-1:-1:-1::0;;;;;;;;;;;8891:8:12::1;8907:9;8839:83;;;;;;;:::i;877:203:7:-:0;977:96;997:5;1027:27;;;1056:4;1062:2;1066:5;1004:68;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;1004:68:7;;;;;;;;;;;;;;-1:-1:-1;;;;;1004:68:7;-1:-1:-1;;;;;;1004:68:7;;;;;;;;;;977:19;:96::i;:::-;877:203;;;;:::o;696:175::-;778:86;798:5;828:23;;;853:2;857:5;805:58;;;;;;;;;:::i;778:86::-;696:175;;;:::o;13198:548:12:-;13299:48;;:::i;:::-;13355;;:::i;:::-;13444:16;;;13458:1;13444:16;;;13418:23;13444:16;;;;;13418:23;13444:16;;;;;;;;;;-1:-1:-1;13444:16:12;13418:42;;13478:6;13466;13473:1;13466:9;;;;;;;;;;;;;:18;-1:-1:-1;;;;;13466:18:12;;;-1:-1:-1;;;;;13466:18:12;;;;;13502:6;13490;13497:1;13490:9;;;;;;;;-1:-1:-1;;;;;13490:18:12;;;:9;;;;;;;;;:18;13564:123;;-1:-1:-1;;;13564:123:12;;13514:47;;13564:6;:33;;;;:123;;13605:6;;1843:10;;1912:6;;13564:123;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;13564:123:12;;;;;;;;;;;;:::i;:::-;13514:173;;13705:6;13712:1;13705:9;;;;;;;;;;;;;;13693:21;;13732:6;13739:1;13732:9;;;;;;;;;;;;;;13720:21;;13198:548;;;;;;;:::o;5708:223:2:-;5856:41;;;;;;;;;5877:19;;-1:-1:-1;;;;;5856:41:2;;;5834:7;;5856:70;;:58;;5902:11;5856:45;:58::i;:::-;:68;:70::i;:::-;5849:77;;5708:223;;;;;:::o;13937:186:12:-;14095:15;;14022:24;;14115:3;;14095:15;-1:-1:-1;;;14095:15:12;;;;;14089:21;;14076:35;;;14075:43;;;13937:186;-1:-1:-1;;13937:186:12:o;6070:224:2:-;6195:7;6217:72;:60;6266:10;6217:44;;;;;;;;6238:6;:22;;;-1:-1:-1;;;;;6217:44:2;;;;:48;;:60;;;;:::i;13750:182:12:-;13835:20;13911:15;;;;;;;;;;;13905:3;:21;13880:47;;13887:13;13881:3;:19;13880:47;;;;1340:613:7;1705:10;;;1704:62;;-1:-1:-1;1721:39:7;;-1:-1:-1;;;1721:39:7;;-1:-1:-1;;;;;1721:15:7;;;;;:39;;1745:4;;1752:7;;1721:39;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:44;1704:62;1696:150;;;;-1:-1:-1;;;1696:150:7;;;;;;;:::i;:::-;1856:90;1876:5;1906:22;;;1930:7;1939:5;1883:62;;;;;;;;;:::i;2959:751::-;3378:23;3404:69;3432:4;3404:69;;;;;;;;;;;;;;;;;3412:5;-1:-1:-1;;;;;3404:27:7;;;:69;;;;;:::i;:::-;3487:17;;3378:95;;-1:-1:-1;3487:21:7;3483:221;;3627:10;3616:30;;;;;;;;;;;;:::i;:::-;3608:85;;;;-1:-1:-1;;;3608:85:7;;;;;;;:::i;1647:253:1:-;1714:16;;:::i;:::-;1738:6;1765;;;:54;;-1:-1:-1;;1811:7:1;;-1:-1:-1;;;;;1806:13:1;1780:17;;;;1801:1;1780:17;1801:1;1775:27;;;;;:44;1765:54;1750:120;;;;-1:-1:-1;;;1750:120:1;;;;;;;:::i;:::-;1883:12;;;;;;;;;;;;;1647:253;-1:-1:-1;;;1647:253:1:o;2556:122::-;2651:7;873:3;2651:21;;2556:122::o;3573:194:8:-;3676:12;3707:53;3730:6;3738:4;3744:1;3747:12;3707:22;:53::i;:::-;3700:60;3573:194;-1:-1:-1;;;;3573:194:8:o;4920:958::-;5050:12;5082:18;5093:6;5082:10;:18::i;:::-;5074:60;;;;-1:-1:-1;;;5074:60:8;;;;;;;:::i;:::-;5205:12;5219:23;5246:6;-1:-1:-1;;;;;5246:11:8;5266:8;5277:4;5246:36;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5204:78;;;;5296:7;5292:580;;;5326:10;-1:-1:-1;5319:17:8;;-1:-1:-1;5319:17:8;5292:580;5437:17;;:21;5433:429;;5695:10;5689:17;5755:15;5742:10;5738:2;5734:19;5727:44;5644:145;5834:12;5827:20;;-1:-1:-1;;;5827:20:8;;;;;;;;:::i;718:413::-;1078:20;1116:8;;;718:413::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;:::o;5:130::-;72:20;;-1:-1;;;;;31902:54;;33472:35;;33462:2;;33521:1;;33511:12;3665:529;;3800:4;3788:9;3783:3;3779:19;3775:30;3772:2;;;-1:-1;;3808:12;3772:2;3836:20;3800:4;3836:20;:::i;:::-;3827:29;;3946:60;4002:3;3978:22;3946:60;:::i;:::-;3928:16;3921:86;4112:60;4168:3;4079:2;4148:9;4144:22;4112:60;:::i;:::-;4079:2;4098:5;4094:16;4087:86;3766:428;;;;:::o;4201:134::-;4279:13;;-1:-1;;;;;32030:70;;33714:35;;33704:2;;33763:1;;33753:12;5029:132;5106:13;;-1:-1;;;;;32532:38;;34203:34;;34193:2;;34251:1;;34241:12;5168:241;;5272:2;5260:9;5251:7;5247:23;5243:32;5240:2;;;-1:-1;;5278:12;5240:2;5340:53;5385:7;5361:22;5340:53;:::i;5416:491::-;;;;5554:2;5542:9;5533:7;5529:23;5525:32;5522:2;;;-1:-1;;5560:12;5522:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;5612:63;-1:-1;5712:2;5751:22;;72:20;97:33;72:20;97:33;:::i;:::-;5516:391;;5720:63;;-1:-1;;;5820:2;5859:22;;;;4409:20;;5516:391::o;5914:773::-;;;;;;6104:3;6092:9;6083:7;6079:23;6075:33;6072:2;;;-1:-1;;6111:12;6072:2;85:6;72:20;97:33;124:5;97:33;:::i;:::-;6163:63;-1:-1;6263:2;6302:22;;72:20;97:33;72:20;97:33;:::i;:::-;6271:63;-1:-1;6371:2;6410:22;;4409:20;;-1:-1;6507:2;6492:18;;6479:32;6531:18;6520:30;;;6517:2;;;-1:-1;;6553:12;6517:2;6654:6;6643:9;6639:22;;;290:3;283:4;275:6;271:17;267:27;257:2;;-1:-1;;298:12;257:2;341:6;328:20;6531:18;360:6;357:30;354:2;;;-1:-1;;390:12;354:2;485:3;6263:2;;469:6;465:17;426:6;451:32;;448:41;445:2;;;-1:-1;;492:12;445:2;6066:621;;;;-1:-1;6066:621;;-1:-1;6263:2;422:17;;6573:98;6066:621;-1:-1;;;6066:621::o;6694:617::-;;;;;6849:3;6837:9;6828:7;6824:23;6820:33;6817:2;;;-1:-1;;6856:12;6817:2;6918:53;6963:7;6939:22;6918:53;:::i;:::-;6908:63;;7026:53;7071:7;7008:2;7051:9;7047:22;7026:53;:::i;:::-;6811:500;;7016:63;;-1:-1;;;;7116:2;7155:22;;4409:20;;7224:2;7263:22;4409:20;;6811:500::o;7318:487::-;;;;7454:2;7442:9;7433:7;7429:23;7425:32;7422:2;;;-1:-1;;7460:12;7422:2;7522:53;7567:7;7543:22;7522:53;:::i;:::-;7512:63;;7630:53;7675:7;7612:2;7655:9;7651:22;7630:53;:::i;:::-;7620:63;;7720:2;7761:9;7757:22;4824:20;4849:31;4874:5;4849:31;:::i;:::-;7728:61;;;;7416:389;;;;;:::o;7812:366::-;;;7933:2;7921:9;7912:7;7908:23;7904:32;7901:2;;;-1:-1;;7939:12;7901:2;8001:53;8046:7;8022:22;8001:53;:::i;:::-;7991:63;8091:2;8130:22;;;;4409:20;;-1:-1;;;7895:283::o;8185:462::-;;8360:2;;8348:9;8339:7;8335:23;8331:32;8328:2;;;-1:-1;;8366:12;8328:2;8417:17;8411:24;8455:18;8447:6;8444:30;8441:2;;;-1:-1;;8477:12;8441:2;8599:22;;725:4;713:17;;709:27;-1:-1;699:2;;-1:-1;;740:12;699:2;780:6;774:13;802:115;817:99;909:6;817:99;:::i;:::-;802:115;:::i;:::-;945:21;;;1002:14;;;;977:17;;;1103:4;1091:17;;;1082:27;;;;1079:36;-1:-1;1076:2;;;-1:-1;;1118:12;1076:2;-1:-1;1144:10;;1138:252;1163:6;1160:1;1157:13;1138:252;;;1243:83;1322:3;1310:10;1243:83;:::i;:::-;1231:96;;1185:1;1178:9;;;;;1341:14;;;;1369;;;;1138:252;;;-1:-1;8497:134;;8322:325;-1:-1;;;;;;;;8322:325::o;8654:392::-;;8794:2;;8782:9;8773:7;8769:23;8765:32;8762:2;;;-1:-1;;8800:12;8762:2;8851:17;8845:24;8889:18;8881:6;8878:30;8875:2;;;-1:-1;;8911:12;8875:2;8998:22;;1543:4;1531:17;;1527:27;-1:-1;1517:2;;-1:-1;;1558:12;1517:2;1598:6;1592:13;1620:80;1635:64;1692:6;1635:64;:::i;1620:80::-;1728:21;;;1785:14;;;;1760:17;;;1874;;;1865:27;;;;1862:36;-1:-1;1859:2;;;-1:-1;;1901:12;1859:2;-1:-1;1927:10;;1921:217;1946:6;1943:1;1940:13;1921:217;;;4557:13;;2014:61;;1968:1;1961:9;;;;;2089:14;;;;2117;;1921:217;;;-1:-1;8931:99;8756:290;-1:-1;;;;;;;8756:290::o;9053:257::-;;9165:2;9153:9;9144:7;9140:23;9136:32;9133:2;;;-1:-1;;9171:12;9133:2;2233:6;2227:13;2245:30;2269:5;2245:30;:::i;:::-;9223:71;9127:183;-1:-1;;;9127:183::o;9317:312::-;;9456:3;9444:9;9435:7;9431:23;9427:33;9424:2;;;-1:-1;;9463:12;9424:2;2478:20;9456:3;2478:20;:::i;:::-;2233:6;2227:13;2245:30;2269:5;2245:30;:::i;:::-;2556:83;;2701:2;2763:22;;2227:13;2245:30;2227:13;2245:30;:::i;:::-;2701:2;2716:16;;2709:83;2865:2;2929:22;;4697:13;32358:12;32347:24;;33961:34;;33951:2;;-1:-1;;33999:12;33951:2;2865;2880:16;;2873:85;3054:59;3109:3;3021:2;3085:22;;3054:59;:::i;:::-;3021:2;3040:5;3036:16;3029:85;3218:59;3273:3;3184;3253:9;3249:22;3218:59;:::i;:::-;3184:3;3204:5;3200:16;3193:85;3340:3;3408:9;3404:22;4968:13;4986:31;5011:5;4986:31;:::i;:::-;3340:3;3356:16;;3349:84;3497:3;3563:22;;;4557:13;3513:16;;;3506:86;;;;-1:-1;3360:5;9418:211;-1:-1;9418:211::o;9636:263::-;;9751:2;9739:9;9730:7;9726:23;9722:32;9719:2;;;-1:-1;;9757:12;9719:2;-1:-1;4557:13;;9713:186;-1:-1;9713:186::o;9906:237::-;;10008:2;9996:9;9987:7;9983:23;9979:32;9976:2;;;-1:-1;;10014:12;9976:2;4837:6;4824:20;4849:31;4874:5;4849:31;:::i;18355:271::-;;12155:5;30480:12;12266:52;12311:6;12306:3;12299:4;12292:5;12288:16;12266:52;:::i;:::-;12330:16;;;;;18489:137;-1:-1;;18489:137::o;18633:222::-;-1:-1;;;;;31902:54;;;;10393:37;;18760:2;18745:18;;18731:124::o;18862:333::-;-1:-1;;;;;31902:54;;;10393:37;;31902:54;;19181:2;19166:18;;10393:37;19017:2;19002:18;;18988:207::o;19202:444::-;-1:-1;;;;;31902:54;;;10393:37;;31902:54;;;;19549:2;19534:18;;10393:37;19632:2;19617:18;;18061:37;;;;19385:2;19370:18;;19356:290::o;19653:333::-;-1:-1;;;;;31902:54;;;;10393:37;;19972:2;19957:18;;18061:37;19808:2;19793:18;;19779:207::o;19993:588::-;20224:2;20238:47;;;30480:12;;20209:18;;;31129:19;;;19993:588;;31178:4;;31169:14;;;;30334;;;19993:588;11705:260;11730:6;11727:1;11724:13;11705:260;;;11791:13;;-1:-1;;;;;31902:54;10393:37;;10304:14;;;;30869;;;;31913:42;11745:9;11705:260;;;-1:-1;;;32263:10;32252:22;;;20470:18;;;18180:49;;;;32252:22;;;;20567:2;20552:18;;;18180:49;20291:116;20195:386;-1:-1;;20195:386::o;20879:310::-;;21026:2;21047:17;21040:47;12698:5;30480:12;31141:6;21026:2;21015:9;21011:18;31129:19;12792:52;12837:6;31169:14;21015:9;31169:14;21026:2;12818:5;12814:16;12792:52;:::i;:::-;33392:7;33376:14;-1:-1;;33372:28;12856:39;;;;31169:14;12856:39;;20997:192;-1:-1;;20997:192::o;21196:416::-;21396:2;21410:47;;;13132:2;21381:18;;;31129:19;-1:-1;;;31169:14;;;13148:41;13208:12;;;21367:245::o;21619:416::-;21819:2;21833:47;;;13459:2;21804:18;;;31129:19;-1:-1;;;31169:14;;;13475:36;13530:12;;;21790:245::o;22042:416::-;22242:2;22256:47;;;13781:2;22227:18;;;31129:19;-1:-1;;;31169:14;;;13797:34;13850:12;;;22213:245::o;22465:416::-;22665:2;22679:47;;;14101:2;22650:18;;;31129:19;-1:-1;;;31169:14;;;14117:42;14178:12;;;22636:245::o;22888:416::-;23088:2;23102:47;;;14429:2;23073:18;;;31129:19;-1:-1;;;31169:14;;;14445:40;14504:12;;;23059:245::o;23311:416::-;23511:2;23525:47;;;14755:2;23496:18;;;31129:19;-1:-1;;;31169:14;;;14771:38;14828:12;;;23482:245::o;23734:416::-;23934:2;23948:47;;;15079:2;23919:18;;;31129:19;-1:-1;;;31169:14;;;15095:34;15148:12;;;23905:245::o;24157:416::-;24357:2;24371:47;;;15399:2;24342:18;;;31129:19;-1:-1;;;31169:14;;;15415:38;15472:12;;;24328:245::o;24580:416::-;24780:2;24794:47;;;15723:2;24765:18;;;31129:19;-1:-1;;;31169:14;;;15739:41;15799:12;;;24751:245::o;25003:416::-;25203:2;25217:47;;;16050:2;25188:18;;;31129:19;16086:34;31169:14;;;16066:55;-1:-1;;;16141:12;;;16134:27;16180:12;;;25174:245::o;25426:416::-;25626:2;25640:47;;;16431:2;25611:18;;;31129:19;16467:31;31169:14;;;16447:52;16518:12;;;25597:245::o;25849:416::-;26049:2;26063:47;;;16769:2;26034:18;;;31129:19;-1:-1;;;31169:14;;;16785:39;16843:12;;;26020:245::o;26272:416::-;26472:2;26486:47;;;17094:2;26457:18;;;31129:19;17130:34;31169:14;;;17110:55;-1:-1;;;17185:12;;;17178:34;17231:12;;;26443:245::o;26695:416::-;26895:2;26909:47;;;17482:2;26880:18;;;31129:19;17518:26;31169:14;;;17498:47;17564:12;;;26866:245::o;27118:416::-;27318:2;27332:47;;;17815:2;27303:18;;;31129:19;17851:34;31169:14;;;17831:55;-1:-1;;;17906:12;;;17899:46;17964:12;;;27289:245::o;27541:222::-;18061:37;;;27668:2;27653:18;;27639:124::o;27770:333::-;18061:37;;;28089:2;28074:18;;18061:37;27925:2;27910:18;;27896:207::o;28110:836::-;18061:37;;;28574:2;28559:18;;;18061:37;;;28409:3;28611:2;28596:18;;28589:48;;;28394:19;;31129;;;28110:836;;10918:21;;31169:14;;;28110:836;10945:291;10970:6;10967:1;10964:13;10945:291;;;31623:12;;;-1:-1;;;;;31597:39;31623:12;11066:6;31597:39;:::i;:::-;31902:54;10393:37;;11157:72;-1:-1;10304:14;;;;10992:1;10985:9;10945:291;;;-1:-1;;;;;;31902:54;;;;28848:2;28833:18;;10393:37;-1:-1;;;28931:3;28916:19;18061:37;28643:126;28380:566;-1:-1;;;;28380:566::o;28953:214::-;32454:4;32443:16;;;;18308:35;;29076:2;29061:18;;29047:120::o;29174:256::-;29236:2;29230:9;29262:17;;;29337:18;29322:34;;29358:22;;;29319:62;29316:2;;;29394:1;;29384:12;29316:2;29236;29403:22;29214:216;;-1:-1;29214:216::o;29437:339::-;;29631:18;29623:6;29620:30;29617:2;;;-1:-1;;29653:12;29617:2;-1:-1;29698:4;29686:17;;;29751:15;;29554:222::o;33032:268::-;33097:1;33104:101;33118:6;33115:1;33112:13;33104:101;;;33185:11;;;33179:18;33166:11;;;33159:39;33140:2;33133:10;33104:101;;;33220:6;33217:1;33214:13;33211:2;;;-1:-1;;33097:1;33267:16;;33260:27;33081:219::o;33413:117::-;-1:-1;;;;;31902:54;;33472:35;;33462:2;;33521:1;;33511:12;33462:2;33456:74;:::o;33537:111::-;33618:5;31814:13;31807:21;33596:5;33593:32;33583:2;;33639:1;;33629:12;34025:113;32454:4;34108:5;32443:16;34085:5;34082:33;34072:2;;34129:1;;34119:12
Swarm Source
ipfs://0b6871363346b722b8f668c18c082cede3ddc85abe6c7eed79e9a4f7fd986a4f
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.