Address Contract Partially Verified
Address
0xE118d797E1c44F2e2A2823191a51D8b46a4A1D51
Balance
0 ETH
Nonce
1
Code Size
2977 bytes
Creator
0x33ab07dF...119A at tx 0xb36acd88...d8e5cd
Indexed Transactions
0
Contract Bytecode
2977 bytes
0x608060405234801561001057600080fd5b50600436106100675760003560e01c8063c1e553e711610050578063c1e553e7146100c9578063c45a01551461010c578063c640752d1461013d57610067565b80638c86f1e41461006c578063b4d1d795146100c1575b600080fd5b6100af6004803603606081101561008257600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020810135916040909101351661017a565b60408051918252519081900360200190f35b6100af6102da565b6100af600480360360608110156100df57600080fd5b5073ffffffffffffffffffffffffffffffffffffffff8135811691602081013591604090910135166102e1565b610114610300565b6040805173ffffffffffffffffffffffffffffffffffffffff9092168252519081900360200190f35b6101786004803603604081101561015357600080fd5b5073ffffffffffffffffffffffffffffffffffffffff81358116916020013516610324565b005b6000806101a87f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f86856104c5565b73ffffffffffffffffffffffffffffffffffffffff811660009081526020819052604081209192506101da87866105b0565b5090508073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff16141561027557604080516020810190915260038301547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815261025a90610255908863ffffffff61070316565b6107c6565b71ffffffffffffffffffffffffffffffffffff1693506102d0565b604080516020810190915260048301547bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1681526102b990610255908863ffffffff61070316565b71ffffffffffffffffffffffffffffffffffff1693505b5050509392505050565b6201518081565b60006102ed8483610324565b6102f884848461017a565b949350505050565b7f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f81565b60006103517f0000000000000000000000005c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f84846104c5565b73ffffffffffffffffffffffffffffffffffffffff811660009081526020819052604081209192508080610384856107cd565b925092509250600084600001548263ffffffff16039050620151808163ffffffff16106104bb576001850154156104a35760405180602001604052808263ffffffff1687600101548703816103d557fe5b047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90811690915290516003870180547fffffffff00000000000000000000000000000000000000000000000000000000169190921617905560408051602081019091526002860154819063ffffffff84169086038161044d57fe5b047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff90811690915290516004870180547fffffffff0000000000000000000000000000000000000000000000000000000016919092161790555b600185018490556002850183905563ffffffff821685555b5050505050505050565b60008060006104d485856105b0565b604080517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606094851b811660208084019190915293851b81166034830152825160288184030181526048830184528051908501207fff0000000000000000000000000000000000000000000000000000000000000060688401529a90941b9093166069840152607d8301989098527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f609d808401919091528851808403909101815260bd909201909752805196019590952095945050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415610638576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526025815260200180610b476025913960400191505060405180910390fd5b8273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1610610672578284610675565b83835b909250905073ffffffffffffffffffffffffffffffffffffffff82166106fc57604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f556e697377617056324c6962726172793a205a45524f5f414444524553530000604482015290519081900360640190fd5b9250929050565b61070b610b21565b600082158061074657505082517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff168281029083828161074357fe5b04145b6107b157604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f4669786564506f696e743a204d554c5f4f564552464c4f570000000000000000604482015290519081900360640190fd5b60408051602081019091529081529392505050565b5160701c90565b60008060006107da610a1f565b90508373ffffffffffffffffffffffffffffffffffffffff16635909c0d56040518163ffffffff1660e01b815260040160206040518083038186803b15801561082257600080fd5b505afa158015610836573d6000803e3d6000fd5b505050506040513d602081101561084c57600080fd5b5051604080517f5a3d5493000000000000000000000000000000000000000000000000000000008152905191945073ffffffffffffffffffffffffffffffffffffffff861691635a3d549391600480820192602092909190829003018186803b1580156108b857600080fd5b505afa1580156108cc573d6000803e3d6000fd5b505050506040513d60208110156108e257600080fd5b5051604080517f0902f1ac00000000000000000000000000000000000000000000000000000000815290519193506000918291829173ffffffffffffffffffffffffffffffffffffffff891691630902f1ac916004808301926060929190829003018186803b15801561095457600080fd5b505afa158015610968573d6000803e3d6000fd5b505050506040513d606081101561097e57600080fd5b5080516020820151604090920151909450909250905063ffffffff80821690851614610a155780840363ffffffff81166109b88486610a29565b517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1602969096019563ffffffff81166109ee8585610a29565b517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16029590950194505b5050509193909250565b63ffffffff421690565b610a31610b34565b6000826dffffffffffffffffffffffffffff1611610ab057604080517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4669786564506f696e743a204449565f42595f5a45524f5f4652414354494f4e604482015290519081900360640190fd5b6040805160208101909152806dffffffffffffffffffffffffffff84167bffffffffffffffffffffffffffff0000000000000000000000000000607087901b1681610af757fe5b047bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16815250905092915050565b6040518060200160405280600081525090565b6040805160208101909152600081529056fe556e697377617056324c6962726172793a204944454e544943414c5f414444524553534553a2646970667358221220bf615cb5b81054f8f76989b6ac4dc0121847523fb606e05a6d45bb3d70dab02864736f6c634300060a0033
Verified Source Code Partial Match
Compiler: v0.6.10+commit.00c0fcaf
EVM: istanbul
Optimization: Yes (2000000 runs)
UniswapOracle.sol 731 lines
// File: @uniswap\v2-core\contracts\interfaces\IUniswapV2Factory.sol
pragma solidity >=0.5.0;
interface IUniswapV2Factory {
event PairCreated(address indexed token0, address indexed token1, address pair, uint);
function feeTo() external view returns (address);
function feeToSetter() external view returns (address);
function getPair(address tokenA, address tokenB) external view returns (address pair);
function allPairs(uint) external view returns (address pair);
function allPairsLength() external view returns (uint);
function createPair(address tokenA, address tokenB) external returns (address pair);
function setFeeTo(address) external;
function setFeeToSetter(address) external;
}
// File: @uniswap\v2-core\contracts\interfaces\IUniswapV2Pair.sol
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;
}
// File: node_modules\@uniswap\lib\contracts\libraries\FullMath.sol
pragma solidity >=0.4.0;
// taken from https://medium.com/coinmonks/math-in-solidity-part-3-percents-and-proportions-4db014e080b1
// license is CC-BY-4.0
library FullMath {
function fullMul(uint256 x, uint256 y) private pure returns (uint256 l, uint256 h) {
uint256 mm = mulmod(x, y, uint256(-1));
l = x * y;
h = mm - l;
if (mm < l) h -= 1;
}
function fullDiv(
uint256 l,
uint256 h,
uint256 d
) private pure returns (uint256) {
uint256 pow2 = d & -d;
d /= pow2;
l /= pow2;
l += h * ((-pow2) / pow2 + 1);
uint256 r = 1;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
r *= 2 - d * r;
return l * r;
}
function mulDiv(
uint256 x,
uint256 y,
uint256 d
) internal pure returns (uint256) {
(uint256 l, uint256 h) = fullMul(x, y);
uint256 mm = mulmod(x, y, d);
if (mm > l) h -= 1;
l -= mm;
require(h < d, 'FullMath: FULLDIV_OVERFLOW');
return fullDiv(l, h, d);
}
}
// File: node_modules\@uniswap\lib\contracts\libraries\Babylonian.sol
pragma solidity >=0.4.0;
// computes square roots using the babylonian method
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
library Babylonian {
function sqrt(uint256 y) internal pure returns (uint256 z) {
if (y > 3) {
z = y;
uint256 x = y / 2 + 1;
while (x < z) {
z = x;
x = (y / x + x) / 2;
}
} else if (y != 0) {
z = 1;
}
// else z = 0
}
}
// File: node_modules\@uniswap\lib\contracts\libraries\BitMath.sol
pragma solidity >=0.5.0;
library BitMath {
function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {
require(x > 0, 'BitMath: ZERO');
if (x >= 0x100000000000000000000000000000000) {
x >>= 128;
r += 128;
}
if (x >= 0x10000000000000000) {
x >>= 64;
r += 64;
}
if (x >= 0x100000000) {
x >>= 32;
r += 32;
}
if (x >= 0x10000) {
x >>= 16;
r += 16;
}
if (x >= 0x100) {
x >>= 8;
r += 8;
}
if (x >= 0x10) {
x >>= 4;
r += 4;
}
if (x >= 0x4) {
x >>= 2;
r += 2;
}
if (x >= 0x2) r += 1;
}
}
// File: @uniswap\lib\contracts\libraries\FixedPoint.sol
pragma solidity >=0.4.0;
// 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 {
uint256 _x;
}
uint8 private constant RESOLUTION = 112;
uint256 private constant Q112 = 0x10000000000000000000000000000;
uint256 private constant Q224 = 0x100000000000000000000000000000000000000000000000000000000;
uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)
// 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);
}
// 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);
}
// multiply a UQ112x112 by a uint, returning a UQ144x112
// reverts on overflow
function mul(uq112x112 memory self, uint256 y) internal pure returns (uq144x112 memory) {
uint256 z = 0;
require(y == 0 || (z = self._x * y) / y == self._x, 'FixedPoint: MUL_OVERFLOW');
return uq144x112(z);
}
// multiply a UQ112x112 by an int and decode, returning an int
// reverts on overflow
function muli(uq112x112 memory self, int256 y) internal pure returns (int256) {
uint256 z = FullMath.mulDiv(self._x, uint256(y < 0 ? -y : y), Q112);
require(z < 2**255, 'FixedPoint: MULI_OVERFLOW');
return y < 0 ? -int256(z) : int256(z);
}
// multiply a UQ112x112 by a UQ112x112, returning a UQ112x112
// lossy
function muluq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) {
if (self._x == 0 || other._x == 0) {
return uq112x112(0);
}
uint112 upper_self = uint112(self._x >> RESOLUTION); // * 2^0
uint112 lower_self = uint112(self._x & LOWER_MASK); // * 2^-112
uint112 upper_other = uint112(other._x >> RESOLUTION); // * 2^0
uint112 lower_other = uint112(other._x & LOWER_MASK); // * 2^-112
// partial products
uint224 upper = uint224(upper_self) * upper_other; // * 2^0
uint224 lower = uint224(lower_self) * lower_other; // * 2^-224
uint224 uppers_lowero = uint224(upper_self) * lower_other; // * 2^-112
uint224 uppero_lowers = uint224(upper_other) * lower_self; // * 2^-112
// so the bit shift does not overflow
require(upper <= uint112(-1), 'FixedPoint: MULUQ_OVERFLOW_UPPER');
// this cannot exceed 256 bits, all values are 224 bits
uint256 sum = uint256(upper << RESOLUTION) + uppers_lowero + uppero_lowers + (lower >> RESOLUTION);
// so the cast does not overflow
require(sum <= uint224(-1), 'FixedPoint: MULUQ_OVERFLOW_SUM');
return uq112x112(uint224(sum));
}
// divide a UQ112x112 by a UQ112x112, returning a UQ112x112
function divuq(uq112x112 memory self, uq112x112 memory other) internal pure returns (uq112x112 memory) {
require(other._x > 0, 'FixedPoint: DIV_BY_ZERO_DIVUQ');
if (self._x == other._x) {
return uq112x112(uint224(Q112));
}
if (self._x <= uint144(-1)) {
uint256 value = (uint256(self._x) << RESOLUTION) / other._x;
require(value <= uint224(-1), 'FixedPoint: DIVUQ_OVERFLOW');
return uq112x112(uint224(value));
}
uint256 result = FullMath.mulDiv(Q112, self._x, other._x);
require(result <= uint224(-1), 'FixedPoint: DIVUQ_OVERFLOW');
return uq112x112(uint224(result));
}
// returns a UQ112x112 which represents the ratio of the numerator to the denominator
// lossy
function fraction(uint112 numerator, uint112 denominator) internal pure returns (uq112x112 memory) {
require(denominator > 0, 'FixedPoint: DIV_BY_ZERO_FRACTION');
return uq112x112((uint224(numerator) << RESOLUTION) / denominator);
}
// take the reciprocal of a UQ112x112
// reverts on overflow
// lossy
function reciprocal(uq112x112 memory self) internal pure returns (uq112x112 memory) {
require(self._x > 1, 'FixedPoint: DIV_BY_ZERO_RECIPROCAL_OR_OVERFLOW');
return uq112x112(uint224(Q224 / self._x));
}
// square root of a UQ112x112
// lossy between 0/1 and 40 bits
function sqrt(uq112x112 memory self) internal pure returns (uq112x112 memory) {
if (self._x <= uint144(-1)) {
return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << 112)));
}
uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x);
safeShiftBits -= safeShiftBits % 2;
return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << safeShiftBits) << ((112 - safeShiftBits) / 2)));
}
}
// File: @openzeppelin\contracts\math\SafeMath.sol
pragma solidity >=0.6.0 <0.8.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;
}
}
// File: @uniswap\v2-periphery\contracts\libraries\UniswapV2OracleLibrary.sol
pragma solidity >=0.5.0;
// 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 price using counterfactuals to save gas and avoid a call to sync.
function currentCumulativePrices(
address pair
) internal view returns (uint price0Cumulative, uint 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();
if (blockTimestampLast != blockTimestamp) {
// subtraction overflow is desired
uint32 timeElapsed = blockTimestamp - blockTimestampLast;
// addition overflow is desired
// counterfactual
price0Cumulative += uint(FixedPoint.fraction(reserve1, reserve0)._x) * timeElapsed;
// counterfactual
price1Cumulative += uint(FixedPoint.fraction(reserve0, reserve1)._x) * timeElapsed;
}
}
}
// File: contracts\protocols\Uniswap\UniswapV2Library.sol
// Original source: https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/libraries/UniswapV2Library.sol
// Modified to unpin solidity version
pragma solidity >=0.5.0;
library UniswapV2Library {
using SafeMath for uint;
// 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');
}
// 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 = address(uint(keccak256(abi.encodePacked(
hex'ff',
factory,
keccak256(abi.encodePacked(token0, token1)),
hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f' // init code hash
))));
}
// fetches and sorts the reserves for a pair
function getReserves(address factory, address tokenA, address tokenB) internal view returns (uint reserveA, uint reserveB) {
(address token0,) = sortTokens(tokenA, tokenB);
(uint reserve0, uint reserve1,) = IUniswapV2Pair(pairFor(factory, tokenA, tokenB)).getReserves();
(reserveA, reserveB) = tokenA == token0 ? (reserve0, reserve1) : (reserve1, reserve0);
}
// given some amount of an asset and pair reserves, returns an equivalent amount of the other asset
function quote(uint amountA, uint reserveA, uint reserveB) internal pure returns (uint amountB) {
require(amountA > 0, 'UniswapV2Library: INSUFFICIENT_AMOUNT');
require(reserveA > 0 && reserveB > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
amountB = amountA.mul(reserveB) / reserveA;
}
// given an input amount of an asset and pair reserves, returns the maximum output amount of the other asset
function getAmountOut(uint amountIn, uint reserveIn, uint reserveOut) internal pure returns (uint amountOut) {
require(amountIn > 0, 'UniswapV2Library: INSUFFICIENT_INPUT_AMOUNT');
require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
uint amountInWithFee = amountIn.mul(997);
uint numerator = amountInWithFee.mul(reserveOut);
uint denominator = reserveIn.mul(1000).add(amountInWithFee);
amountOut = numerator / denominator;
}
// given an output amount of an asset and pair reserves, returns a required input amount of the other asset
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) {
require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT');
require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
uint numerator = reserveIn.mul(amountOut).mul(1000);
uint denominator = reserveOut.sub(amountOut).mul(997);
amountIn = (numerator / denominator).add(1);
}
// performs chained getAmountOut calculations on any number of pairs
function getAmountsOut(address factory, uint amountIn, address[] memory path) internal view returns (uint[] memory amounts) {
require(path.length >= 2, 'UniswapV2Library: INVALID_PATH');
amounts = new uint[](path.length);
amounts[0] = amountIn;
for (uint i; i < path.length - 1; i++) {
(uint reserveIn, uint reserveOut) = getReserves(factory, path[i], path[i + 1]);
amounts[i + 1] = getAmountOut(amounts[i], reserveIn, reserveOut);
}
}
// performs chained getAmountIn calculations on any number of pairs
function getAmountsIn(address factory, uint amountOut, address[] memory path) internal view returns (uint[] memory amounts) {
require(path.length >= 2, 'UniswapV2Library: INVALID_PATH');
amounts = new uint[](path.length);
amounts[amounts.length - 1] = amountOut;
for (uint i = path.length - 1; i > 0; i--) {
(uint reserveIn, uint reserveOut) = getReserves(factory, path[i - 1], path[i]);
amounts[i - 1] = getAmountIn(amounts[i], reserveIn, reserveOut);
}
}
}
// File: contracts\protocols\Uniswap\IUniswapOracle.sol
pragma solidity >=0.5.0;
interface IUniswapOracle
{
function PERIOD() external returns (uint);
function factory() external returns (address);
function update(
address _tokenIn,
address _tokenOut
) external;
function consult(
address _tokenIn,
uint _amountIn,
address _tokenOut
) external view
returns (uint _amountOut);
function updateAndConsult(
address _tokenIn,
uint _amountIn,
address _tokenOut
) external
returns (uint _amountOut);
}
// File: contracts\protocols\Uniswap\UniswapOracle.sol
// Original source: https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples
// Modified to unpin solidity version and to support multiple pairs
pragma solidity ^0.6.6;
contract UniswapOracle is IUniswapOracle
{
using FixedPoint for *;
struct Observation
{
uint timestamp;
uint price0Cumulative;
uint price1Cumulative;
FixedPoint.uq112x112 price0Average;
FixedPoint.uq112x112 price1Average;
}
uint public override constant PERIOD = 24 hours;
address public override immutable factory;
// mapping from pair address to a list of price observations of that pair
mapping(address => Observation) private pairObservations;
constructor(
address _factory
) public
{
factory = _factory;
}
/**
* @notice Updates and stores the exchange rate
* @dev For the first 24 hours the rate will be 0.
*/
function update(
address _tokenIn,
address _tokenOut
) public override
{
address pair = UniswapV2Library.pairFor(factory, _tokenIn, _tokenOut);
Observation storage observation = pairObservations[pair];
(uint price0Cumulative, uint price1Cumulative, uint32 blockTimestamp) =
UniswapV2OracleLibrary.currentCumulativePrices(address(pair));
uint32 timeElapsed = uint32(blockTimestamp - observation.timestamp); // overflow is desired
// ensure that at least one full period has passed since the last update
if(timeElapsed >= PERIOD)
{
if(observation.price0Cumulative > 0)
{
// overflow is desired, casting never truncates
// cumulative price is in (uq112x112 price * seconds) units so we simply wrap it after division by time elapsed
observation.price0Average = FixedPoint.uq112x112(uint224((price0Cumulative - observation.price0Cumulative) / timeElapsed));
observation.price1Average = FixedPoint.uq112x112(uint224((price1Cumulative - observation.price1Cumulative) / timeElapsed));
}
observation.price0Cumulative = price0Cumulative;
observation.price1Cumulative = price1Cumulative;
observation.timestamp = blockTimestamp;
}
}
/**
* @notice Returns the rate after `update` has been called.
*/
function consult(
address _tokenIn,
uint _amountIn,
address _tokenOut
) public override view
returns (uint _amountOut)
{
address pair = UniswapV2Library.pairFor(factory, _tokenIn, _tokenOut);
Observation storage observation = pairObservations[pair];
(address token0,) = UniswapV2Library.sortTokens(_tokenIn, _tokenOut);
if (_tokenIn == token0)
{
_amountOut = observation.price0Average.mul(_amountIn).decode144();
}
else
{
_amountOut = observation.price1Average.mul(_amountIn).decode144();
}
}
/**
* @notice Calls `update` and returns the rate in a single call
*/
function updateAndConsult(
address _tokenIn,
uint _amountIn,
address _tokenOut
) public override
returns (uint _amountOut)
{
update(_tokenIn, _tokenOut);
return consult(_tokenIn, _amountIn, _tokenOut);
}
}
Read Contract
PERIOD 0xb4d1d795 → uint256
consult 0x8c86f1e4 → uint256
factory 0xc45a0155 → address
Write Contract 2 functions
These functions modify contract state and require a wallet transaction to execute.
update 0xc640752d
address _tokenIn
address _tokenOut
updateAndConsult 0xc1e553e7
address _tokenIn
uint256 _amountIn
address _tokenOut
returns: uint256
Recent Transactions
No transactions found for this address