Source Code
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 31209007 | 16 hrs ago | 0 FRAX | |||||
| 31209007 | 16 hrs ago | 0 FRAX | |||||
| 31209007 | 16 hrs ago | 0 FRAX | |||||
| 31209007 | 16 hrs ago | 0 FRAX | |||||
| 31209007 | 16 hrs ago | 0 FRAX | |||||
| 31209007 | 16 hrs ago | 0 FRAX | |||||
| 31209007 | 16 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31206525 | 18 hrs ago | 0 FRAX | |||||
| 31203769 | 19 hrs ago | 0 FRAX | |||||
| 31203769 | 19 hrs ago | 0 FRAX | |||||
| 31203769 | 19 hrs ago | 0 FRAX | |||||
| 31203769 | 19 hrs ago | 0 FRAX | |||||
| 31203769 | 19 hrs ago | 0 FRAX |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
FrxEthDualOracle
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 1000000 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ======================== FrxEthDualOracle =========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// ====================================================================
import { Timelock2Step } from "frax-std/access-control/v1/Timelock2Step.sol";
import { ITimelock2Step } from "frax-std/access-control/v1/interfaces/ITimelock2Step.sol";
import { UniswapV3SingleTwapOracle, ConstructorParams as UniswapV3SingleTwapOracleParams } from "../abstracts/UniswapV3SingleTwapOracle.sol";
import { ChainlinkOracleWithMaxDelay, ConstructorParams as ChainlinkOracleWithMaxDelayParams } from "../abstracts/ChainlinkOracleWithMaxDelay.sol";
import { EthUsdChainlinkOracleWithMaxDelay, ConstructorParams as EthUsdChainlinkOracleWithMaxDelayParams } from "../abstracts/EthUsdChainlinkOracleWithMaxDelay.sol";
import { DualOracleBase, ConstructorParams as DualOracleBaseParams } from "../DualOracleBase.sol";
import { FraxSwapTwapOracle, ConstructorParams as FraxSwapOracleParams } from "../abstracts/FraxSwapTwapPriceOracle.sol";
import "interfaces/IDualOracle.sol";
struct ConstructorParams {
address fraxswapPair;
uint32 twapDuration;
address frxEthErc20;
address frxEthUsdChainlinkFeed;
uint256 maximumOracleDelay;
address timelockAddress;
}
/// @title FrxEthDualOracle
contract FrxEthDualOracle is DualOracleBase, Timelock2Step, FraxSwapTwapOracle, EthUsdChainlinkOracleWithMaxDelay {
address public immutable FRXETH_ERC20;
constructor(
ConstructorParams memory _params
)
DualOracleBase(
DualOracleBaseParams({
baseToken0: address(840),
baseToken0Decimals: 18,
quoteToken0: _params.frxEthErc20,
quoteToken0Decimals: 18,
baseToken1: address(840),
baseToken1Decimals: 18,
quoteToken1: _params.frxEthErc20,
quoteToken1Decimals: 18
})
)
Timelock2Step()
EthUsdChainlinkOracleWithMaxDelay(
EthUsdChainlinkOracleWithMaxDelayParams({
ethUsdChainlinkFeedAddress: _params.frxEthUsdChainlinkFeed,
maxEthUsdOracleDelay: _params.maximumOracleDelay
})
)
FraxSwapTwapOracle(
FraxSwapOracleParams({
fraxswapPair: _params.fraxswapPair,
toQuote: _params.frxEthErc20,
twapDuration: _params.twapDuration
})
)
{
_setTimelock({ _newTimelock: _params.timelockAddress });
_registerInterface({ interfaceId: type(IDualOracle).interfaceId });
_registerInterface({ interfaceId: type(ITimelock2Step).interfaceId });
FRXETH_ERC20 = _params.frxEthErc20;
}
// ====================================================================
// View Helpers
// ====================================================================
function name() external pure returns (string memory) {
return "FrxEth RedStone Dual Oracle + TWAP";
}
// ====================================================================
// Configuration Setters
// ====================================================================
/// @notice The ```setMaximumEthUsdOracleDelay``` function set the max oracle delay for the Eth/USD Redstone oracle
/// @dev Requires msg.sender to be the timelock address
/// @param _newMaxOracleDelay The new max oracle delay
function setMaximumEthUsdOracleDelay(uint256 _newMaxOracleDelay) external override {
_requireTimelock();
_setMaximumEthUsdOracleDelay({ _newMaxOracleDelay: _newMaxOracleDelay });
}
/// @notice The ```setTwapDurationFraxSwap``` function set the twap duration for the FraxSwap Twap Oracle
/// @dev Requiores msg.sender to be the timelock address
/// @param _newTwapDuration The new twap duration
function setTwapDurationFraxSwap(uint32 _newTwapDuration) external override {
_requireTimelock();
_setTwapDurationFraxSwap({ _newTwapDuration: _newTwapDuration });
}
// ====================================================================
// Price Functions
// ====================================================================
/// @notice The ```getEthPerUsdRedStone``` function returns the amount of eth per 1 USD
/// @return _isBadData Whether the data returned from the oracle is stale
/// @return _ethPerUsd The amount of eth per unit of USD
function getEthPerUsdRedStone() public view returns (bool _isBadData, uint256 _ethPerUsd) {
(bool isBadData, , uint256 usdPerEth) = _getEthUsdChainlinkPrice();
_isBadData = isBadData;
_ethPerUsd = (ETH_USD_CHAINLINK_FEED_PRECISION * ORACLE_PRECISION) / usdPerEth;
}
/// @notice The ```getPricesNormalized``` function returns the normalized prices in human readable form
/// @return _isBadDataNormal If the Redstone oracle is stale
/// @return _priceLowNormal The normalized low price
/// @return _priceHighNormal The normalized high price
function getPricesNormalized()
external
view
returns (bool _isBadDataNormal, uint256 _priceLowNormal, uint256 _priceHighNormal)
{
(bool _isBadData, uint256 _priceLow, uint256 _priceHigh) = _getPrices();
_isBadDataNormal = _isBadData;
_priceLowNormal = NORMALIZATION_0 > 0
? _priceLow * 10 ** uint256(NORMALIZATION_0)
: _priceLow / 10 ** (uint256(-NORMALIZATION_0));
_priceHighNormal = NORMALIZATION_1 > 0
? _priceHigh * 10 ** uint256(NORMALIZATION_1)
: _priceHigh / 10 ** (uint256(-NORMALIZATION_1));
}
function _getPrices() internal view returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh) {
(bool isBadData, uint256 _ethPerUsdRedStone) = getEthPerUsdRedStone();
uint256 _fraxPerEthTwap = _getTwapFraxSwapPair();
uint256 _ethPerFraxTwap = (ORACLE_PRECISION ** 2) / _fraxPerEthTwap;
_isBadData = isBadData;
_priceLow = _ethPerFraxTwap < _ethPerUsdRedStone ? _ethPerFraxTwap : _ethPerUsdRedStone;
_priceHigh = _ethPerUsdRedStone > _ethPerFraxTwap ? _ethPerUsdRedStone : _ethPerFraxTwap;
}
/// @notice The ```getPrices``` function is intended to return two prices from different oracles
/// @return _isBadData is true when data is stale or otherwise bad
/// @return _priceLow is the lower of the two prices
/// @return _priceHigh is the higher of the two prices
function getPrices() external view returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh) {
return _getPrices();
}
}// SPDX-License-Identifier: ISC
pragma solidity >=0.8.0;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ========================== Timelock2Step ===========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Primary Author
// Drake Evans: https://github.com/DrakeEvans
// Reviewers
// Dennis: https://github.com/denett
// ====================================================================
/// @title Timelock2Step
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @dev Inspired by the OpenZeppelin's Ownable2Step contract
/// @notice An abstract contract which contains 2-step transfer and renounce logic for a timelock address
abstract contract Timelock2Step {
/// @notice The pending timelock address
address public pendingTimelockAddress;
/// @notice The current timelock address
address public timelockAddress;
constructor() {
timelockAddress = msg.sender;
}
/// @notice Emitted when timelock is transferred
error OnlyTimelock();
/// @notice Emitted when pending timelock is transferred
error OnlyPendingTimelock();
/// @notice The ```TimelockTransferStarted``` event is emitted when the timelock transfer is initiated
/// @param previousTimelock The address of the previous timelock
/// @param newTimelock The address of the new timelock
event TimelockTransferStarted(address indexed previousTimelock, address indexed newTimelock);
/// @notice The ```TimelockTransferred``` event is emitted when the timelock transfer is completed
/// @param previousTimelock The address of the previous timelock
/// @param newTimelock The address of the new timelock
event TimelockTransferred(address indexed previousTimelock, address indexed newTimelock);
/// @notice The ```_isSenderTimelock``` function checks if msg.sender is current timelock address
/// @return Whether or not msg.sender is current timelock address
function _isSenderTimelock() internal view returns (bool) {
return msg.sender == timelockAddress;
}
/// @notice The ```_requireTimelock``` function reverts if msg.sender is not current timelock address
function _requireTimelock() internal view {
if (msg.sender != timelockAddress) revert OnlyTimelock();
}
/// @notice The ```_isSenderPendingTimelock``` function checks if msg.sender is pending timelock address
/// @return Whether or not msg.sender is pending timelock address
function _isSenderPendingTimelock() internal view returns (bool) {
return msg.sender == pendingTimelockAddress;
}
/// @notice The ```_requirePendingTimelock``` function reverts if msg.sender is not pending timelock address
function _requirePendingTimelock() internal view {
if (msg.sender != pendingTimelockAddress) revert OnlyPendingTimelock();
}
/// @notice The ```_transferTimelock``` function initiates the timelock transfer
/// @dev This function is to be implemented by a public function
/// @param _newTimelock The address of the nominated (pending) timelock
function _transferTimelock(address _newTimelock) internal {
pendingTimelockAddress = _newTimelock;
emit TimelockTransferStarted(timelockAddress, _newTimelock);
}
/// @notice The ```_acceptTransferTimelock``` function completes the timelock transfer
/// @dev This function is to be implemented by a public function
function _acceptTransferTimelock() internal {
pendingTimelockAddress = address(0);
_setTimelock(msg.sender);
}
/// @notice The ```_setTimelock``` function sets the timelock address
/// @dev This function is to be implemented by a public function
/// @param _newTimelock The address of the new timelock
function _setTimelock(address _newTimelock) internal {
emit TimelockTransferred(timelockAddress, _newTimelock);
timelockAddress = _newTimelock;
}
/// @notice The ```transferTimelock``` function initiates the timelock transfer
/// @dev Must be called by the current timelock
/// @param _newTimelock The address of the nominated (pending) timelock
function transferTimelock(address _newTimelock) external virtual {
_requireTimelock();
_transferTimelock(_newTimelock);
}
/// @notice The ```acceptTransferTimelock``` function completes the timelock transfer
/// @dev Must be called by the pending timelock
function acceptTransferTimelock() external virtual {
_requirePendingTimelock();
_acceptTransferTimelock();
}
/// @notice The ```renounceTimelock``` function renounces the timelock after setting pending timelock to current timelock
/// @dev Pending timelock must be set to current timelock before renouncing, creating a 2-step renounce process
function renounceTimelock() external virtual {
_requireTimelock();
_requirePendingTimelock();
_transferTimelock(address(0));
_setTimelock(address(0));
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;
interface ITimelock2Step {
event TimelockTransferStarted(address indexed previousTimelock, address indexed newTimelock);
event TimelockTransferred(address indexed previousTimelock, address indexed newTimelock);
function acceptTransferTimelock() external;
function pendingTimelockAddress() external view returns (address);
function renounceTimelock() external;
function timelockAddress() external view returns (address);
function transferTimelock(address _newTimelock) external;
}// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ==================== UniswapV3SingleTwapOracle =====================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Author
// Drake Evans: https://github.com/DrakeEvans
// Reviewers
// Dennis: https://github.com/denett
// ====================================================================
import { IStaticOracle } from "@mean-finance/uniswap-v3-oracle/solidity/interfaces/IStaticOracle.sol";
import { ERC165Storage } from "src/contracts/utils/ERC165Storage.sol";
import { IUniswapV3SingleTwapOracle } from "interfaces/oracles/abstracts/IUniswapV3SingleTwapOracle.sol";
struct ConstructorParams {
address uniswapV3PairAddress;
uint32 twapDuration;
address baseToken;
address quoteToken;
}
/// @title UniswapV3SingleTwapOracle
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @notice An oracle for UniV3 Twap prices
abstract contract UniswapV3SingleTwapOracle is ERC165Storage, IUniswapV3SingleTwapOracle {
/// @notice address of the Uniswap V3 pair
address public immutable UNI_V3_PAIR_ADDRESS;
/// @notice The precision of the twap
uint128 public constant TWAP_PRECISION = 1e18;
/// @notice The base token of the twap
address public immutable UNISWAP_V3_TWAP_BASE_TOKEN;
/// @notice The quote token of the twap
address public immutable UNISWAP_V3_TWAP_QUOTE_TOKEN;
/// @notice The duration of the twap
uint32 public twapDuration;
constructor(ConstructorParams memory _params) {
_registerInterface({ interfaceId: type(IUniswapV3SingleTwapOracle).interfaceId });
UNI_V3_PAIR_ADDRESS = _params.uniswapV3PairAddress;
twapDuration = _params.twapDuration;
UNISWAP_V3_TWAP_BASE_TOKEN = _params.baseToken;
UNISWAP_V3_TWAP_QUOTE_TOKEN = _params.quoteToken;
}
/// @notice The ```_setTwapDuration``` function sets duration of the twap
/// @param _newTwapDuration The new twap duration
function _setTwapDuration(uint32 _newTwapDuration) internal {
emit SetTwapDuration({ oldTwapDuration: twapDuration, newTwapDuration: _newTwapDuration });
twapDuration = _newTwapDuration;
}
function setTwapDuration(uint32 _newTwapDuration) external virtual;
/// @notice The ```_getUniswapV3Twap``` function is called to get the twap
/// @return _twap The twap price
function _getUniswapV3Twap() internal view returns (uint256 _twap) {
address[] memory _pools = new address[](1);
_pools[0] = UNI_V3_PAIR_ADDRESS;
_twap = IStaticOracle(0xB210CE856631EeEB767eFa666EC7C1C57738d438).quoteSpecificPoolsWithTimePeriod({
baseAmount: TWAP_PRECISION,
baseToken: UNISWAP_V3_TWAP_BASE_TOKEN,
quoteToken: UNISWAP_V3_TWAP_QUOTE_TOKEN,
pools: _pools,
period: twapDuration
});
}
/// @notice The ```getUniswapV3Twap``` function is called to get the twap
/// @return _twap The twap price
function getUniswapV3Twap() external view virtual returns (uint256 _twap) {
_twap = _getUniswapV3Twap();
}
}// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// =================== ChainlinkOracleWithMaxDelay ====================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Author
// Drake Evans: https://github.com/DrakeEvans
// Reviewers
// Dennis: https://github.com/denett
// ====================================================================
import { AggregatorV3Interface } from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import { ERC165Storage } from "src/contracts/utils/ERC165Storage.sol";
import { IChainlinkOracleWithMaxDelay } from "interfaces/oracles/abstracts/IChainlinkOracleWithMaxDelay.sol";
struct ConstructorParams {
address chainlinkFeedAddress;
uint256 maximumOracleDelay;
}
/// @title ChainlinkOracleWithMaxDelay
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @notice An abstract oracle for getting prices from Chainlink
abstract contract ChainlinkOracleWithMaxDelay is ERC165Storage, IChainlinkOracleWithMaxDelay {
/// @notice Chainlink aggregator
address public immutable CHAINLINK_FEED_ADDRESS;
/// @notice Decimals of ETH/USD chainlink feed
uint8 public immutable CHAINLINK_FEED_DECIMALS;
/// @notice Precision of ETH/USD chainlink feed
uint256 public immutable CHAINLINK_FEED_PRECISION;
/// @notice Maximum delay of Chainlink data, after which it is considered stale
uint256 public maximumOracleDelay;
constructor(ConstructorParams memory _params) {
_registerInterface({ interfaceId: type(IChainlinkOracleWithMaxDelay).interfaceId });
CHAINLINK_FEED_ADDRESS = _params.chainlinkFeedAddress;
CHAINLINK_FEED_DECIMALS = AggregatorV3Interface(CHAINLINK_FEED_ADDRESS).decimals();
CHAINLINK_FEED_PRECISION = 10 ** uint256(CHAINLINK_FEED_DECIMALS);
maximumOracleDelay = _params.maximumOracleDelay;
}
/// @notice The ```SetMaximumOracleDelay``` event is emitted when the max oracle delay is set
/// @param oldMaxOracleDelay The old max oracle delay
/// @param newMaxOracleDelay The new max oracle delay
event SetMaximumOracleDelay(uint256 oldMaxOracleDelay, uint256 newMaxOracleDelay);
/// @notice The ```_setMaximumOracleDelay``` function sets the max oracle delay to determine if Chainlink data is stale
/// @param _newMaxOracleDelay The new max oracle delay
function _setMaximumOracleDelay(uint256 _newMaxOracleDelay) internal {
emit SetMaximumOracleDelay({ oldMaxOracleDelay: maximumOracleDelay, newMaxOracleDelay: _newMaxOracleDelay });
maximumOracleDelay = _newMaxOracleDelay;
}
function setMaximumOracleDelay(uint256 _newMaxOracleDelay) external virtual;
function _getChainlinkPrice() internal view returns (bool _isBadData, uint256 _updatedAt, uint256 _price) {
(, int256 _answer, , uint256 _chainlinkUpdatedAt, ) = AggregatorV3Interface(CHAINLINK_FEED_ADDRESS)
.latestRoundData();
// If data is stale or negative, set bad data to true and return
_isBadData = _answer <= 0 || ((block.timestamp - _chainlinkUpdatedAt) > maximumOracleDelay);
_updatedAt = _chainlinkUpdatedAt;
_price = uint256(_answer);
}
/// @notice The ```getChainlinkPrice``` function returns the chainlink price and the timestamp of the last update
/// @dev Uses the same prevision as the chainlink feed, virtual so it can be overridden
/// @return _isBadData True if the data is stale or negative
/// @return _updatedAt The timestamp of the last update
/// @return _price The price
function getChainlinkPrice() external view virtual returns (bool _isBadData, uint256 _updatedAt, uint256 _price) {
return _getChainlinkPrice();
}
}// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ================ EthUsdChainlinkOracleWithMaxDelay =================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Author
// Drake Evans: https://github.com/DrakeEvans
// Reviewers
// Dennis: https://github.com/denett
// ====================================================================
import { AggregatorV3Interface } from "@chainlink/contracts/src/v0.8/interfaces/AggregatorV3Interface.sol";
import { ERC165Storage } from "src/contracts/utils/ERC165Storage.sol";
import { IEthUsdChainlinkOracleWithMaxDelay } from "interfaces/oracles/abstracts/IEthUsdChainlinkOracleWithMaxDelay.sol";
struct ConstructorParams {
address ethUsdChainlinkFeedAddress;
uint256 maxEthUsdOracleDelay;
}
/// @title EthUsdChainlinkOracleWithMaxDelay
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @notice An abstract oracle for getting eth/usd prices from Chainlink
abstract contract EthUsdChainlinkOracleWithMaxDelay is ERC165Storage, IEthUsdChainlinkOracleWithMaxDelay {
/// @notice Chainlink aggregator
address public immutable ETH_USD_CHAINLINK_FEED_ADDRESS;
/// @notice Decimals of ETH/USD chainlink feed
uint8 public immutable ETH_USD_CHAINLINK_FEED_DECIMALS;
/// @notice Precision of ETH/USD chainlink feed
uint256 public immutable ETH_USD_CHAINLINK_FEED_PRECISION;
/// @notice Maximum delay of Chainlink data, after which it is considered stale
uint256 public maximumEthUsdOracleDelay;
constructor(ConstructorParams memory _params) {
_registerInterface({ interfaceId: type(IEthUsdChainlinkOracleWithMaxDelay).interfaceId });
ETH_USD_CHAINLINK_FEED_ADDRESS = _params.ethUsdChainlinkFeedAddress;
ETH_USD_CHAINLINK_FEED_DECIMALS = AggregatorV3Interface(ETH_USD_CHAINLINK_FEED_ADDRESS).decimals();
ETH_USD_CHAINLINK_FEED_PRECISION = 10 ** uint256(ETH_USD_CHAINLINK_FEED_DECIMALS);
maximumEthUsdOracleDelay = _params.maxEthUsdOracleDelay;
}
/// @notice The ```_setMaximumEthUsdOracleDelay``` function sets the max oracle delay to determine if Chainlink data is stale
/// @param _newMaxOracleDelay The new max oracle delay
function _setMaximumEthUsdOracleDelay(uint256 _newMaxOracleDelay) internal {
emit SetMaximumEthUsdOracleDelay({
oldMaxOracleDelay: maximumEthUsdOracleDelay,
newMaxOracleDelay: _newMaxOracleDelay
});
maximumEthUsdOracleDelay = _newMaxOracleDelay;
}
function setMaximumEthUsdOracleDelay(uint256 _newMaxOracleDelay) external virtual;
/// @notice The ```_getEthUsdChainlinkPrice``` function is called to get the eth/usd price from Chainlink
/// @dev If data is stale or negative, set bad data to true and return
/// @return _isBadData If the data is stale
/// @return _updatedAt The timestamp of the last update
/// @return _usdPerEth The eth/usd price
function _getEthUsdChainlinkPrice()
internal
view
returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth)
{
(, int256 _answer, , uint256 _ethUsdChainlinkUpdatedAt, ) = AggregatorV3Interface(
ETH_USD_CHAINLINK_FEED_ADDRESS
).latestRoundData();
// If data is stale or negative, set bad data to true and return
_isBadData = _answer <= 0 || ((block.timestamp - _ethUsdChainlinkUpdatedAt) > maximumEthUsdOracleDelay);
_updatedAt = _ethUsdChainlinkUpdatedAt;
_usdPerEth = uint256(_answer);
}
/// @notice The ```getEthUsdChainlinkPrice``` function is called to get the eth/usd price from Chainlink
/// @return _isBadData If the data is stale
/// @return _updatedAt The timestamp of the last update
/// @return _usdPerEth The eth/usd price
function getEthUsdChainlinkPrice()
external
view
virtual
returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth)
{
(_isBadData, _updatedAt, _usdPerEth) = _getEthUsdChainlinkPrice();
}
}// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ========================== DualOracleBase ==========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Author
// Drake Evans: https://github.com/DrakeEvans
// ====================================================================
import "interfaces/IDualOracle.sol";
struct ConstructorParams {
address baseToken0;
uint8 baseToken0Decimals;
address quoteToken0;
uint8 quoteToken0Decimals;
address baseToken1;
uint8 baseToken1Decimals;
address quoteToken1;
uint8 quoteToken1Decimals;
}
/// @title DualOracleBase
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @notice Base Contract for Frax Dual Oracles
abstract contract DualOracleBase is IDualOracle {
/// @notice The precision of the oracle
uint256 public constant ORACLE_PRECISION = 1e18;
/// @notice The first quote token
address public immutable QUOTE_TOKEN_0;
/// @notice The first quote token decimals
uint256 public immutable QUOTE_TOKEN_0_DECIMALS;
/// @notice The second quote token
address public immutable QUOTE_TOKEN_1;
/// @notice The second quote token decimals
uint256 public immutable QUOTE_TOKEN_1_DECIMALS;
/// @notice The first base token
address public immutable BASE_TOKEN_0;
/// @notice The first base token decimals
uint256 public immutable BASE_TOKEN_0_DECIMALS;
/// @notice The second base token
address public immutable BASE_TOKEN_1;
/// @notice The second base token decimals
uint256 public immutable BASE_TOKEN_1_DECIMALS;
/// @notice The first normalization factor which accounts for different decimals across ERC20s
/// @dev Normalization = quoteTokenDecimals - baseTokenDecimals
int256 public immutable NORMALIZATION_0;
/// @notice The second normalization factor which accounts for different decimals across ERC20s
/// @dev Normalization = quoteTokenDecimals - baseTokenDecimals
int256 public immutable NORMALIZATION_1;
constructor(ConstructorParams memory _params) {
QUOTE_TOKEN_0 = _params.quoteToken0;
QUOTE_TOKEN_0_DECIMALS = _params.quoteToken0Decimals;
QUOTE_TOKEN_1 = _params.quoteToken1;
QUOTE_TOKEN_1_DECIMALS = _params.quoteToken1Decimals;
BASE_TOKEN_0 = _params.baseToken0;
BASE_TOKEN_0_DECIMALS = _params.baseToken0Decimals;
BASE_TOKEN_1 = _params.baseToken1;
BASE_TOKEN_1_DECIMALS = _params.baseToken1Decimals;
NORMALIZATION_0 = int256(QUOTE_TOKEN_0_DECIMALS) - int256(BASE_TOKEN_0_DECIMALS);
NORMALIZATION_1 = int256(QUOTE_TOKEN_1_DECIMALS) - int256(BASE_TOKEN_1_DECIMALS);
}
// ====================================================================
// View Helpers
// ====================================================================
function decimals() external pure returns (uint8) {
return 18;
}
}// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ======================= FraxswapTwapOracle =========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// ====================================================================
import { ERC165Storage } from "src/contracts/utils/ERC165Storage.sol";
import { IERC20Metadata } from "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import { IFraxswapPair } from "dev-fraxswap/src/contracts/core/interfaces/IFraxswapPair.sol";
import { UQ112x112 } from "src/contracts/utils/UQ112x112.sol";
struct ConstructorParams {
address fraxswapPair;
address toQuote;
uint32 twapDuration;
}
/// @title FraxSwapTwapOracle
/// @notice Will fetch the twap price of the quote asset denominated in the base token
/// @notice Only intended to work for pairs in which both of the assets have 18 decimals
abstract contract FraxSwapTwapOracle is ERC165Storage {
/// @notice Fraxswap Pair to source twap
IFraxswapPair public immutable FRAXSWAP_PAIR;
/// @notice The token in the fraxswap pair which the price of the base token is denominated in
address public FRAXSWAP_BASE_TOKEN;
/// @notice The token in the fraxswap pair which we would like the twap of
address public FRAXSWAP_QUOTE_TOKEN;
/// @notice The duration of the time wieghted moving average is
uint32 public twapDuration;
/// @notice flow control to perform the operation on token0|token1 accounting
bool isToken0;
using UQ112x112 for uint224;
constructor(ConstructorParams memory _params) {
// Fraxswap Oracle Config
FRAXSWAP_PAIR = IFraxswapPair(_params.fraxswapPair);
twapDuration = _params.twapDuration;
address token0 = FRAXSWAP_PAIR.token0();
address token1 = FRAXSWAP_PAIR.token1();
if (token0 == _params.toQuote) {
isToken0 = true;
FRAXSWAP_QUOTE_TOKEN = _params.toQuote;
FRAXSWAP_BASE_TOKEN = token1;
} else if (token1 == _params.toQuote) {
// isToken0 initalizes to false
FRAXSWAP_QUOTE_TOKEN = _params.toQuote;
FRAXSWAP_BASE_TOKEN = token0;
} else {
revert TokenNotInPair();
}
// Sanity check tokens
if (FRAXSWAP_PAIR.getTWAPHistoryLength() < 5) revert PairNotOldEnough();
if (IERC20Metadata(token0).decimals() != 18) revert WrongDecimals();
if (IERC20Metadata(token1).decimals() != 18) revert WrongDecimals();
}
// ====================================================================
// Post Construction Setters
// ====================================================================
function setTwapDurationFraxSwap(uint32 _newTwapDuration) external virtual;
/// @notice The ```_setTwapDurationFraxSwap``` function is called to modify the twap duration post deployment
/// @dev Contains no access control
/// @param _newTwapDuration The new twap duration to set
function _setTwapDurationFraxSwap(uint32 _newTwapDuration) internal {
emit NewTwapDurationSet(twapDuration, _newTwapDuration);
twapDuration = _newTwapDuration;
}
// ====================================================================
// Twap Pricinge Function
// ====================================================================
/// @notice The ```_getTwapFraxSwapPair``` function is called to get the twap of the fraxswap pair
/// @return _basePerQuote returns the amount of base token per quote token
function _getTwapFraxSwapPair() public view virtual returns (uint256 _basePerQuote) {
uint256 len = FRAXSWAP_PAIR.getTWAPHistoryLength();
IFraxswapPair.TWAPObservation memory obsCurrent = FRAXSWAP_PAIR.TWAPObservationHistory(len - 1);
// Update last observation up to the current block
if (obsCurrent.timestamp < block.timestamp) {
// Update the reserves
(uint112 _reserve0, uint112 _reserve1, ) = FRAXSWAP_PAIR.getReserves();
uint32 blockTimestamp = uint32(block.timestamp % 2 ** 32);
// Get the latest observed prices
unchecked {
uint32 timeElapsed = blockTimestamp - uint32(obsCurrent.timestamp);
obsCurrent.price0CumulativeLast += uint256(UQ112x112.encode(_reserve1).uqdiv(_reserve0)) * timeElapsed;
obsCurrent.price1CumulativeLast += uint256(UQ112x112.encode(_reserve0).uqdiv(_reserve1)) * timeElapsed;
obsCurrent.timestamp = blockTimestamp;
}
}
IFraxswapPair.TWAPObservation memory obsLast;
uint256 j;
// Cannot be > 1 obs per second and > 1 block per second
for (uint256 i = twapDuration / 40; i < twapDuration; i += twapDuration / 20) {
obsLast = FRAXSWAP_PAIR.TWAPObservationHistory(len - (1 + i));
unchecked {
if ((obsCurrent.timestamp - obsLast.timestamp) < twapDuration) {
j = i;
} else {
break;
}
}
}
for (j; j < len; j++) {
obsLast = FRAXSWAP_PAIR.TWAPObservationHistory(len - (1 + j));
unchecked {
if ((obsCurrent.timestamp - obsLast.timestamp) > twapDuration) break;
}
}
if (isToken0) {
uint256 encoded;
unchecked {
encoded =
(obsCurrent.price0CumulativeLast - obsLast.price0CumulativeLast) /
uint32(obsCurrent.timestamp - obsLast.timestamp);
}
_basePerQuote = decode112with18(encoded);
} else {
uint256 encoded;
unchecked {
encoded =
(obsCurrent.price1CumulativeLast - obsLast.price1CumulativeLast) /
uint32(obsCurrent.timestamp - obsLast.timestamp);
}
_basePerQuote = decode112with18(encoded);
}
}
// ====================================================================
// Math Utilities
// ====================================================================
// Inspired by https://gist.github.com/alexroan/629172728f82cb5c88554896163b35a0#file-uniswapanchoredview-sol-L24
// decode a uq112x112 into a uint with 18 decimals of precision
function decode112with18(uint256 valToDecode) internal pure returns (uint256) {
// we only have 256 - 224 = 32 bits to spare, so scaling up by ~60 bits is dangerous
// instead, get close to:
// (x * 1e18) >> 112
// without risk of overflowing, e.g.:
// (x) / 2 ** (112 - lg(1e18))
return valToDecode / 5_192_296_858_534_827;
}
event NewTwapDurationSet(uint32 oldDuration, uint32 newDuration);
error TokenNotInPair();
error WrongDecimals();
error PairNotOldEnough();
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface IDualOracle is IERC165 {
function ORACLE_PRECISION() external view returns (uint256);
function BASE_TOKEN_0() external view returns (address);
function BASE_TOKEN_0_DECIMALS() external view returns (uint256);
function BASE_TOKEN_1() external view returns (address);
function BASE_TOKEN_1_DECIMALS() external view returns (uint256);
function decimals() external view returns (uint8);
function getPricesNormalized() external view returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh);
function getPrices() external view returns (bool _isBadData, uint256 _priceLow, uint256 _priceHigh);
function name() external view returns (string memory);
function NORMALIZATION_0() external view returns (int256);
function NORMALIZATION_1() external view returns (int256);
function QUOTE_TOKEN_0() external view returns (address);
function QUOTE_TOKEN_0_DECIMALS() external view returns (uint256);
function QUOTE_TOKEN_1() external view returns (address);
function QUOTE_TOKEN_1_DECIMALS() external view returns (uint256);
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.7.6 <0.9.0;
import '@uniswap/v3-core/contracts/interfaces/IUniswapV3Factory.sol';
/// @title Uniswap V3 Static Oracle
/// @notice Oracle contract for calculating price quoting against Uniswap V3
interface IStaticOracle {
/// @notice Returns the address of the Uniswap V3 factory
/// @dev This value is assigned during deployment and cannot be changed
/// @return The address of the Uniswap V3 factory
function UNISWAP_V3_FACTORY() external view returns (IUniswapV3Factory);
/// @notice Returns how many observations are needed per minute in Uniswap V3 oracles, on the deployed chain
/// @dev This value is assigned during deployment and cannot be changed
/// @return Number of observation that are needed per minute
function CARDINALITY_PER_MINUTE() external view returns (uint8);
/// @notice Returns all supported fee tiers
/// @return The supported fee tiers
function supportedFeeTiers() external view returns (uint24[] memory);
/// @notice Returns whether a specific pair can be supported by the oracle
/// @dev The pair can be provided in tokenA/tokenB or tokenB/tokenA order
/// @return Whether the given pair can be supported by the oracle
function isPairSupported(address tokenA, address tokenB) external view returns (bool);
/// @notice Returns all existing pools for the given pair
/// @dev The pair can be provided in tokenA/tokenB or tokenB/tokenA order
/// @return All existing pools for the given pair
function getAllPoolsForPair(address tokenA, address tokenB) external view returns (address[] memory);
/// @notice Returns a quote, based on the given tokens and amount, by querying all of the pair's pools
/// @dev If some pools are not configured correctly for the given period, then they will be ignored
/// @dev Will revert if there are no pools available/configured for the pair and period combination
/// @param baseAmount Amount of token to be converted
/// @param baseToken Address of an ERC20 token contract used as the baseAmount denomination
/// @param quoteToken Address of an ERC20 token contract used as the quoteAmount denomination
/// @param period Number of seconds from which to calculate the TWAP
/// @return quoteAmount Amount of quoteToken received for baseAmount of baseToken
/// @return queriedPools The pools that were queried to calculate the quote
function quoteAllAvailablePoolsWithTimePeriod(
uint128 baseAmount,
address baseToken,
address quoteToken,
uint32 period
) external view returns (uint256 quoteAmount, address[] memory queriedPools);
/// @notice Returns a quote, based on the given tokens and amount, by querying only the specified fee tiers
/// @dev Will revert if the pair does not have a pool for one of the given fee tiers, or if one of the pools
/// is not prepared/configured correctly for the given period
/// @param baseAmount Amount of token to be converted
/// @param baseToken Address of an ERC20 token contract used as the baseAmount denomination
/// @param quoteToken Address of an ERC20 token contract used as the quoteAmount denomination
/// @param feeTiers The fee tiers to consider when calculating the quote
/// @param period Number of seconds from which to calculate the TWAP
/// @return quoteAmount Amount of quoteToken received for baseAmount of baseToken
/// @return queriedPools The pools that were queried to calculate the quote
function quoteSpecificFeeTiersWithTimePeriod(
uint128 baseAmount,
address baseToken,
address quoteToken,
uint24[] calldata feeTiers,
uint32 period
) external view returns (uint256 quoteAmount, address[] memory queriedPools);
/// @notice Returns a quote, based on the given tokens and amount, by querying only the specified pools
/// @dev Will revert if one of the pools is not prepared/configured correctly for the given period
/// @param baseAmount Amount of token to be converted
/// @param baseToken Address of an ERC20 token contract used as the baseAmount denomination
/// @param quoteToken Address of an ERC20 token contract used as the quoteAmount denomination
/// @param pools The pools to consider when calculating the quote
/// @param period Number of seconds from which to calculate the TWAP
/// @return quoteAmount Amount of quoteToken received for baseAmount of baseToken
function quoteSpecificPoolsWithTimePeriod(
uint128 baseAmount,
address baseToken,
address quoteToken,
address[] calldata pools,
uint32 period
) external view returns (uint256 quoteAmount);
/// @notice Will initialize all existing pools for the given pair, so that they can be queried with the given period in the future
/// @dev Will revert if there are no pools available for the pair and period combination
/// @param tokenA One of the pair's tokens
/// @param tokenB The other of the pair's tokens
/// @param period The period that will be guaranteed when quoting
/// @return preparedPools The pools that were prepared
function prepareAllAvailablePoolsWithTimePeriod(
address tokenA,
address tokenB,
uint32 period
) external returns (address[] memory preparedPools);
/// @notice Will initialize the pair's pools with the specified fee tiers, so that they can be queried with the given period in the future
/// @dev Will revert if the pair does not have a pool for a given fee tier
/// @param tokenA One of the pair's tokens
/// @param tokenB The other of the pair's tokens
/// @param feeTiers The fee tiers to consider when searching for the pair's pools
/// @param period The period that will be guaranteed when quoting
/// @return preparedPools The pools that were prepared
function prepareSpecificFeeTiersWithTimePeriod(
address tokenA,
address tokenB,
uint24[] calldata feeTiers,
uint32 period
) external returns (address[] memory preparedPools);
/// @notice Will initialize all given pools, so that they can be queried with the given period in the future
/// @param pools The pools to initialize
/// @param period The period that will be guaranteed when quoting
function prepareSpecificPoolsWithTimePeriod(address[] calldata pools, uint32 period) external;
/// @notice Will increase observations for all existing pools for the given pair, so they start accruing information for twap calculations
/// @dev Will revert if there are no pools available for the pair and period combination
/// @param tokenA One of the pair's tokens
/// @param tokenB The other of the pair's tokens
/// @param cardinality The cardinality that will be guaranteed when quoting
/// @return preparedPools The pools that were prepared
function prepareAllAvailablePoolsWithCardinality(
address tokenA,
address tokenB,
uint16 cardinality
) external returns (address[] memory preparedPools);
/// @notice Will increase the pair's pools with the specified fee tiers observations, so they start accruing information for twap calculations
/// @dev Will revert if the pair does not have a pool for a given fee tier
/// @param tokenA One of the pair's tokens
/// @param tokenB The other of the pair's tokens
/// @param feeTiers The fee tiers to consider when searching for the pair's pools
/// @param cardinality The cardinality that will be guaranteed when quoting
/// @return preparedPools The pools that were prepared
function prepareSpecificFeeTiersWithCardinality(
address tokenA,
address tokenB,
uint24[] calldata feeTiers,
uint16 cardinality
) external returns (address[] memory preparedPools);
/// @notice Will increase all given pools observations, so they start accruing information for twap calculations
/// @param pools The pools to initialize
/// @param cardinality The cardinality that will be guaranteed when quoting
function prepareSpecificPoolsWithCardinality(address[] calldata pools, uint16 cardinality) external;
/// @notice Adds support for a new fee tier
/// @dev Will revert if the given tier is invalid, or already supported
/// @param feeTier The new fee tier to add
function addNewFeeTier(uint24 feeTier) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)
pragma solidity ^0.8.0;
import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
/**
* @dev Storage based implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165Storage is ERC165 {
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface IUniswapV3SingleTwapOracle is IERC165 {
event SetTwapDuration(uint256 oldTwapDuration, uint256 newTwapDuration);
function TWAP_PRECISION() external view returns (uint128);
function UNISWAP_V3_TWAP_BASE_TOKEN() external view returns (address);
function UNISWAP_V3_TWAP_QUOTE_TOKEN() external view returns (address);
function UNI_V3_PAIR_ADDRESS() external view returns (address);
function getUniswapV3Twap() external view returns (uint256 _twap);
function twapDuration() external view returns (uint32);
function setTwapDuration(uint32 _newTwapDuration) external;
}// 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);
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: UNLICENSED
pragma solidity 0.8.20;
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface IChainlinkOracleWithMaxDelay is IERC165 {
event SetMaximumOracleDelay(address oracle, uint256 oldMaxOracleDelay, uint256 newMaxOracleDelay);
function CHAINLINK_FEED_ADDRESS() external view returns (address);
function CHAINLINK_FEED_DECIMALS() external view returns (uint8);
function CHAINLINK_FEED_PRECISION() external view returns (uint256);
function getChainlinkPrice() external view returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth);
function maximumOracleDelay() external view returns (uint256);
function setMaximumOracleDelay(uint256 _newMaxOracleDelay) external;
}// SPDX-License-Identifier: UNLICENSED
pragma solidity 0.8.20;
import { IERC165 } from "@openzeppelin/contracts/utils/introspection/IERC165.sol";
interface IEthUsdChainlinkOracleWithMaxDelay is IERC165 {
event SetMaximumEthUsdOracleDelay(uint256 oldMaxOracleDelay, uint256 newMaxOracleDelay);
function ETH_USD_CHAINLINK_FEED_ADDRESS() external view returns (address);
function ETH_USD_CHAINLINK_FEED_DECIMALS() external view returns (uint8);
function ETH_USD_CHAINLINK_FEED_PRECISION() external view returns (uint256);
function maximumEthUsdOracleDelay() external view returns (uint256);
function getEthUsdChainlinkPrice() external view returns (bool _isBadData, uint256 _updatedAt, uint256 _usdPerEth);
function setMaximumEthUsdOracleDelay(uint256 _newMaxOracleDelay) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)
pragma solidity ^0.8.20;
import {IERC20} from "../IERC20.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*/
interface IERC20Metadata is IERC20 {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.0;
import { IUniswapV2Pair } from "@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol";
/// @dev Fraxswap LP Pair Interface
interface IFraxswapPair is IUniswapV2Pair {
// TWAMM
struct TWAPObservation {
uint256 timestamp;
uint256 price0CumulativeLast;
uint256 price1CumulativeLast;
}
function TWAPObservationHistory(uint256 index) external view returns (TWAPObservation memory);
event LongTermSwap0To1(address indexed addr, uint256 orderId, uint256 amount0In, uint256 numberOfTimeIntervals);
event LongTermSwap1To0(address indexed addr, uint256 orderId, uint256 amount1In, uint256 numberOfTimeIntervals);
event CancelLongTermOrder(
address indexed addr,
uint256 orderId,
address sellToken,
uint256 unsoldAmount,
address buyToken,
uint256 purchasedAmount
);
event WithdrawProceedsFromLongTermOrder(
address indexed addr,
uint256 orderId,
address indexed proceedToken,
uint256 proceeds,
bool orderExpired
);
function fee() external view returns (uint256);
function longTermSwapFrom0To1(uint256 amount0In, uint256 numberOfTimeIntervals) external returns (uint256 orderId);
function longTermSwapFrom1To0(uint256 amount1In, uint256 numberOfTimeIntervals) external returns (uint256 orderId);
function cancelLongTermSwap(uint256 orderId) external;
function withdrawProceedsFromLongTermSwap(
uint256 orderId
) external returns (bool is_expired, address rewardTkn, uint256 totalReward);
function executeVirtualOrders(uint256 blockTimestamp) external;
function getAmountOut(uint256 amountIn, address tokenIn) external view returns (uint256);
function getAmountIn(uint256 amountOut, address tokenOut) external view returns (uint256);
function orderTimeInterval() external returns (uint256);
function getTWAPHistoryLength() external view returns (uint256);
function getTwammReserves()
external
view
returns (
uint112 _reserve0,
uint112 _reserve1,
uint32 _blockTimestampLast,
uint112 _twammReserve0,
uint112 _twammReserve1,
uint256 _fee
);
function getReserveAfterTwamm(
uint256 blockTimestamp
)
external
view
returns (
uint112 _reserve0,
uint112 _reserve1,
uint256 lastVirtualOrderTimestamp,
uint112 _twammReserve0,
uint112 _twammReserve1
);
function getNextOrderID() external view returns (uint256);
function getOrderIDsForUser(address user) external view returns (uint256[] memory);
function getOrderIDsForUserLength(address user) external view returns (uint256);
function twammUpToDate() external view returns (bool);
function getTwammState()
external
view
returns (
uint256 token0Rate,
uint256 token1Rate,
uint256 lastVirtualOrderTimestamp,
uint256 orderTimeInterval_rtn,
uint256 rewardFactorPool0,
uint256 rewardFactorPool1
);
function getTwammSalesRateEnding(
uint256 _blockTimestamp
) external view returns (uint256 orderPool0SalesRateEnding, uint256 orderPool1SalesRateEnding);
function getTwammRewardFactor(
uint256 _blockTimestamp
) external view returns (uint256 rewardFactorPool0AtTimestamp, uint256 rewardFactorPool1AtTimestamp);
function getTwammOrder(
uint256 orderId
)
external
view
returns (
uint256 id,
uint256 creationTimestamp,
uint256 expirationTimestamp,
uint256 saleRate,
address owner,
address sellTokenAddr,
address buyTokenAddr
);
function getTwammOrderProceedsView(
uint256 orderId,
uint256 blockTimestamp
) external view returns (bool orderExpired, uint256 totalReward);
function getTwammOrderProceeds(uint256 orderId) external returns (bool orderExpired, uint256 totalReward);
function togglePauseNewSwaps() external;
}// SPDX-License-Identifier: ISC
pragma solidity >=0.8.0;
// File contracts/Fraxswap/core/libraries/UQ112x112.sol
// a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
// range: [0, 2**112 - 1]
// resolution: 1 / 2**112
library UQ112x112 {
uint224 constant Q112 = 2 ** 112;
// encode a uint112 as a UQ112x112
function encode(uint112 y) internal pure returns (uint224 z) {
z = uint224(y) * Q112; // never overflows
}
// divide a UQ112x112 by a uint112, returning a UQ112x112
function uqdiv(uint224 x, uint112 y) internal pure returns (uint224 z) {
z = x / uint224(y);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}// SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity >=0.5.0;
/// @title The interface for the Uniswap V3 Factory
/// @notice The Uniswap V3 Factory facilitates creation of Uniswap V3 pools and control over the protocol fees
interface IUniswapV3Factory {
/// @notice Emitted when the owner of the factory is changed
/// @param oldOwner The owner before the owner was changed
/// @param newOwner The owner after the owner was changed
event OwnerChanged(address indexed oldOwner, address indexed newOwner);
/// @notice Emitted when a pool is created
/// @param token0 The first token of the pool by address sort order
/// @param token1 The second token of the pool by address sort order
/// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip
/// @param tickSpacing The minimum number of ticks between initialized ticks
/// @param pool The address of the created pool
event PoolCreated(
address indexed token0,
address indexed token1,
uint24 indexed fee,
int24 tickSpacing,
address pool
);
/// @notice Emitted when a new fee amount is enabled for pool creation via the factory
/// @param fee The enabled fee, denominated in hundredths of a bip
/// @param tickSpacing The minimum number of ticks between initialized ticks for pools created with the given fee
event FeeAmountEnabled(uint24 indexed fee, int24 indexed tickSpacing);
/// @notice Returns the current owner of the factory
/// @dev Can be changed by the current owner via setOwner
/// @return The address of the factory owner
function owner() external view returns (address);
/// @notice Returns the tick spacing for a given fee amount, if enabled, or 0 if not enabled
/// @dev A fee amount can never be removed, so this value should be hard coded or cached in the calling context
/// @param fee The enabled fee, denominated in hundredths of a bip. Returns 0 in case of unenabled fee
/// @return The tick spacing
function feeAmountTickSpacing(uint24 fee) external view returns (int24);
/// @notice Returns the pool address for a given pair of tokens and a fee, or address 0 if it does not exist
/// @dev tokenA and tokenB may be passed in either token0/token1 or token1/token0 order
/// @param tokenA The contract address of either token0 or token1
/// @param tokenB The contract address of the other token
/// @param fee The fee collected upon every swap in the pool, denominated in hundredths of a bip
/// @return pool The pool address
function getPool(
address tokenA,
address tokenB,
uint24 fee
) external view returns (address pool);
/// @notice Creates a pool for the given two tokens and fee
/// @param tokenA One of the two tokens in the desired pool
/// @param tokenB The other of the two tokens in the desired pool
/// @param fee The desired fee for the pool
/// @dev tokenA and tokenB may be passed in either order: token0/token1 or token1/token0. tickSpacing is retrieved
/// from the fee. The call will revert if the pool already exists, the fee is invalid, or the token arguments
/// are invalid.
/// @return pool The address of the newly created pool
function createPool(
address tokenA,
address tokenB,
uint24 fee
) external returns (address pool);
/// @notice Updates the owner of the factory
/// @dev Must be called by the current owner
/// @param _owner The new owner of the factory
function setOwner(address _owner) external;
/// @notice Enables a fee amount with the given tickSpacing
/// @dev Fee amounts may never be removed once enabled
/// @param fee The fee amount to enable, denominated in hundredths of a bip (i.e. 1e-6)
/// @param tickSpacing The spacing between ticks to be enforced for all pools created with the given fee amount
function enableFeeAmount(uint24 fee, int24 tickSpacing) external;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the value of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the value of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves a `value` amount of 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 value) 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 a `value` amount of tokens 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 value) external returns (bool);
/**
* @dev Moves a `value` amount of tokens from `from` to `to` using the
* allowance mechanism. `value` 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 value) external returns (bool);
}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;
}{
"remappings": [
"ds-test/=node_modules/ds-test/src/",
"forge-std/=node_modules/forge-std/src/",
"frax-std/=node_modules/frax-standard-solidity/src/",
"script/=src/script/",
"src/=src/",
"test/=src/test/",
"interfaces/=src/contracts/interfaces/",
"arbitrum/=node_modules/@arbitrum/",
"rlp/=node_modules/solidity-rlp/contracts/",
"@solmate/=node_modules/@rari-capital/solmate/src/",
"@arbitrum/=node_modules/@arbitrum/",
"@chainlink/=node_modules/@chainlink/",
"@mean-finance/=node_modules/@mean-finance/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@rari-capital/=node_modules/@rari-capital/",
"@uniswap/=node_modules/@uniswap/",
"dev-fraxswap/=node_modules/dev-fraxswap/",
"frax-standard-solidity/=node_modules/frax-standard-solidity/",
"prb-math/=node_modules/prb-math/",
"solidity-bytes-utils/=node_modules/solidity-bytes-utils/",
"solidity-rlp/=node_modules/solidity-rlp/"
],
"optimizer": {
"enabled": true,
"runs": 1000000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "shanghai",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"components":[{"internalType":"address","name":"fraxswapPair","type":"address"},{"internalType":"uint32","name":"twapDuration","type":"uint32"},{"internalType":"address","name":"frxEthErc20","type":"address"},{"internalType":"address","name":"frxEthUsdChainlinkFeed","type":"address"},{"internalType":"uint256","name":"maximumOracleDelay","type":"uint256"},{"internalType":"address","name":"timelockAddress","type":"address"}],"internalType":"struct ConstructorParams","name":"_params","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"OnlyPendingTimelock","type":"error"},{"inputs":[],"name":"OnlyTimelock","type":"error"},{"inputs":[],"name":"PairNotOldEnough","type":"error"},{"inputs":[],"name":"TokenNotInPair","type":"error"},{"inputs":[],"name":"WrongDecimals","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"oldDuration","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"newDuration","type":"uint32"}],"name":"NewTwapDurationSet","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMaxOracleDelay","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMaxOracleDelay","type":"uint256"}],"name":"SetMaximumEthUsdOracleDelay","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferred","type":"event"},{"inputs":[],"name":"BASE_TOKEN_0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_TOKEN_0_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_TOKEN_1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"BASE_TOKEN_1_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_CHAINLINK_FEED_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_CHAINLINK_FEED_DECIMALS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ETH_USD_CHAINLINK_FEED_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FRAXSWAP_BASE_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FRAXSWAP_PAIR","outputs":[{"internalType":"contract IFraxswapPair","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FRAXSWAP_QUOTE_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FRXETH_ERC20","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NORMALIZATION_0","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NORMALIZATION_1","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE_PRECISION","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUOTE_TOKEN_0","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUOTE_TOKEN_0_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUOTE_TOKEN_1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"QUOTE_TOKEN_1_DECIMALS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_getTwapFraxSwapPair","outputs":[{"internalType":"uint256","name":"_basePerQuote","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptTransferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"getEthPerUsdRedStone","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_ethPerUsd","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getEthUsdChainlinkPrice","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_updatedAt","type":"uint256"},{"internalType":"uint256","name":"_usdPerEth","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPrices","outputs":[{"internalType":"bool","name":"_isBadData","type":"bool"},{"internalType":"uint256","name":"_priceLow","type":"uint256"},{"internalType":"uint256","name":"_priceHigh","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getPricesNormalized","outputs":[{"internalType":"bool","name":"_isBadDataNormal","type":"bool"},{"internalType":"uint256","name":"_priceLowNormal","type":"uint256"},{"internalType":"uint256","name":"_priceHighNormal","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maximumEthUsdOracleDelay","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"pendingTimelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newMaxOracleDelay","type":"uint256"}],"name":"setMaximumEthUsdOracleDelay","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint32","name":"_newTwapDuration","type":"uint32"}],"name":"setTwapDurationFraxSwap","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newTimelock","type":"address"}],"name":"transferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"twapDuration","outputs":[{"internalType":"uint32","name":"","type":"uint32"}],"stateMutability":"view","type":"function"}]Contract Creation Code
61026060405234801562000011575f80fd5b506040516200236b3803806200236b8339810160408190526200003491620006c8565b6040805180820182526060808401516001600160a01b0390811683526080808601516020808601919091528551808501875287518416815287870180518516828401528289015163ffffffff168289015287516101008082018a526103488083526012958301868152845189169b84018c905298830186815283880191825260a080850188815295518a1660c080870191825260e08088019a8b529e909a52915160ff9081169182905291518a1690985295518616909a528151871690529551831661012081905297519094166101405292511661016052929390926200011c919062000789565b610180526101605160e05162000133919062000789565b6101a05250600180546001600160a01b0319163317905580516001600160a01b03166101c08190526040808301516004805463ffffffff909216600160a01b0263ffffffff60a01b199092169190911781558151630dfe168160e01b815291515f9392630dfe168192818101926020929091908290030181865afa158015620001be573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001e49190620007b2565b90505f6101c0516001600160a01b031663d21220a76040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000227573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200024d9190620007b2565b905082602001516001600160a01b0316826001600160a01b031603620002bb57600480546020850151600160c01b600164ff0000000160a01b03199092166001600160a01b039182161791909117909155600380546001600160a01b0319169183169190911790556200032c565b82602001516001600160a01b0316816001600160a01b03160362000313576020830151600480546001600160a01b03199081166001600160a01b0393841617909155600380549091169184169190911790556200032c565b604051630c40208b60e01b815260040160405180910390fd5b60056101c0516001600160a01b0316637fa2ee6e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200036e573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620003949190620007d5565b1015620003b4576040516355c21b8960e11b815260040160405180910390fd5b816001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa158015620003f1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620004179190620007ed565b60ff166012146200043b57604051632754761960e01b815260040160405180910390fd5b806001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000478573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200049e9190620007ed565b60ff16601214620004c257604051632754761960e01b815260040160405180910390fd5b505050620004dd6323e2f2e160e11b620005ba60201b60201c565b80516001600160a01b03166101e08190526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa15801562000528573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200054e9190620007ed565b60ff166102008190526200056490600a6200090a565b610220526020015160055560a08101516200057f906200063d565b6200059163415f130360e01b620005ba565b620005a3632fa3fc3160e21b620005ba565b604001516001600160a01b03166102405262000917565b6001600160e01b03198082169003620006195760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319165f908152600260205260409020805460ff19166001179055565b6001546040516001600160a01b038084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3600180546001600160a01b0319166001600160a01b0392909216919091179055565b80516001600160a01b0381168114620006af575f80fd5b919050565b805163ffffffff81168114620006af575f80fd5b5f60c08284031215620006d9575f80fd5b60405160c081016001600160401b03811182821017156200070857634e487b7160e01b5f52604160045260245ffd5b604052620007168362000698565b81526200072660208401620006b4565b6020820152620007396040840162000698565b60408201526200074c6060840162000698565b6060820152608083015160808201526200076960a0840162000698565b60a08201529392505050565b634e487b7160e01b5f52601160045260245ffd5b8181035f831280158383131683831282161715620007ab57620007ab62000775565b5092915050565b5f60208284031215620007c3575f80fd5b620007ce8262000698565b9392505050565b5f60208284031215620007e6575f80fd5b5051919050565b5f60208284031215620007fe575f80fd5b815160ff81168114620007ce575f80fd5b600181815b808511156200084f57815f190482111562000833576200083362000775565b808516156200084157918102915b93841c939080029062000814565b509250929050565b5f82620008675750600162000904565b816200087557505f62000904565b81600181146200088e57600281146200089957620008b9565b600191505062000904565b60ff841115620008ad57620008ad62000775565b50506001821b62000904565b5060208310610133831016604e8410600b8410161715620008de575081810a62000904565b620008ea83836200080f565b805f190482111562000900576200090062000775565b0290505b92915050565b5f620007ce838362000857565b60805160a05160c05160e05161010051610120516101405161016051610180516101a0516101c0516101e05161020051610220516102405161195762000a145f395f61054301525f81816104cc0152610efb01525f6103cf01525f818161056a015261107001525f81816105a001528181610757015281816107fc0152818161089a01528181610a900152610bca01525f818161023d01528181610e1101528181610e3a0152610e7d01525f81816105cf01528181610d7001528181610d990152610ddc01525f6103a801525f61032f01525f61065701525f61030801525f6104f301525f61048501525f61063001525f61060901526119575ff3fe608060405234801561000f575f80fd5b5060043610610234575f3560e01c8063550af47e1161013d5780639c0d313f116100b8578063d736094611610088578063e5a66dfa1161006e578063e5a66dfa1461062b578063f097486c14610652578063f6ccaad414610679575f80fd5b8063d7360946146105f1578063e0d2e78014610604575f80fd5b80639c0d313f1461058c5780639f50f7611461059b578063bd9a548b146105c2578063c82f2b12146105ca575f80fd5b8063781097d01161010d57806388c210f7116100f357806388c210f71461051e57806390e67fe81461053e57806399a64f2814610565575f80fd5b8063781097d0146104ee5780637c99a49914610515575f80fd5b8063550af47e1461046157806359c909e1146104805780635f9a63e4146104a7578063726de1a5146104c7575f80fd5b8063313ce567116101cd57806343aae02d1161019d5780634bc66f32116101835780634bc66f32146104315780634d3375e8146104515780634f8b4ae714610459575f80fd5b806343aae02d14610416578063450140951461041e575f80fd5b8063313ce5671461038e57806337f85f66146103a35780633b17136a146103ca5780633cb6f5fa146103f1575f80fd5b8063090f3f5011610208578063090f3f50146102bf578063116d797614610303578063208880041461032a57806326d8954514610351575f80fd5b806232e91a1461023857806301ffc9a71461027257806306fdde0314610295578063075a194e146102aa575b5f80fd5b61025f7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6102856102803660046113b1565b610681565b6040519015158152602001610269565b61029d610708565b60405161026991906113f0565b6102bd6102b836600461146a565b610728565b005b5f546102de9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610269565b6102de7f000000000000000000000000000000000000000000000000000000000000000081565b6102de7f000000000000000000000000000000000000000000000000000000000000000081565b6004546103799074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610269565b60125b60405160ff9091168152602001610269565b61025f7f000000000000000000000000000000000000000000000000000000000000000081565b6103917f000000000000000000000000000000000000000000000000000000000000000081565b6103f961073c565b604080519315158452602084019290925290820152606001610269565b61025f610753565b6102bd61042c366004611485565b610d45565b6001546102de9073ffffffffffffffffffffffffffffffffffffffff1681565b6103f9610d56565b6102bd610eb7565b610469610edb565b604080519215158352602083019190915201610269565b6102de7f000000000000000000000000000000000000000000000000000000000000000081565b6003546102de9073ffffffffffffffffffffffffffffffffffffffff1681565b61025f7f000000000000000000000000000000000000000000000000000000000000000081565b61025f7f000000000000000000000000000000000000000000000000000000000000000081565b61025f60055481565b6004546102de9073ffffffffffffffffffffffffffffffffffffffff1681565b6102de7f000000000000000000000000000000000000000000000000000000000000000081565b6102de7f000000000000000000000000000000000000000000000000000000000000000081565b61025f670de0b6b3a764000081565b6102de7f000000000000000000000000000000000000000000000000000000000000000081565b6103f9610f36565b61025f7f000000000000000000000000000000000000000000000000000000000000000081565b6102bd6105ff3660046114b8565b610f4c565b6102de7f000000000000000000000000000000000000000000000000000000000000000081565b61025f7f000000000000000000000000000000000000000000000000000000000000000081565b61025f7f000000000000000000000000000000000000000000000000000000000000000081565b6102bd610f5d565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061070257507fffffffff0000000000000000000000000000000000000000000000000000000082165f9081526002602052604090205460ff165b92915050565b606060405180606001604052806022815260200161192960229139905090565b610730610f6d565b61073981610fbe565b50565b5f805f610747611069565b91959094509092509050565b5f807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16637fa2ee6e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107e291906114cf565b90505f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166327e7383661082c600185611513565b6040518263ffffffff1660e01b815260040161084a91815260200190565b606060405180830381865afa158015610865573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108899190611526565b905042815f015110156109f6575f807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610901573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061092591906115c7565b5090925090505f61093b64010000000042611638565b8451909150810363ffffffff811661097a8561095686611126565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690611150565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16028560200181815101915081815250508063ffffffff166109bc8461095687611126565b6040870180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216929092020190525063ffffffff16835250505b610a1760405180606001604052805f81526020015f81526020015f81525090565b6004545f908190610a489060289074010000000000000000000000000000000000000000900463ffffffff1661164b565b63ffffffff1690505b60045474010000000000000000000000000000000000000000900463ffffffff16811015610ba95773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166327e73836610ac083600161166d565b610aca9088611513565b6040518263ffffffff1660e01b8152600401610ae891815260200190565b606060405180830381865afa158015610b03573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b279190611526565b600454815186519295507401000000000000000000000000000000000000000090910463ffffffff1691031015610b6057809150610b65565b610ba9565b600454610b929060149074010000000000000000000000000000000000000000900463ffffffff1661164b565b610ba29063ffffffff168261166d565b9050610a51565b505b83811015610ca35773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000166327e73836610bfa83600161166d565b610c049087611513565b6040518263ffffffff1660e01b8152600401610c2291815260200190565b606060405180830381865afa158015610c3d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c619190611526565b600454815185519294507401000000000000000000000000000000000000000090910463ffffffff16910311610ca35780610c9b81611680565b915050610bab565b6004547801000000000000000000000000000000000000000000000000900460ff1615610d06575f825f0151845f01510363ffffffff16836020015185602001510381610cf257610cf261160b565b049050610cfe81611172565b955050610d3e565b5f825f0151845f01510363ffffffff16836040015185604001510381610d2e57610d2e61160b565b049050610d3a81611172565b9550505b5050505090565b610d4d610f6d565b61073981611184565b5f805f805f80610d646111f8565b9250925092508295505f7f000000000000000000000000000000000000000000000000000000000000000013610dd757610dbd7f00000000000000000000000000000000000000000000000000000000000000006116b7565b610dc890600a61180b565b610dd29083611816565b610e0c565b610e027f0000000000000000000000000000000000000000000000000000000000000000600a61180b565b610e0c9083611829565b94505f7f000000000000000000000000000000000000000000000000000000000000000013610e7857610e5e7f00000000000000000000000000000000000000000000000000000000000000006116b7565b610e6990600a61180b565b610e739082611816565b610ead565b610ea37f0000000000000000000000000000000000000000000000000000000000000000600a61180b565b610ead9082611829565b9350505050909192565b610ebf610f6d565b610ec7611263565b610ed05f611184565b610ed95f6112b3565b565b5f805f80610ee7611069565b925050915081935080670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000000000000610f249190611829565b610f2e9190611816565b925050509091565b5f805f610f416111f8565b925092509250909192565b610f54610f6d565b61073981611340565b610f65611263565b610ed9611381565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ed9576040517f1c0be90a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004546040805163ffffffff740100000000000000000000000000000000000000009093048316815291831660208301527fe99a18add462219d56cbe6eacbd37b6795ea7beb885a903238a2fe939b6dfa24910160405180910390a16004805463ffffffff90921674010000000000000000000000000000000000000000027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b5f805f805f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156110d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110fb9190611859565b509350509250505f8213158061111b57506005546111198242611513565b115b959094509092509050565b5f6107026e0100000000000000000000000000006dffffffffffffffffffffffffffff84166118a5565b5f61116b6dffffffffffffffffffffffffffff8316846118ec565b9392505050565b5f6107026612725dd1d243ab83611816565b5f80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a9190a350565b5f805f805f611205610edb565b915091505f611212610753565b90505f816112296002670de0b6b3a764000061191a565b6112339190611816565b90508396508281106112455782611247565b805b95508083116112565780611258565b825b945050505050909192565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610ed9576040517ff5c49e6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60055460408051918252602082018390527f1b427db70b2e813aae1e9f4dc54fcd2ae904b1350f60b84a7bab7d379aa2b02e910160405180910390a1600555565b5f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055610ed9336112b3565b5f602082840312156113c1575f80fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461116b575f80fd5b5f6020808352835180828501525f5b8181101561141b578581018301518582016040015282016113ff565b505f6040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b63ffffffff81168114610739575f80fd5b5f6020828403121561147a575f80fd5b813561116b81611459565b5f60208284031215611495575f80fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461116b575f80fd5b5f602082840312156114c8575f80fd5b5035919050565b5f602082840312156114df575f80fd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610702576107026114e6565b5f60608284031215611536575f80fd5b6040516060810181811067ffffffffffffffff8211171561157e577f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b80604052508251815260208301516020820152604083015160408201528091505092915050565b80516dffffffffffffffffffffffffffff811681146115c2575f80fd5b919050565b5f805f606084860312156115d9575f80fd5b6115e2846115a5565b92506115f0602085016115a5565b9150604084015161160081611459565b809150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f826116465761164661160b565b500690565b5f63ffffffff808416806116615761166161160b565b92169190910492915050565b80820180821115610702576107026114e6565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036116b0576116b06114e6565b5060010190565b5f7f800000000000000000000000000000000000000000000000000000000000000082036116e7576116e76114e6565b505f0390565b600181815b8085111561174657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561172c5761172c6114e6565b8085161561173957918102915b93841c93908002906116f2565b509250929050565b5f8261175c57506001610702565b8161176857505f610702565b816001811461177e5760028114611788576117a4565b6001915050610702565b60ff841115611799576117996114e6565b50506001821b610702565b5060208310610133831016604e8410600b84101617156117c7575081810a610702565b6117d183836116ed565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611803576118036114e6565b029392505050565b5f61116b838361174e565b5f826118245761182461160b565b500490565b8082028115828204841417610702576107026114e6565b805169ffffffffffffffffffff811681146115c2575f80fd5b5f805f805f60a0868803121561186d575f80fd5b61187686611840565b945060208601519350604086015192506060860151915061189960808701611840565b90509295509295909350565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8281168282168181028316929181158285048214176118e3576118e36114e6565b50505092915050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff808416806116615761166161160b565b5f61116b60ff84168361174e56fe4672784574682052656453746f6e65204475616c204f7261636c65202b2054574150a164736f6c6343000814000a0000000000000000000000004527bced9d41706d1436507e9a6e354d3ff44ff90000000000000000000000000000000000000000000000000000000000000f3c000000000000000000000000fc0000000000000000000000000000000000000600000000000000000000000089e60b56efd70a1d4fbbae947bc33cae41e37a720000000000000000000000000000000000000000000000000000000000000f3c000000000000000000000000c16068d1ca7e24e20e56bb70af4d00d92aa4f0b2
Deployed Bytecode
0x608060405234801561000f575f80fd5b5060043610610234575f3560e01c8063550af47e1161013d5780639c0d313f116100b8578063d736094611610088578063e5a66dfa1161006e578063e5a66dfa1461062b578063f097486c14610652578063f6ccaad414610679575f80fd5b8063d7360946146105f1578063e0d2e78014610604575f80fd5b80639c0d313f1461058c5780639f50f7611461059b578063bd9a548b146105c2578063c82f2b12146105ca575f80fd5b8063781097d01161010d57806388c210f7116100f357806388c210f71461051e57806390e67fe81461053e57806399a64f2814610565575f80fd5b8063781097d0146104ee5780637c99a49914610515575f80fd5b8063550af47e1461046157806359c909e1146104805780635f9a63e4146104a7578063726de1a5146104c7575f80fd5b8063313ce567116101cd57806343aae02d1161019d5780634bc66f32116101835780634bc66f32146104315780634d3375e8146104515780634f8b4ae714610459575f80fd5b806343aae02d14610416578063450140951461041e575f80fd5b8063313ce5671461038e57806337f85f66146103a35780633b17136a146103ca5780633cb6f5fa146103f1575f80fd5b8063090f3f5011610208578063090f3f50146102bf578063116d797614610303578063208880041461032a57806326d8954514610351575f80fd5b806232e91a1461023857806301ffc9a71461027257806306fdde0314610295578063075a194e146102aa575b5f80fd5b61025f7f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6102856102803660046113b1565b610681565b6040519015158152602001610269565b61029d610708565b60405161026991906113f0565b6102bd6102b836600461146a565b610728565b005b5f546102de9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610269565b6102de7f000000000000000000000000000000000000000000000000000000000000034881565b6102de7f000000000000000000000000000000000000000000000000000000000000034881565b6004546103799074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff9091168152602001610269565b60125b60405160ff9091168152602001610269565b61025f7f000000000000000000000000000000000000000000000000000000000000001281565b6103917f000000000000000000000000000000000000000000000000000000000000000881565b6103f961073c565b604080519315158452602084019290925290820152606001610269565b61025f610753565b6102bd61042c366004611485565b610d45565b6001546102de9073ffffffffffffffffffffffffffffffffffffffff1681565b6103f9610d56565b6102bd610eb7565b610469610edb565b604080519215158352602083019190915201610269565b6102de7f000000000000000000000000fc0000000000000000000000000000000000000681565b6003546102de9073ffffffffffffffffffffffffffffffffffffffff1681565b61025f7f0000000000000000000000000000000000000000000000000000000005f5e10081565b61025f7f000000000000000000000000000000000000000000000000000000000000001281565b61025f60055481565b6004546102de9073ffffffffffffffffffffffffffffffffffffffff1681565b6102de7f000000000000000000000000fc0000000000000000000000000000000000000681565b6102de7f00000000000000000000000089e60b56efd70a1d4fbbae947bc33cae41e37a7281565b61025f670de0b6b3a764000081565b6102de7f0000000000000000000000004527bced9d41706d1436507e9a6e354d3ff44ff981565b6103f9610f36565b61025f7f000000000000000000000000000000000000000000000000000000000000000081565b6102bd6105ff3660046114b8565b610f4c565b6102de7f000000000000000000000000fc0000000000000000000000000000000000000681565b61025f7f000000000000000000000000000000000000000000000000000000000000001281565b61025f7f000000000000000000000000000000000000000000000000000000000000001281565b6102bd610f5d565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061070257507fffffffff0000000000000000000000000000000000000000000000000000000082165f9081526002602052604090205460ff165b92915050565b606060405180606001604052806022815260200161192960229139905090565b610730610f6d565b61073981610fbe565b50565b5f805f610747611069565b91959094509092509050565b5f807f0000000000000000000000004527bced9d41706d1436507e9a6e354d3ff44ff973ffffffffffffffffffffffffffffffffffffffff16637fa2ee6e6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156107be573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906107e291906114cf565b90505f73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004527bced9d41706d1436507e9a6e354d3ff44ff9166327e7383661082c600185611513565b6040518263ffffffff1660e01b815260040161084a91815260200190565b606060405180830381865afa158015610865573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906108899190611526565b905042815f015110156109f6575f807f0000000000000000000000004527bced9d41706d1436507e9a6e354d3ff44ff973ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa158015610901573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061092591906115c7565b5090925090505f61093b64010000000042611638565b8451909150810363ffffffff811661097a8561095686611126565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1690611150565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff16028560200181815101915081815250508063ffffffff166109bc8461095687611126565b6040870180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff92909216929092020190525063ffffffff16835250505b610a1760405180606001604052805f81526020015f81526020015f81525090565b6004545f908190610a489060289074010000000000000000000000000000000000000000900463ffffffff1661164b565b63ffffffff1690505b60045474010000000000000000000000000000000000000000900463ffffffff16811015610ba95773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004527bced9d41706d1436507e9a6e354d3ff44ff9166327e73836610ac083600161166d565b610aca9088611513565b6040518263ffffffff1660e01b8152600401610ae891815260200190565b606060405180830381865afa158015610b03573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610b279190611526565b600454815186519295507401000000000000000000000000000000000000000090910463ffffffff1691031015610b6057809150610b65565b610ba9565b600454610b929060149074010000000000000000000000000000000000000000900463ffffffff1661164b565b610ba29063ffffffff168261166d565b9050610a51565b505b83811015610ca35773ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000004527bced9d41706d1436507e9a6e354d3ff44ff9166327e73836610bfa83600161166d565b610c049087611513565b6040518263ffffffff1660e01b8152600401610c2291815260200190565b606060405180830381865afa158015610c3d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610c619190611526565b600454815185519294507401000000000000000000000000000000000000000090910463ffffffff16910311610ca35780610c9b81611680565b915050610bab565b6004547801000000000000000000000000000000000000000000000000900460ff1615610d06575f825f0151845f01510363ffffffff16836020015185602001510381610cf257610cf261160b565b049050610cfe81611172565b955050610d3e565b5f825f0151845f01510363ffffffff16836040015185604001510381610d2e57610d2e61160b565b049050610d3a81611172565b9550505b5050505090565b610d4d610f6d565b61073981611184565b5f805f805f80610d646111f8565b9250925092508295505f7f000000000000000000000000000000000000000000000000000000000000000013610dd757610dbd7f00000000000000000000000000000000000000000000000000000000000000006116b7565b610dc890600a61180b565b610dd29083611816565b610e0c565b610e027f0000000000000000000000000000000000000000000000000000000000000000600a61180b565b610e0c9083611829565b94505f7f000000000000000000000000000000000000000000000000000000000000000013610e7857610e5e7f00000000000000000000000000000000000000000000000000000000000000006116b7565b610e6990600a61180b565b610e739082611816565b610ead565b610ea37f0000000000000000000000000000000000000000000000000000000000000000600a61180b565b610ead9082611829565b9350505050909192565b610ebf610f6d565b610ec7611263565b610ed05f611184565b610ed95f6112b3565b565b5f805f80610ee7611069565b925050915081935080670de0b6b3a76400007f0000000000000000000000000000000000000000000000000000000005f5e100610f249190611829565b610f2e9190611816565b925050509091565b5f805f610f416111f8565b925092509250909192565b610f54610f6d565b61073981611340565b610f65611263565b610ed9611381565b60015473ffffffffffffffffffffffffffffffffffffffff163314610ed9576040517f1c0be90a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6004546040805163ffffffff740100000000000000000000000000000000000000009093048316815291831660208301527fe99a18add462219d56cbe6eacbd37b6795ea7beb885a903238a2fe939b6dfa24910160405180910390a16004805463ffffffff90921674010000000000000000000000000000000000000000027fffffffffffffffff00000000ffffffffffffffffffffffffffffffffffffffff909216919091179055565b5f805f805f7f00000000000000000000000089e60b56efd70a1d4fbbae947bc33cae41e37a7273ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa1580156110d7573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906110fb9190611859565b509350509250505f8213158061111b57506005546111198242611513565b115b959094509092509050565b5f6107026e0100000000000000000000000000006dffffffffffffffffffffffffffff84166118a5565b5f61116b6dffffffffffffffffffffffffffff8316846118ec565b9392505050565b5f6107026612725dd1d243ab83611816565b5f80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217835560015460405192939116917f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a9190a350565b5f805f805f611205610edb565b915091505f611212610753565b90505f816112296002670de0b6b3a764000061191a565b6112339190611816565b90508396508281106112455782611247565b805b95508083116112565780611258565b825b945050505050909192565b5f5473ffffffffffffffffffffffffffffffffffffffff163314610ed9576040517ff5c49e6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b60055460408051918252602082018390527f1b427db70b2e813aae1e9f4dc54fcd2ae904b1350f60b84a7bab7d379aa2b02e910160405180910390a1600555565b5f80547fffffffffffffffffffffffff0000000000000000000000000000000000000000169055610ed9336112b3565b5f602082840312156113c1575f80fd5b81357fffffffff000000000000000000000000000000000000000000000000000000008116811461116b575f80fd5b5f6020808352835180828501525f5b8181101561141b578581018301518582016040015282016113ff565b505f6040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b63ffffffff81168114610739575f80fd5b5f6020828403121561147a575f80fd5b813561116b81611459565b5f60208284031215611495575f80fd5b813573ffffffffffffffffffffffffffffffffffffffff8116811461116b575f80fd5b5f602082840312156114c8575f80fd5b5035919050565b5f602082840312156114df575f80fd5b5051919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b81810381811115610702576107026114e6565b5f60608284031215611536575f80fd5b6040516060810181811067ffffffffffffffff8211171561157e577f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b80604052508251815260208301516020820152604083015160408201528091505092915050565b80516dffffffffffffffffffffffffffff811681146115c2575f80fd5b919050565b5f805f606084860312156115d9575f80fd5b6115e2846115a5565b92506115f0602085016115a5565b9150604084015161160081611459565b809150509250925092565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f826116465761164661160b565b500690565b5f63ffffffff808416806116615761166161160b565b92169190910492915050565b80820180821115610702576107026114e6565b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036116b0576116b06114e6565b5060010190565b5f7f800000000000000000000000000000000000000000000000000000000000000082036116e7576116e76114e6565b505f0390565b600181815b8085111561174657817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561172c5761172c6114e6565b8085161561173957918102915b93841c93908002906116f2565b509250929050565b5f8261175c57506001610702565b8161176857505f610702565b816001811461177e5760028114611788576117a4565b6001915050610702565b60ff841115611799576117996114e6565b50506001821b610702565b5060208310610133831016604e8410600b84101617156117c7575081810a610702565b6117d183836116ed565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115611803576118036114e6565b029392505050565b5f61116b838361174e565b5f826118245761182461160b565b500490565b8082028115828204841417610702576107026114e6565b805169ffffffffffffffffffff811681146115c2575f80fd5b5f805f805f60a0868803121561186d575f80fd5b61187686611840565b945060208601519350604086015192506060860151915061189960808701611840565b90509295509295909350565b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8281168282168181028316929181158285048214176118e3576118e36114e6565b50505092915050565b5f7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff808416806116615761166161160b565b5f61116b60ff84168361174e56fe4672784574682052656453746f6e65204475616c204f7261636c65202b2054574150a164736f6c6343000814000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004527bced9d41706d1436507e9a6e354d3ff44ff90000000000000000000000000000000000000000000000000000000000000f3c000000000000000000000000fc0000000000000000000000000000000000000600000000000000000000000089e60b56efd70a1d4fbbae947bc33cae41e37a720000000000000000000000000000000000000000000000000000000000000f3c000000000000000000000000c16068d1ca7e24e20e56bb70af4d00d92aa4f0b2
-----Decoded View---------------
Arg [0] : _params (tuple):
Arg [1] : fraxswapPair (address): 0x4527bcEd9d41706D1436507e9a6e354d3FF44ff9
Arg [2] : twapDuration (uint32): 3900
Arg [3] : frxEthErc20 (address): 0xFC00000000000000000000000000000000000006
Arg [4] : frxEthUsdChainlinkFeed (address): 0x89e60b56efD70a1D4FBBaE947bC33cae41e37A72
Arg [5] : maximumOracleDelay (uint256): 3900
Arg [6] : timelockAddress (address): 0xc16068d1ca7E24E20e56bB70af4D00D92AA4f0b2
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000004527bced9d41706d1436507e9a6e354d3ff44ff9
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000f3c
Arg [2] : 000000000000000000000000fc00000000000000000000000000000000000006
Arg [3] : 00000000000000000000000089e60b56efd70a1d4fbbae947bc33cae41e37a72
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000f3c
Arg [5] : 000000000000000000000000c16068d1ca7e24e20e56bb70af4d00d92aa4f0b2
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.