Warning! Contract bytecode has been changed and doesn't match the verified one. Therefore, interaction with this smart contract may be risky.
- Contract name:
- UniV2Oracle
- Optimization enabled
- true
- Compiler version
- v0.6.12+commit.27d51765
- Optimization runs
- 200
- EVM Version
- default
- Verified at
- 2024-07-26T18:19:16.638567Z
Constructor Arguments
0x0000000000000000000000003f50f880041521738fa88c46cdf7e0d8eeb11aa2
Arg [0] (address) : 0x3f50f880041521738fa88c46cdf7e0d8eeb11aa2
contracts/Tokenomics/UniV2Oracle.sol
pragma solidity =0.6.12; import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; import '@uniswap/lib/contracts/libraries/FixedPoint.sol'; import '@uniswap/v2-periphery/contracts/libraries/UniswapV2OracleLibrary.sol'; // fixed window oracle that recomputes the average price for the entire period once every period // note that the price average is only guaranteed to be over at least 1 period, but may be over a longer period contract UniV2Oracle { using FixedPoint for *; uint32 public constant PERIOD = 1 hours; IUniswapV2Pair immutable pair; address public immutable token0; address public immutable token1; uint public price0CumulativeLast; uint public price1CumulativeLast; uint32 public blockTimestampLast; FixedPoint.uq112x112 public price0Average; FixedPoint.uq112x112 public price1Average; constructor(IUniswapV2Pair uniV2Pair) public { IUniswapV2Pair _pair = uniV2Pair; pair = _pair; token0 = _pair.token0(); token1 = _pair.token1(); price0CumulativeLast = _pair.price0CumulativeLast(); // fetch the current accumulated price value (1 / 0) price1CumulativeLast = _pair.price1CumulativeLast(); // fetch the current accumulated price value (0 / 1) uint112 reserve0; uint112 reserve1; (reserve0, reserve1, blockTimestampLast) = _pair.getReserves(); require(reserve0 != 0 && reserve1 != 0, 'UniV2Oracle: NO_RESERVES'); // ensure that there's liquidity in the pair } function update() external { (uint price0Cumulative, uint price1Cumulative, uint32 blockTimestamp) = UniswapV2OracleLibrary.currentCumulativePrices(address(pair)); uint32 timeElapsed = blockTimestamp - blockTimestampLast; // overflow is desired // ensure that at least one full period has passed since the last update if(timeElapsed >= PERIOD){ // overflow is desired, casting never truncates // cumulative price is in (uq112x112 price * seconds) units so we simply wrap it after division by time elapsed price0Average = FixedPoint.uq112x112(uint224((price0Cumulative - price0CumulativeLast) / timeElapsed)); price1Average = FixedPoint.uq112x112(uint224((price1Cumulative - price1CumulativeLast) / timeElapsed)); price0CumulativeLast = price0Cumulative; price1CumulativeLast = price1Cumulative; blockTimestampLast = blockTimestamp; } } // note this will always return 0 before update has been called successfully for the first time. function consult(address token, uint amountIn, uint32 age) external view returns (uint amountOut, uint32 timestamp) { timestamp = blockTimestampLast; require((currentBlockTimestamp() - timestamp < age), 'UniV2Oracle: STALE_PRICE'); if (token == token0) { amountOut = price0Average.mul(amountIn).decode144(); } else { require(token == token1, 'UniV2Oracle: INVALID_TOKEN'); amountOut = price1Average.mul(amountIn).decode144(); } } // helper function that returns the current block timestamp within the range of uint32, i.e. [0, 2**32 - 1] // based on UniswapV2OracleLibrary used by UniV2Oracle.sol function currentBlockTimestamp() internal view returns (uint32) { return uint32(block.timestamp % 2 ** 32); } }
@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 { uint _x; } uint8 private constant RESOLUTION = 112; // 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); } }
@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; }
@uniswap/v2-periphery/contracts/libraries/UniswapV2OracleLibrary.sol
pragma solidity >=0.5.0; import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol'; import '@uniswap/lib/contracts/libraries/FixedPoint.sol'; // 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; } } }
Compiler Settings
{"outputSelection":{"*":{"*":["*"],"":["*"]}},"optimizer":{"runs":200,"enabled":true},"libraries":{}}
Contract ABI
[{"type":"constructor","stateMutability":"nonpayable","inputs":[{"type":"address","name":"uniV2Pair","internalType":"contract IUniswapV2Pair"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"PERIOD","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint32","name":"","internalType":"uint32"}],"name":"blockTimestampLast","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"amountOut","internalType":"uint256"},{"type":"uint32","name":"timestamp","internalType":"uint32"}],"name":"consult","inputs":[{"type":"address","name":"token","internalType":"address"},{"type":"uint256","name":"amountIn","internalType":"uint256"},{"type":"uint32","name":"age","internalType":"uint32"}]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint224","name":"_x","internalType":"uint224"}],"name":"price0Average","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"price0CumulativeLast","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint224","name":"_x","internalType":"uint224"}],"name":"price1Average","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"uint256","name":"","internalType":"uint256"}],"name":"price1CumulativeLast","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"token0","inputs":[]},{"type":"function","stateMutability":"view","outputs":[{"type":"address","name":"","internalType":"address"}],"name":"token1","inputs":[]},{"type":"function","stateMutability":"nonpayable","outputs":[],"name":"update","inputs":[]}]
Contract Creation Code
0x60e060405234801561001057600080fd5b50604051610bce380380610bce8339818101604052602081101561003357600080fd5b50516001600160601b0319606082901b1660805260408051630dfe168160e01b8152905182916001600160a01b03831691630dfe168191600480820192602092909190829003018186803b15801561008a57600080fd5b505afa15801561009e573d6000803e3d6000fd5b505050506040513d60208110156100b457600080fd5b505160601b6001600160601b03191660a0526040805163d21220a760e01b815290516001600160a01b0383169163d21220a7916004808301926020929190829003018186803b15801561010657600080fd5b505afa15801561011a573d6000803e3d6000fd5b505050506040513d602081101561013057600080fd5b505160601b6001600160601b03191660c05260408051635909c0d560e01b815290516001600160a01b03831691635909c0d5916004808301926020929190829003018186803b15801561018257600080fd5b505afa158015610196573d6000803e3d6000fd5b505050506040513d60208110156101ac57600080fd5b505160005560408051635a3d549360e01b815290516001600160a01b03831691635a3d5493916004808301926020929190829003018186803b1580156101f157600080fd5b505afa158015610205573d6000803e3d6000fd5b505050506040513d602081101561021b57600080fd5b505160015560408051630240bc6b60e21b8152905160009182916001600160a01b03851691630902f1ac916004808301926060929190829003018186803b15801561026557600080fd5b505afa158015610279573d6000803e3d6000fd5b505050506040513d606081101561028f57600080fd5b50805160208201516040909201516002805463ffffffff191663ffffffff909216919091179055925090506001600160701b038216158015906102da57506001600160701b03811615155b61032b576040805162461bcd60e51b815260206004820152601860248201527f556e6956324f7261636c653a204e4f5f52455345525645530000000000000000604482015290519081900360640190fd5b5050505060805160601c60a05160601c60c05160601c61086061036e6000398061030852806104155250806101a8528061039f5250806101ef52506108606000f3fe608060405234801561001057600080fd5b506004361061009e5760003560e01c8063a6bb453911610066578063a6bb453914610117578063b4d1d7951461011f578063c5700a0214610140578063d21220a714610148578063f73a815d146101505761009e565b80630dfe1681146100a35780635909c0d5146100c75780635a3d5493146100e15780635e6aaf2c146100e9578063a2e620451461010d575b600080fd5b6100ab6101a6565b604080516001600160a01b039092168252519081900360200190f35b6100cf6101ca565b60408051918252519081900360200190f35b6100cf6101d0565b6100f16101d6565b604080516001600160e01b039092168252519081900360200190f35b6101156101e5565b005b6100f16102e5565b6101276102f4565b6040805163ffffffff9092168252519081900360200190f35b6101276102fa565b6100ab610306565b6101886004803603606081101561016657600080fd5b5080356001600160a01b0316906020810135906040013563ffffffff1661032a565b6040805192835263ffffffff90911660208301528051918290030190f35b7f000000000000000000000000000000000000000000000000000000000000000081565b60005481565b60015481565b6004546001600160e01b031681565b60008060006102137f00000000000000000000000000000000000000000000000000000000000000006104d4565b600254929550909350915063ffffffff908116820390610e10908216106102df5760405180602001604052808263ffffffff1660005487038161025257fe5b046001600160e01b039081169091529051600380546001600160e01b031916919092161790556040805160208101909152600154819063ffffffff84169086038161029957fe5b046001600160e01b039081169091529051600480546001600160e01b03191691909216179055600084905560018390556002805463ffffffff191663ffffffff84161790555b50505050565b6003546001600160e01b031681565b610e1081565b60025463ffffffff1681565b7f000000000000000000000000000000000000000000000000000000000000000081565b60025460009063ffffffff908116908316816103446106a3565b0363ffffffff161061039d576040805162461bcd60e51b815260206004820152601860248201527f556e6956324f7261636c653a205354414c455f50524943450000000000000000604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b031614156104135760408051602081019091526003546001600160e01b03168152610403906103fe90866106ad565b61072b565b6001600160901b031691506104cc565b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316856001600160a01b031614610499576040805162461bcd60e51b815260206004820152601a60248201527f556e6956324f7261636c653a20494e56414c49445f544f4b454e000000000000604482015290519081900360640190fd5b60408051602081019091526004546001600160e01b031681526104c0906103fe90866106ad565b6001600160901b031691505b935093915050565b60008060006104e16106a3565b9050836001600160a01b0316635909c0d56040518163ffffffff1660e01b815260040160206040518083038186803b15801561051c57600080fd5b505afa158015610530573d6000803e3d6000fd5b505050506040513d602081101561054657600080fd5b505160408051635a3d549360e01b815290519194506001600160a01b03861691635a3d549391600480820192602092909190829003018186803b15801561058c57600080fd5b505afa1580156105a0573d6000803e3d6000fd5b505050506040513d60208110156105b657600080fd5b505160408051630240bc6b60e21b81529051919350600091829182916001600160a01b03891691630902f1ac916004808301926060929190829003018186803b15801561060257600080fd5b505afa158015610616573d6000803e3d6000fd5b505050506040513d606081101561062c57600080fd5b5080516020820151604090920151909450909250905063ffffffff808216908516146106995780840363ffffffff81166106668486610732565b516001600160e01b031602969096019563ffffffff81166106878585610732565b516001600160e01b0316029590950194505b5050509193909250565b63ffffffff421690565b6106b56107e2565b60008215806106db57505082516001600160e01b0316828102908382816106d857fe5b04145b6107165760405162461bcd60e51b81526004018080602001828103825260238152602001806108086023913960400191505060405180910390fd5b60408051602081019091529081529392505050565b5160701c90565b61073a6107f5565b6000826001600160701b031611610798576040805162461bcd60e51b815260206004820152601760248201527f4669786564506f696e743a204449565f42595f5a45524f000000000000000000604482015290519081900360640190fd5b6040805160208101909152806001600160701b0384166dffffffffffffffffffffffffffff60701b607087901b16816107cd57fe5b046001600160e01b0316815250905092915050565b6040518060200160405280600081525090565b6040805160208101909152600081529056fe4669786564506f696e743a204d554c5449504c49434154494f4e5f4f564552464c4f57a2646970667358221220ab25b354454027d74b60a94b9b988b52ee02e3dbe1c813b7c23684dccd470cdd64736f6c634300060c00330000000000000000000000003f50f880041521738fa88c46cdf7e0d8eeb11aa2
Deployed ByteCode
0x608060405234801561001057600080fd5b506004361061009e5760003560e01c8063a6bb453911610066578063a6bb453914610117578063b4d1d7951461011f578063c5700a0214610140578063d21220a714610148578063f73a815d146101505761009e565b80630dfe1681146100a35780635909c0d5146100c75780635a3d5493146100e15780635e6aaf2c146100e9578063a2e620451461010d575b600080fd5b6100ab6101a6565b604080516001600160a01b039092168252519081900360200190f35b6100cf6101ca565b60408051918252519081900360200190f35b6100cf6101d0565b6100f16101d6565b604080516001600160e01b039092168252519081900360200190f35b6101156101e5565b005b6100f16102e5565b6101276102f4565b6040805163ffffffff9092168252519081900360200190f35b6101276102fa565b6100ab610306565b6101886004803603606081101561016657600080fd5b5080356001600160a01b0316906020810135906040013563ffffffff1661032a565b6040805192835263ffffffff90911660208301528051918290030190f35b7f00000000000000000000000012e605bc104e93b45e1ad99f9e555f659051c2bb81565b60005481565b60015481565b6004546001600160e01b031681565b60008060006102137f0000000000000000000000003f50f880041521738fa88c46cdf7e0d8eeb11aa26104d4565b600254929550909350915063ffffffff908116820390610e10908216106102df5760405180602001604052808263ffffffff1660005487038161025257fe5b046001600160e01b039081169091529051600380546001600160e01b031916919092161790556040805160208101909152600154819063ffffffff84169086038161029957fe5b046001600160e01b039081169091529051600480546001600160e01b03191691909216179055600084905560018390556002805463ffffffff191663ffffffff84161790555b50505050565b6003546001600160e01b031681565b610e1081565b60025463ffffffff1681565b7f0000000000000000000000001d80c49bbbcd1c0911346656b529df9e5c2f783d81565b60025460009063ffffffff908116908316816103446106a3565b0363ffffffff161061039d576040805162461bcd60e51b815260206004820152601860248201527f556e6956324f7261636c653a205354414c455f50524943450000000000000000604482015290519081900360640190fd5b7f00000000000000000000000012e605bc104e93b45e1ad99f9e555f659051c2bb6001600160a01b0316856001600160a01b031614156104135760408051602081019091526003546001600160e01b03168152610403906103fe90866106ad565b61072b565b6001600160901b031691506104cc565b7f0000000000000000000000001d80c49bbbcd1c0911346656b529df9e5c2f783d6001600160a01b0316856001600160a01b031614610499576040805162461bcd60e51b815260206004820152601a60248201527f556e6956324f7261636c653a20494e56414c49445f544f4b454e000000000000604482015290519081900360640190fd5b60408051602081019091526004546001600160e01b031681526104c0906103fe90866106ad565b6001600160901b031691505b935093915050565b60008060006104e16106a3565b9050836001600160a01b0316635909c0d56040518163ffffffff1660e01b815260040160206040518083038186803b15801561051c57600080fd5b505afa158015610530573d6000803e3d6000fd5b505050506040513d602081101561054657600080fd5b505160408051635a3d549360e01b815290519194506001600160a01b03861691635a3d549391600480820192602092909190829003018186803b15801561058c57600080fd5b505afa1580156105a0573d6000803e3d6000fd5b505050506040513d60208110156105b657600080fd5b505160408051630240bc6b60e21b81529051919350600091829182916001600160a01b03891691630902f1ac916004808301926060929190829003018186803b15801561060257600080fd5b505afa158015610616573d6000803e3d6000fd5b505050506040513d606081101561062c57600080fd5b5080516020820151604090920151909450909250905063ffffffff808216908516146106995780840363ffffffff81166106668486610732565b516001600160e01b031602969096019563ffffffff81166106878585610732565b516001600160e01b0316029590950194505b5050509193909250565b63ffffffff421690565b6106b56107e2565b60008215806106db57505082516001600160e01b0316828102908382816106d857fe5b04145b6107165760405162461bcd60e51b81526004018080602001828103825260238152602001806108086023913960400191505060405180910390fd5b60408051602081019091529081529392505050565b5160701c90565b61073a6107f5565b6000826001600160701b031611610798576040805162461bcd60e51b815260206004820152601760248201527f4669786564506f696e743a204449565f42595f5a45524f000000000000000000604482015290519081900360640190fd5b6040805160208101909152806001600160701b0384166dffffffffffffffffffffffffffff60701b607087901b16816107cd57fe5b046001600160e01b0316815250905092915050565b6040518060200160405280600081525090565b6040805160208101909152600081529056fe4669786564506f696e743a204d554c5449504c49434154494f4e5f4f564552464c4f57a2646970667358221220ab25b354454027d74b60a94b9b988b52ee02e3dbe1c813b7c23684dccd470cdd64736f6c634300060c0033