Contract Overview
Balance:
0 ETH
ETH Value:
$0.00
My Name Tag:
Not Available
Txn Hash | Method |
Block
|
From
|
To
|
Value | [Txn Fee] | |||
---|---|---|---|---|---|---|---|---|---|
0x22aa2613f3f3c7d4d1e7179a96aa2b9dece1f3cc521c6f3ae5620fd5e02f3d86 | 0x60c03461 | 14904528 | 650 days 10 hrs ago | 0xab9769cd4028541ee351cec203a24bf3b873b403 | IN | Create: ChainlinkOracle | 0 ETH | 0.00314666731 ETH |
[ Download CSV Export ]
Latest 25 internal transaction
[ Download CSV Export ]
Contract Name:
ChainlinkOracle
Compiler Version
v0.8.14+commit.80d49f37
Optimization Enabled:
Yes with 4999 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.4; import { Initializable } from '@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol'; import { AggregatorV3Interface } from '@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol'; import { FlagsInterface } from '@chainlink/contracts/src/v0.8/interfaces/FlagsInterface.sol'; import { FixedPoint96 } from '@uniswap/v3-core-0.8-support/contracts/libraries/FixedPoint96.sol'; import { FixedPoint128 } from '@uniswap/v3-core-0.8-support/contracts/libraries/FixedPoint128.sol'; import { FullMath } from '@uniswap/v3-core-0.8-support/contracts/libraries/FullMath.sol'; import { SafeCast } from '@uniswap/v3-core-0.8-support/contracts/libraries/SafeCast.sol'; import { AddressHelper } from '../libraries/AddressHelper.sol'; import { PriceMath } from '../libraries/PriceMath.sol'; import { IOracle } from '../interfaces/IOracle.sol'; contract ChainlinkOracle is IOracle { using AddressHelper for address; using FullMath for uint256; using SafeCast for uint256; using PriceMath for uint256; AggregatorV3Interface public aggregator; FlagsInterface public chainlinkFlags; uint8 immutable vTokenDecimals; uint8 immutable vQuoteDecimals; address private constant FLAG_ARBITRUM_SEQ_OFFLINE = address(bytes20(bytes32(uint256(keccak256('chainlink.flags.arbitrum-seq-offline')) - 1))); error NotEnoughHistory(); error SequencerOffline(); error IllegalAggregatorAddress(address aggregator); constructor( address _aggregator, address _flags, uint8 _vTokenDecimals, uint8 _vQuoteDecimals ) { if (_aggregator.isZero()) revert IllegalAggregatorAddress(address(0)); aggregator = AggregatorV3Interface(_aggregator); chainlinkFlags = FlagsInterface(_flags); vTokenDecimals = _vTokenDecimals; vQuoteDecimals = _vQuoteDecimals; } function getTwapPriceX128(uint32 twapDuration) public view returns (uint256 priceX128) { priceX128 = getPrice(twapDuration); priceX128 = priceX128.mulDiv( FixedPoint128.Q128 * 10**(vQuoteDecimals), 10**(vTokenDecimals + aggregator.decimals()) ); } function getPrice(uint256 twapDuration) internal view returns (uint256) { FlagsInterface _chainlinkFlags = chainlinkFlags; if (address(_chainlinkFlags) != address(0)) { bool isRaised = _chainlinkFlags.getFlag(FLAG_ARBITRUM_SEQ_OFFLINE); if (isRaised) { revert SequencerOffline(); } } (uint80 round, uint256 latestPrice, uint256 latestTS) = _getLatestRoundData(); uint256 endTS = block.timestamp; uint256 thresholdTS = endTS - twapDuration; //If twap duration = 0 or less data available just return latestPrice if (twapDuration == 0 || round == 0 || latestTS <= thresholdTS) { return latestPrice; } uint256 totalTime = endTS - latestTS; uint256 twap = latestPrice * totalTime; uint256 periodLength; uint256 startTS; uint256 periodPrice; endTS = latestTS; //Aggregate prices for all the eligible rounds before thresholdTS i.e. adds price*periodLength to twap //For the last eligible round goes till thresholdTS only while (true) { //If 0 round is reached before reaching thresholdTS then just consider the available data if (round == 0) { return totalTime == 0 ? latestPrice : twap / totalTime; } round = round - 1; (, periodPrice, startTS) = _getRoundData(round); if (periodPrice == 0) break; //If the starting time of a period is lesser than threshold timestamp (now-twapDuration) then period is thresholdTS -> endTS if (startTS <= thresholdTS) { periodLength = (endTS - thresholdTS); twap += periodPrice * periodLength; totalTime += periodLength; break; } // In normal case where thresholdTS < startTS. The whole period is considered i.e. startTS -> endTS periodLength = (endTS - startTS); twap += (periodPrice * periodLength); totalTime += periodLength; //endTS of previous period = startTS of current period endTS = startTS; } //Divide the accumulated value by the whole duration return twap == 0 ? latestPrice : twap / totalTime; } function _getLatestRoundData() private view returns ( uint80, uint256 finalPrice, uint256 ) { (uint80 round, int256 latestPrice, , uint256 latestTS, ) = aggregator.latestRoundData(); if (latestPrice < 0 && round <= 0) revert NotEnoughHistory(); if (latestPrice < 0) { (round, finalPrice, latestTS) = _getRoundData(round - 1); } else { finalPrice = uint256(latestPrice); } return (round, finalPrice, latestTS); } function _getRoundData(uint80 _round) private view returns ( uint80, uint256, uint256 ) { (uint80 round, int256 latestPrice, , uint256 latestTS, ) = _getRoundDataWithCheck(_round); while (latestPrice < 0 && round > 0) { round = round - 1; (, latestPrice, , latestTS, ) = aggregator.getRoundData(round); } if (latestPrice < 0 && round <= 0) revert NotEnoughHistory(); return (round, uint256(latestPrice), latestTS); } function _getRoundDataWithCheck(uint80 _round) private view returns ( uint80, int256, uint256, uint256, uint80 ) { try aggregator.getRoundData(_round) returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { return (roundId, answer, startedAt, updatedAt, answeredInRound); } catch { return (0, 0, 0, 0, 0); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (proxy/utils/Initializable.sol) pragma solidity ^0.8.0; import "../../utils/AddressUpgradeable.sol"; /** * @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed * behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an * external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer * function so it can only be called once. The {initializer} modifier provided by this contract will have this effect. * * TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as * possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. * * [CAUTION] * ==== * Avoid leaving a contract uninitialized. * * An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation * contract, which may impact the proxy. To initialize the implementation contract, you can either invoke the * initializer manually, or you can include a constructor to automatically mark it as initialized when it is deployed: * * [.hljs-theme-light.nopadding] * ``` * /// @custom:oz-upgrades-unsafe-allow constructor * constructor() initializer {} * ``` * ==== */ abstract contract Initializable { /** * @dev Indicates that the contract has been initialized. */ bool private _initialized; /** * @dev Indicates that the contract is in the process of being initialized. */ bool private _initializing; /** * @dev Modifier to protect an initializer function from being invoked twice. */ modifier initializer() { // If the contract is initializing we ignore whether _initialized is set in order to support multiple // inheritance patterns, but we only do this in the context of a constructor, because in other contexts the // contract may have been reentered. require(_initializing ? _isConstructor() : !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } /** * @dev Modifier to protect an initialization function so that it can only be invoked by functions with the * {initializer} modifier, directly or indirectly. */ modifier onlyInitializing() { require(_initializing, "Initializable: contract is not initializing"); _; } function _isConstructor() private view returns (bool) { return !AddressUpgradeable.isContract(address(this)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface AggregatorV3Interface { function decimals() external view returns (uint8); function description() external view returns (string memory); function version() external view returns (uint256); // getRoundData and latestRoundData should both raise "No data present" // if they do not have data to report, instead of returning unset values // which could be misinterpreted as actual reported values. function getRoundData(uint80 _roundId) external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestRoundData() external view returns ( uint80 roundId, int256 answer, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface FlagsInterface { function getFlag(address) external view returns (bool); function getFlags(address[] calldata) external view returns (bool[] memory); function raiseFlag(address) external; function raiseFlags(address[] calldata) external; function lowerFlags(address[] calldata) external; function setRaisingAccessController(address) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.4.0; /// @title FixedPoint96 /// @notice A library for handling binary fixed point numbers, see https://en.wikipedia.org/wiki/Q_(number_format) /// @dev Used in SqrtPriceMath.sol library FixedPoint96 { uint8 internal constant RESOLUTION = 96; uint256 internal constant Q96 = 0x1000000000000000000000000; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.4.0; /// @title FixedPoint128 /// @notice A library for handling binary fixed point numbers, see https://en.wikipedia.org/wiki/Q_(number_format) library FixedPoint128 { uint256 internal constant Q128 = 0x100000000000000000000000000000000; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /// @title Contains 512-bit math functions /// @notice Facilitates multiplication and division that can have overflow of an intermediate value without any loss of precision /// @dev Handles "phantom overflow" i.e., allows multiplication and division where an intermediate value overflows 256 bits library FullMath { /// @notice Calculates floor(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result /// @dev Credit to Remco Bloemen under MIT license https://xn--2-umb.com/21/muldiv function mulDiv( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = a * b // Compute the product mod 2**256 and mod 2**256 - 1 // then use the Chinese Remainder Theorem to reconstruct // the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2**256 + prod0 uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(a, b, not(0)) prod0 := mul(a, b) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division if (prod1 == 0) { require(denominator > 0); assembly { result := div(prod0, denominator) } return result; } // Make sure the result is less than 2**256. // Also prevents denominator == 0 require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0] // Compute remainder using mulmod uint256 remainder; assembly { remainder := mulmod(a, b, denominator) } // Subtract 256 bit number from 512 bit number assembly { prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator // Compute largest power of two divisor of denominator. // Always >= 1. uint256 twos = (0 - denominator) & denominator; // Divide denominator by power of two assembly { denominator := div(denominator, twos) } // Divide [prod1 prod0] by the factors of two assembly { prod0 := div(prod0, twos) } // Shift in bits from prod1 into prod0. For this we need // to flip `twos` such that it is 2**256 / twos. // If twos is zero, then it becomes one assembly { twos := add(div(sub(0, twos), twos), 1) } prod0 |= prod1 * twos; // Invert denominator mod 2**256 // Now that denominator is an odd number, it has an inverse // modulo 2**256 such that denominator * inv = 1 mod 2**256. // Compute the inverse by starting with a seed that is correct // correct for four bits. That is, denominator * inv = 1 mod 2**4 uint256 inv = (3 * denominator) ^ 2; // Now use Newton-Raphson iteration to improve the precision. // Thanks to Hensel's lifting lemma, this also works in modular // arithmetic, doubling the correct bits in each step. inv *= 2 - denominator * inv; // inverse mod 2**8 inv *= 2 - denominator * inv; // inverse mod 2**16 inv *= 2 - denominator * inv; // inverse mod 2**32 inv *= 2 - denominator * inv; // inverse mod 2**64 inv *= 2 - denominator * inv; // inverse mod 2**128 inv *= 2 - denominator * inv; // inverse mod 2**256 // Because the division is now exact we can divide by multiplying // with the modular inverse of denominator. This will give us the // correct result modulo 2**256. Since the precoditions guarantee // that the outcome is less than 2**256, this is the final result. // We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inv; return result; } } /// @notice Calculates ceil(a×b÷denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 /// @param a The multiplicand /// @param b The multiplier /// @param denominator The divisor /// @return result The 256-bit result function mulDivRoundingUp( uint256 a, uint256 b, uint256 denominator ) internal pure returns (uint256 result) { unchecked { result = mulDiv(a, b, denominator); if (mulmod(a, b, denominator) > 0) { require(result < type(uint256).max); result++; } } } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity >=0.5.0; /// @title Safe casting methods /// @notice Contains methods for safely casting between types library SafeCast { /// @notice Cast a uint256 to a uint160, revert on overflow /// @param y The uint256 to be downcasted /// @return z The downcasted integer, now type uint160 function toUint160(uint256 y) internal pure returns (uint160 z) { require((z = uint160(y)) == y); } /// @notice Cast a int256 to a int128, revert on overflow or underflow /// @param y The int256 to be downcasted /// @return z The downcasted integer, now type int128 function toInt128(int256 y) internal pure returns (int128 z) { require((z = int128(y)) == y); } /// @notice Cast a uint256 to a int256, revert on overflow /// @param y The uint256 to be casted /// @return z The casted integer, now type int256 function toInt256(uint256 y) internal pure returns (int256 z) { require(y < 2**255); z = int256(y); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; import { IVToken } from '../interfaces/IVToken.sol'; /// @title Address helper functions library AddressHelper { /// @notice converts address to uint32, using the least significant 32 bits /// @param addr Address to convert /// @return truncated last 4 bytes of the address function truncate(address addr) internal pure returns (uint32 truncated) { assembly { truncated := and(addr, 0xffffffff) } } /// @notice converts IERC20 contract to uint32 /// @param addr contract /// @return truncated last 4 bytes of the address function truncate(IERC20 addr) internal pure returns (uint32 truncated) { return truncate(address(addr)); } /// @notice checks if two addresses are equal /// @param a first address /// @param b second address /// @return true if addresses are equal function eq(address a, address b) internal pure returns (bool) { return a == b; } /// @notice checks if addresses of two IERC20 contracts are equal /// @param a first contract /// @param b second contract /// @return true if addresses are equal function eq(IERC20 a, IERC20 b) internal pure returns (bool) { return eq(address(a), address(b)); } /// @notice checks if an address is zero /// @param a address to check /// @return true if address is zero function isZero(address a) internal pure returns (bool) { return a == address(0); } /// @notice checks if address of an IERC20 contract is zero /// @param a contract to check /// @return true if address is zero function isZero(IERC20 a) internal pure returns (bool) { return isZero(address(a)); } }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.4; import { FullMath } from '@uniswap/v3-core-0.8-support/contracts/libraries/FullMath.sol'; import { FixedPoint96 } from '@uniswap/v3-core-0.8-support/contracts/libraries/FixedPoint96.sol'; import { TickMath } from '@uniswap/v3-core-0.8-support/contracts/libraries/TickMath.sol'; import { Bisection } from './Bisection.sol'; /// @title Price math functions library PriceMath { using FullMath for uint256; error IllegalSqrtPrice(uint160 sqrtPriceX96); /// @notice Computes the square of a sqrtPriceX96 value /// @param sqrtPriceX96: the square root of the input price in Q96 format /// @return priceX128 : input price in Q128 format function toPriceX128(uint160 sqrtPriceX96) internal pure returns (uint256 priceX128) { if (sqrtPriceX96 < TickMath.MIN_SQRT_RATIO || sqrtPriceX96 >= TickMath.MAX_SQRT_RATIO) { revert IllegalSqrtPrice(sqrtPriceX96); } priceX128 = _toPriceX128(sqrtPriceX96); } /// @notice computes the square of a sqrtPriceX96 value /// @param sqrtPriceX96: input price in Q128 format function _toPriceX128(uint160 sqrtPriceX96) private pure returns (uint256 priceX128) { priceX128 = uint256(sqrtPriceX96).mulDiv(sqrtPriceX96, 1 << 64); } /// @notice computes the square root of a priceX128 value /// @param priceX128: input price in Q128 format /// @return sqrtPriceX96 : the square root of the input price in Q96 format function toSqrtPriceX96(uint256 priceX128) internal pure returns (uint160 sqrtPriceX96) { // Uses bisection method to find solution to the equation toPriceX128(x) = priceX128 sqrtPriceX96 = Bisection.findSolution( _toPriceX128, priceX128, /// @dev sqrtPriceX96 is always bounded by MIN_SQRT_RATIO and MAX_SQRT_RATIO. /// If solution falls outside of these bounds, findSolution method reverts TickMath.MIN_SQRT_RATIO, TickMath.MAX_SQRT_RATIO - 1 ); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.5.0; interface IOracle { function getTwapPriceX128(uint32 twapDuration) external view returns (uint256 priceX128); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library AddressUpgradeable { /** * @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 * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://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"); (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"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // 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 assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `from` to `to` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 amount ) external returns (bool); /** * @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.8.0; import { IERC20 } from '@openzeppelin/contracts/token/ERC20/IERC20.sol'; interface IVToken is IERC20 { function mint(address account, uint256 amount) external; function burn(uint256 amount) external; function setVPoolWrapper(address) external; }
// SPDX-License-Identifier: GPL-2.0-or-later pragma solidity ^0.8.0; /// @title Math library for computing sqrt prices from ticks and vice versa /// @notice Computes sqrt price for ticks of size 1.0001, i.e. sqrt(1.0001^tick) as fixed point Q64.96 numbers. Supports /// prices between 2**-128 and 2**128 library TickMath { error T(); error R(); /// @dev The minimum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**-128 int24 internal constant MIN_TICK = -887272; /// @dev The maximum tick that may be passed to #getSqrtRatioAtTick computed from log base 1.0001 of 2**128 int24 internal constant MAX_TICK = -MIN_TICK; /// @dev The minimum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MIN_TICK) uint160 internal constant MIN_SQRT_RATIO = 4295128739; /// @dev The maximum value that can be returned from #getSqrtRatioAtTick. Equivalent to getSqrtRatioAtTick(MAX_TICK) uint160 internal constant MAX_SQRT_RATIO = 1461446703485210103287273052203988822378723970342; /// @notice Calculates sqrt(1.0001^tick) * 2^96 /// @dev Throws if |tick| > max tick /// @param tick The input tick for the above formula /// @return sqrtPriceX96 A Fixed point Q64.96 number representing the sqrt of the ratio of the two assets (token1/token0) /// at the given tick function getSqrtRatioAtTick(int24 tick) internal pure returns (uint160 sqrtPriceX96) { unchecked { uint256 absTick = tick < 0 ? uint256(-int256(tick)) : uint256(int256(tick)); if (absTick > uint256(int256(MAX_TICK))) revert T(); uint256 ratio = absTick & 0x1 != 0 ? 0xfffcb933bd6fad37aa2d162d1a594001 : 0x100000000000000000000000000000000; if (absTick & 0x2 != 0) ratio = (ratio * 0xfff97272373d413259a46990580e213a) >> 128; if (absTick & 0x4 != 0) ratio = (ratio * 0xfff2e50f5f656932ef12357cf3c7fdcc) >> 128; if (absTick & 0x8 != 0) ratio = (ratio * 0xffe5caca7e10e4e61c3624eaa0941cd0) >> 128; if (absTick & 0x10 != 0) ratio = (ratio * 0xffcb9843d60f6159c9db58835c926644) >> 128; if (absTick & 0x20 != 0) ratio = (ratio * 0xff973b41fa98c081472e6896dfb254c0) >> 128; if (absTick & 0x40 != 0) ratio = (ratio * 0xff2ea16466c96a3843ec78b326b52861) >> 128; if (absTick & 0x80 != 0) ratio = (ratio * 0xfe5dee046a99a2a811c461f1969c3053) >> 128; if (absTick & 0x100 != 0) ratio = (ratio * 0xfcbe86c7900a88aedcffc83b479aa3a4) >> 128; if (absTick & 0x200 != 0) ratio = (ratio * 0xf987a7253ac413176f2b074cf7815e54) >> 128; if (absTick & 0x400 != 0) ratio = (ratio * 0xf3392b0822b70005940c7a398e4b70f3) >> 128; if (absTick & 0x800 != 0) ratio = (ratio * 0xe7159475a2c29b7443b29c7fa6e889d9) >> 128; if (absTick & 0x1000 != 0) ratio = (ratio * 0xd097f3bdfd2022b8845ad8f792aa5825) >> 128; if (absTick & 0x2000 != 0) ratio = (ratio * 0xa9f746462d870fdf8a65dc1f90e061e5) >> 128; if (absTick & 0x4000 != 0) ratio = (ratio * 0x70d869a156d2a1b890bb3df62baf32f7) >> 128; if (absTick & 0x8000 != 0) ratio = (ratio * 0x31be135f97d08fd981231505542fcfa6) >> 128; if (absTick & 0x10000 != 0) ratio = (ratio * 0x9aa508b5b7a84e1c677de54f3e99bc9) >> 128; if (absTick & 0x20000 != 0) ratio = (ratio * 0x5d6af8dedb81196699c329225ee604) >> 128; if (absTick & 0x40000 != 0) ratio = (ratio * 0x2216e584f5fa1ea926041bedfe98) >> 128; if (absTick & 0x80000 != 0) ratio = (ratio * 0x48a170391f7dc42444e8fa2) >> 128; if (tick > 0) ratio = type(uint256).max / ratio; // this divides by 1<<32 rounding up to go from a Q128.128 to a Q128.96. // we then downcast because we know the result always fits within 160 bits due to our tick input constraint // we round up in the division so getTickAtSqrtRatio of the output price is always consistent sqrtPriceX96 = uint160((ratio >> 32) + (ratio % (1 << 32) == 0 ? 0 : 1)); } } /// @notice Calculates the greatest tick value such that getRatioAtTick(tick) <= ratio /// @dev Throws in case sqrtPriceX96 < MIN_SQRT_RATIO, as MIN_SQRT_RATIO is the lowest value getRatioAtTick may /// ever return. /// @param sqrtPriceX96 The sqrt ratio for which to compute the tick as a Q64.96 /// @return tick The greatest tick for which the ratio is less than or equal to the input ratio function getTickAtSqrtRatio(uint160 sqrtPriceX96) internal pure returns (int24 tick) { unchecked { // second inequality must be < because the price can never reach the price at the max tick if (!(sqrtPriceX96 >= MIN_SQRT_RATIO && sqrtPriceX96 < MAX_SQRT_RATIO)) revert R(); uint256 ratio = uint256(sqrtPriceX96) << 32; uint256 r = ratio; uint256 msb = 0; assembly { let f := shl(7, gt(r, 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(6, gt(r, 0xFFFFFFFFFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(5, gt(r, 0xFFFFFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(4, gt(r, 0xFFFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(3, gt(r, 0xFF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(2, gt(r, 0xF)) msb := or(msb, f) r := shr(f, r) } assembly { let f := shl(1, gt(r, 0x3)) msb := or(msb, f) r := shr(f, r) } assembly { let f := gt(r, 0x1) msb := or(msb, f) } if (msb >= 128) r = ratio >> (msb - 127); else r = ratio << (127 - msb); int256 log_2 = (int256(msb) - 128) << 64; assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(63, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(62, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(61, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(60, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(59, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(58, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(57, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(56, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(55, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(54, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(53, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(52, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(51, f)) r := shr(f, r) } assembly { r := shr(127, mul(r, r)) let f := shr(128, r) log_2 := or(log_2, shl(50, f)) } int256 log_sqrt10001 = log_2 * 255738958999603826347141; // 128.128 number int24 tickLow = int24((log_sqrt10001 - 3402992956809132418596140100660247210) >> 128); int24 tickHi = int24((log_sqrt10001 + 291339464771989622907027621153398088495) >> 128); tick = tickLow == tickHi ? tickLow : getSqrtRatioAtTick(tickHi) <= sqrtPriceX96 ? tickHi : tickLow; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /// @title Bisection Method /// @notice https://en.wikipedia.org/wiki/Bisection_method library Bisection { error SolutionOutOfBounds(uint256 y_target, uint160 x_lower, uint160 x_upper); /// @notice Finds the solution to the equation f(x) = y_target using the bisection method /// @param f: strictly increasing function f: uint160 -> uint256 /// @param y_target: the target value of f(x) /// @param x_lower: the lower bound for x /// @param x_upper: the upper bound for x /// @return x_target: the rounded down solution to the equation f(x) = y_target function findSolution( function(uint160) pure returns (uint256) f, uint256 y_target, uint160 x_lower, uint160 x_upper ) internal pure returns (uint160) { // compute y at the bounds uint256 y_lower = f(x_lower); uint256 y_upper = f(x_upper); // if y is out of the bounds then revert if (y_target < y_lower || y_target > y_upper) revert SolutionOutOfBounds(y_target, x_lower, x_upper); // bisect repeatedly until the solution is within an error of 1 unit uint256 y_mid; uint160 x_mid; while (x_upper - x_lower > 1) { x_mid = x_lower + (x_upper - x_lower) / 2; y_mid = f(x_mid); if (y_mid > y_target) { x_upper = x_mid; y_upper = y_mid; } else { x_lower = x_mid; y_lower = y_mid; } } // at this point, x_upper - x_lower is either 0 or 1 // if it is 1 then check if x_upper is the solution, else return x_lower as the rounded down solution return x_lower != x_upper && f(x_upper) == y_target ? x_upper : x_lower; } }
{ "viaIR": true, "optimizer": { "enabled": true, "runs": 4999 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"_aggregator","type":"address"},{"internalType":"address","name":"_flags","type":"address"},{"internalType":"uint8","name":"_vTokenDecimals","type":"uint8"},{"internalType":"uint8","name":"_vQuoteDecimals","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"aggregator","type":"address"}],"name":"IllegalAggregatorAddress","type":"error"},{"inputs":[],"name":"NotEnoughHistory","type":"error"},{"inputs":[],"name":"SequencerOffline","type":"error"},{"inputs":[],"name":"aggregator","outputs":[{"internalType":"contract AggregatorV3Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chainlinkFlags","outputs":[{"internalType":"contract FlagsInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint32","name":"twapDuration","type":"uint32"}],"name":"getTwapPriceX128","outputs":[{"internalType":"uint256","name":"priceX128","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
60c03461009657601f610b6d38819003918201601f19168301916001600160401b0383118484101761009b57808492608094604052833981010312610096578061004b610076926100b1565b90610058602082016100b1565b6100706060610069604085016100c5565b93016100c5565b926100d3565b604051610a4a9081610123823960805181610143015260a0518160880152f35b600080fd5b634e487b7160e01b600052604160045260246000fd5b51906001600160a01b038216820361009657565b519060ff8216820361009657565b6001600160a01b039081169182156101095760018060a01b0319928360005416176000551690600154161760015560805260a052565b60405163091b998160e11b815260006004820152602490fdfe608080604052600436101561001357600080fd5b6000803560e01c918263245a7bfc146101d957508163dd86c1011461004b575063e4440e0214610043575b600080fd5b61003e610207565b346101d65760206003193601126101d65760043563ffffffff81168091036101d2576101869161007d61017692610486565b61016c6101676100ac7f000000000000000000000000000000000000000000000000000000000000000061026c565b936fffffffffffffffffffffffffffffffff85116001166101c5575b600460206101066100ed845473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1690565b604051928380927f313ce5670000000000000000000000000000000000000000000000000000000082525afa9182156101b8575b9161018a575b507f0000000000000000000000000000000000000000000000000000000000000000610340565b61026c565b9160801b90610369565b6040519081529081906020820190565b0390f35b6101ab915060203d81116101b1575b6101a381836102aa565b81019061031a565b87610140565b503d610199565b6101c0610333565b61013a565b6101cd61023c565b6100c8565b5080fd5b80fd5b346101d257816003193601126101d25773ffffffffffffffffffffffffffffffffffffffff60209254168152f35b503461003e57600060031936011261003e57602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff16604d811161027e575b600a0a90565b61028661023c565b610278565b806000190482118115151661029e570290565b6102a661023c565b0290565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176102eb57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b9081602091031261003e575160ff8116810361003e5790565b506040513d6000823e3d90fd5b60ff8091169116908160ff038111610356570190565b61035e61023c565b0190565b1561003e57565b909160001983830992808302928380861095039480860395146103e357908291610394868411610362565b0981806000031680920460028082600302188083028203028083028203028083028203028083028203028083028203028092029003029360018380600003040190848311900302920304170290565b505091506103f2821515610362565b0490565b818110610401570390565b61040961023c565b0390565b9081602091031261003e5751801515810361003e5790565b811561042f570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b69ffffffffffffffffffff600019911660018110610356570190565b81198111610356570190565b6001906104aa6100ed835473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff811661060c575b506104cf61072a565b919290938342906104e084836103f6565b93159081156105f7575b5080156105ed575b6105e5576105048483929695966103f6565b9361050f858861028b565b95915b610537575b5050505090801560001461052a57505090565b6105349250610425565b90565b69ffffffffffffffffffff8116156105d2576105529061045e565b9061055c82610841565b9791509182156105ca578588111561059f57610596929161058a6105838a610590946103f6565b809461028b565b9061047a565b9561047a565b93949082610512565b6105c19697506105bb94506105839193509461058a92956103f6565b9261047a565b38808080610517565b509550610517565b5050505090811560001461052a57505090565b505050505090565b50828411156104f2565b69ffffffffffffffffffff91501615386104ea565b602060405180927f357e47fe000000000000000000000000000000000000000000000000000000008252818061065d600482019073a438451d6458044c3c8cd2f6f31c91ac882a6d91602083019252565b03915afa9081156106d4575b6000916106a6575b5061067c57386104c6565b60046040517fdb502a67000000000000000000000000000000000000000000000000000000008152fd5b6106c7915060203d81116106cd575b6106bf81836102aa565b81019061040d565b38610671565b503d6106b5565b6106dc610333565b610669565b519069ffffffffffffffffffff8216820361003e57565b908160a091031261003e5761070c816106e1565b916020820151916040810151916105346080606084015193016106e1565b600460a073ffffffffffffffffffffffffffffffffffffffff60005416604051928380927ffeaf968c0000000000000000000000000000000000000000000000000000000082525afa8015610834575b600091829083926107ff575b508291906000811280806107eb575b6107c157156107b9575050506107ad6107b29161045e565b610841565b9290919290565b919391925090565b60046040517f9ee522a9000000000000000000000000000000000000000000000000000000008152fd5b5069ffffffffffffffffffff851615610795565b915050610823915060a03d811161082d575b61081b81836102aa565b8101906106f8565b5091905038610786565b503d610811565b61083c610333565b61077a565b61084a9061095d565b509290509091906000926108756100ed855473ffffffffffffffffffffffffffffffffffffffff1690565b925b84821280610948575b1561091e5750506108909061045e565b6040517f9a6fc8f500000000000000000000000000000000000000000000000000000000815269ffffffffffffffffffff8216600482015260a0908181602481875afa908115610911575b859286926108eb575b5050610877565b610905935080919250903d1061082d5761081b81836102aa565b509250509038806108e4565b610919610333565b6108db565b9390949250841280610934575b6107c157929190565b5069ffffffffffffffffffff81161561092b565b5069ffffffffffffffffffff83161515610880565b60009060a069ffffffffffffffffffff602473ffffffffffffffffffffffffffffffffffffffff8554169360405194859384927f9a6fc8f50000000000000000000000000000000000000000000000000000000084521660048301525afa82918291829182918291816109e9575b506109de57505050505080918180918190565b959394509192909190565b935094505050610a07915060a03d811161082d5761081b81836102aa565b92949193909291386109cb56fea2646970667358221220038174ac85da7be6c8f8293f2ff71b601f8f49303ed5bd9751239916b3a0976d64736f6c634300080e0033000000000000000000000000639fe6ab55c921f74e7fac1ee960c0b6293ba6120000000000000000000000003c14e07edd0dc67442fa96f1ec6999c57e810a8300000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000006
Deployed Bytecode
0x608080604052600436101561001357600080fd5b6000803560e01c918263245a7bfc146101d957508163dd86c1011461004b575063e4440e0214610043575b600080fd5b61003e610207565b346101d65760206003193601126101d65760043563ffffffff81168091036101d2576101869161007d61017692610486565b61016c6101676100ac7f000000000000000000000000000000000000000000000000000000000000000661026c565b936fffffffffffffffffffffffffffffffff85116001166101c5575b600460206101066100ed845473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff1690565b604051928380927f313ce5670000000000000000000000000000000000000000000000000000000082525afa9182156101b8575b9161018a575b507f0000000000000000000000000000000000000000000000000000000000000012610340565b61026c565b9160801b90610369565b6040519081529081906020820190565b0390f35b6101ab915060203d81116101b1575b6101a381836102aa565b81019061031a565b87610140565b503d610199565b6101c0610333565b61013a565b6101cd61023c565b6100c8565b5080fd5b80fd5b346101d257816003193601126101d25773ffffffffffffffffffffffffffffffffffffffff60209254168152f35b503461003e57600060031936011261003e57602073ffffffffffffffffffffffffffffffffffffffff60015416604051908152f35b507f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60ff16604d811161027e575b600a0a90565b61028661023c565b610278565b806000190482118115151661029e570290565b6102a661023c565b0290565b90601f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0910116810190811067ffffffffffffffff8211176102eb57604052565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b9081602091031261003e575160ff8116810361003e5790565b506040513d6000823e3d90fd5b60ff8091169116908160ff038111610356570190565b61035e61023c565b0190565b1561003e57565b909160001983830992808302928380861095039480860395146103e357908291610394868411610362565b0981806000031680920460028082600302188083028203028083028203028083028203028083028203028083028203028092029003029360018380600003040190848311900302920304170290565b505091506103f2821515610362565b0490565b818110610401570390565b61040961023c565b0390565b9081602091031261003e5751801515810361003e5790565b811561042f570490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b69ffffffffffffffffffff600019911660018110610356570190565b81198111610356570190565b6001906104aa6100ed835473ffffffffffffffffffffffffffffffffffffffff1690565b73ffffffffffffffffffffffffffffffffffffffff811661060c575b506104cf61072a565b919290938342906104e084836103f6565b93159081156105f7575b5080156105ed575b6105e5576105048483929695966103f6565b9361050f858861028b565b95915b610537575b5050505090801560001461052a57505090565b6105349250610425565b90565b69ffffffffffffffffffff8116156105d2576105529061045e565b9061055c82610841565b9791509182156105ca578588111561059f57610596929161058a6105838a610590946103f6565b809461028b565b9061047a565b9561047a565b93949082610512565b6105c19697506105bb94506105839193509461058a92956103f6565b9261047a565b38808080610517565b509550610517565b5050505090811560001461052a57505090565b505050505090565b50828411156104f2565b69ffffffffffffffffffff91501615386104ea565b602060405180927f357e47fe000000000000000000000000000000000000000000000000000000008252818061065d600482019073a438451d6458044c3c8cd2f6f31c91ac882a6d91602083019252565b03915afa9081156106d4575b6000916106a6575b5061067c57386104c6565b60046040517fdb502a67000000000000000000000000000000000000000000000000000000008152fd5b6106c7915060203d81116106cd575b6106bf81836102aa565b81019061040d565b38610671565b503d6106b5565b6106dc610333565b610669565b519069ffffffffffffffffffff8216820361003e57565b908160a091031261003e5761070c816106e1565b916020820151916040810151916105346080606084015193016106e1565b600460a073ffffffffffffffffffffffffffffffffffffffff60005416604051928380927ffeaf968c0000000000000000000000000000000000000000000000000000000082525afa8015610834575b600091829083926107ff575b508291906000811280806107eb575b6107c157156107b9575050506107ad6107b29161045e565b610841565b9290919290565b919391925090565b60046040517f9ee522a9000000000000000000000000000000000000000000000000000000008152fd5b5069ffffffffffffffffffff851615610795565b915050610823915060a03d811161082d575b61081b81836102aa565b8101906106f8565b5091905038610786565b503d610811565b61083c610333565b61077a565b61084a9061095d565b509290509091906000926108756100ed855473ffffffffffffffffffffffffffffffffffffffff1690565b925b84821280610948575b1561091e5750506108909061045e565b6040517f9a6fc8f500000000000000000000000000000000000000000000000000000000815269ffffffffffffffffffff8216600482015260a0908181602481875afa908115610911575b859286926108eb575b5050610877565b610905935080919250903d1061082d5761081b81836102aa565b509250509038806108e4565b610919610333565b6108db565b9390949250841280610934575b6107c157929190565b5069ffffffffffffffffffff81161561092b565b5069ffffffffffffffffffff83161515610880565b60009060a069ffffffffffffffffffff602473ffffffffffffffffffffffffffffffffffffffff8554169360405194859384927f9a6fc8f50000000000000000000000000000000000000000000000000000000084521660048301525afa82918291829182918291816109e9575b506109de57505050505080918180918190565b959394509192909190565b935094505050610a07915060a03d811161082d5761081b81836102aa565b92949193909291386109cb56fea2646970667358221220038174ac85da7be6c8f8293f2ff71b601f8f49303ed5bd9751239916b3a0976d64736f6c634300080e0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000639fe6ab55c921f74e7fac1ee960c0b6293ba6120000000000000000000000003c14e07edd0dc67442fa96f1ec6999c57e810a8300000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000006
-----Decoded View---------------
Arg [0] : _aggregator (address): 0x639Fe6ab55C921f74e7fac1ee960C0B6293ba612
Arg [1] : _flags (address): 0x3C14e07Edd0dC67442FA96f1Ec6999c57E810a83
Arg [2] : _vTokenDecimals (uint8): 18
Arg [3] : _vQuoteDecimals (uint8): 6
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000639fe6ab55c921f74e7fac1ee960c0b6293ba612
Arg [1] : 0000000000000000000000003c14e07edd0dc67442fa96f1ec6999c57e810a83
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000006
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.