Overview
ETH Balance
0 ETH
Eth Value
$0.00More Info
Private Name Tags
ContractCreator
View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Contract Name:
FeedSwitch
Compiler Version
v0.8.20+commit.a1b79de6
Optimization Enabled:
Yes with 10000 runs
Other Settings:
shanghai EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.18; import "src/interfaces/IChainlinkFeed.sol"; interface IPendlePT { function expiry() external view returns (uint256); } /// @title FeedSwitch for Pendle PT tokens /// @notice A contract to switch between feeds after a timelock period /// @dev The switch can only be initiated by the guardian and will be effective after the timelock period has passed, can only be done before maturity. /// If the switch is initiated but not yet effective, it can be cancelled by the guardian without timelock period. /// The feed will default to the afterMaturityFeed if the maturity has passed. /// The guardian can initiate the switch again to the previous feed multiple times. contract FeedSwitch { error NotGuardian(); error FeedDecimalsMismatch(); error MaturityInPast(); error MaturityPassed(); address public immutable guardian; IChainlinkFeed public immutable initialFeed; IChainlinkFeed public immutable beforeMaturityFeed; IChainlinkFeed public immutable afterMaturityFeed; uint256 public immutable maturity; uint256 public immutable timelockPeriod; IChainlinkFeed public feed; IChainlinkFeed public previousFeed; uint256 public switchCompletedAt; event FeedSwitchInitiated(address indexed newFeed); constructor( address _feed, address _beforeMaturityFeed, address _afterMaturityFeed, uint256 _timelockPeriod, address _pendlePT, address _guardian ) { feed = IChainlinkFeed(_feed); initialFeed = IChainlinkFeed(_feed); beforeMaturityFeed = IChainlinkFeed(_beforeMaturityFeed); afterMaturityFeed = IChainlinkFeed(_afterMaturityFeed); if ( beforeMaturityFeed.decimals() != 18 || afterMaturityFeed.decimals() != 18 || feed.decimals() != 18 ) revert FeedDecimalsMismatch(); timelockPeriod = _timelockPeriod; maturity = IPendlePT(_pendlePT).expiry(); if (maturity <= block.timestamp) revert MaturityInPast(); guardian = _guardian; } /// @notice Initiate the feed switch, entering the timelock period /// @dev Can only be called by the guardian and can be done before maturity, after that, the feed will return afterMaturityFeed data function initiateFeedSwitch() external { if (msg.sender != guardian) revert NotGuardian(); if (block.timestamp >= maturity) revert MaturityPassed(); if (switchCompletedAt < block.timestamp) { switchCompletedAt = block.timestamp + timelockPeriod; } else switchCompletedAt = 0; if (address(feed) == address(initialFeed)) { feed = beforeMaturityFeed; previousFeed = initialFeed; } else { feed = initialFeed; previousFeed = beforeMaturityFeed; } emit FeedSwitchInitiated(address(feed)); } /// @notice Get the current feed data /// @return roundId The round ID /// @return price The price of the asset /// @return startedAt The timestamp of the start of the round /// @return updatedAt The timestamp of the last update /// @return answeredInRound The round ID in which the price was answered function latestRoundData() public view returns ( uint80 roundId, int256 price, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ) { if (block.timestamp >= maturity) { return afterMaturityFeed.latestRoundData(); } else if (block.timestamp >= switchCompletedAt) { return feed.latestRoundData(); } else { return previousFeed.latestRoundData(); } } /// @notice Get the latest price of the asset /// @return price The price of the asset function latestAnswer() external view returns (int256) { (, int256 latestPrice, , , ) = latestRoundData(); return latestPrice; } /// @notice Get the number of decimals of the feed /// @return decimals The number of decimals function decimals() external pure returns (uint8) { return 18; } /// @notice Check if the feed switch is queued /// @dev If not queued, will return false and 0 as time left /// @return isQueued Whether the feed switch is queued /// @return timeLeft The time left for the switch to be effective function isFeedSwitchQueued() external view returns (bool, uint256) { bool isQueued = switchCompletedAt > 0 && block.timestamp < switchCompletedAt; if (!isQueued) return (false, 0); else return (isQueued, switchCompletedAt - block.timestamp); } }
pragma solidity ^0.8.13; interface IChainlinkFeed { function aggregator() external view returns (address aggregator); function decimals() external view returns (uint8 decimals); function latestRoundData() external view returns ( uint80 roundId, int256 crvUsdPrice, uint256 startedAt, uint256 updatedAt, uint80 answeredInRound ); function latestAnswer() external view returns (int256 price); function description() external view returns (string memory description); } interface IChainlinkBasePriceFeed is IChainlinkFeed { function assetToUsd() external view returns (IChainlinkFeed); function assetToUsdFallback() external view returns (IChainlinkFeed); function assetToUsdHeartbeat() external view returns (uint256 heartbeat); }
{ "remappings": [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "solmate/=lib/solmate/src/", "halmos-cheatcodes/=lib/openzeppelin-contracts/lib/halmos-cheatcodes/src/" ], "optimizer": { "enabled": true, "runs": 10000 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "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
[{"inputs":[{"internalType":"address","name":"_feed","type":"address"},{"internalType":"address","name":"_beforeMaturityFeed","type":"address"},{"internalType":"address","name":"_afterMaturityFeed","type":"address"},{"internalType":"uint256","name":"_timelockPeriod","type":"uint256"},{"internalType":"address","name":"_pendlePT","type":"address"},{"internalType":"address","name":"_guardian","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"FeedDecimalsMismatch","type":"error"},{"inputs":[],"name":"MaturityInPast","type":"error"},{"inputs":[],"name":"MaturityPassed","type":"error"},{"inputs":[],"name":"NotGuardian","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newFeed","type":"address"}],"name":"FeedSwitchInitiated","type":"event"},{"inputs":[],"name":"afterMaturityFeed","outputs":[{"internalType":"contract IChainlinkFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"beforeMaturityFeed","outputs":[{"internalType":"contract IChainlinkFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"feed","outputs":[{"internalType":"contract IChainlinkFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"guardian","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialFeed","outputs":[{"internalType":"contract IChainlinkFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initiateFeedSwitch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isFeedSwitchQueued","outputs":[{"internalType":"bool","name":"","type":"bool"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestAnswer","outputs":[{"internalType":"int256","name":"","type":"int256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"latestRoundData","outputs":[{"internalType":"uint80","name":"roundId","type":"uint80"},{"internalType":"int256","name":"price","type":"int256"},{"internalType":"uint256","name":"startedAt","type":"uint256"},{"internalType":"uint256","name":"updatedAt","type":"uint256"},{"internalType":"uint80","name":"answeredInRound","type":"uint80"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maturity","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"previousFeed","outputs":[{"internalType":"contract IChainlinkFeed","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"switchCompletedAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelockPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
61014060405234801562000011575f80fd5b5060405162000c6f38038062000c6f8339810160408190526200003491620002a7565b5f80546001600160a01b0319166001600160a01b0388811691821790925560a05285811660c081905290851660e0526040805163313ce56760e01b8152905163313ce567916004808201926020929091908290030181865afa1580156200009d573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620000c391906200031b565b60ff1660121415806200013e575060e0516001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000110573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200013691906200031b565b60ff16601214155b80620001c257505f8054906101000a90046001600160a01b03166001600160a01b031663313ce5676040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000194573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190620001ba91906200031b565b60ff16601214155b15620001e1576040516329a2a3af60e11b815260040160405180910390fd5b826101208181525050816001600160a01b031663e184c9be6040518163ffffffff1660e01b8152600401602060405180830381865afa15801562000227573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906200024d919062000344565b61010081905242106200027357604051631c38546760e01b815260040160405180910390fd5b6001600160a01b0316608052506200035c9350505050565b80516001600160a01b0381168114620002a2575f80fd5b919050565b5f805f805f8060c08789031215620002bd575f80fd5b620002c8876200028b565b9550620002d8602088016200028b565b9450620002e8604088016200028b565b935060608701519250620002ff608088016200028b565b91506200030f60a088016200028b565b90509295509295509295565b5f602082840312156200032c575f80fd5b815160ff811681146200033d575f80fd5b9392505050565b5f6020828403121562000355575f80fd5b5051919050565b60805160a05160c05160e0516101005161012051610886620003e95f395f818161012801526103fc01525f818160ee0152818161039601526105ea01525f818161024a015261061101525f818161027101528181610489015261057201525f81816101d101528181610447015281816104d8015261052301525f81816101a2015261033d01526108865ff3fe608060405234801561000f575f80fd5b50600436106100e5575f3560e01c8063668c50c511610088578063c6a304e711610063578063c6a304e71461023b578063d04f955114610245578063ea36a8eb1461026c578063feaf968c14610293575f80fd5b8063668c50c5146101f35780637e8de5ba14610212578063c0e6547814610232575f80fd5b806337a7b7d8116100c357806337a7b7d814610159578063452a93201461019d57806350d25bcd146101c457806363dab52f146101cc575f80fd5b8063204f83f9146100e95780632ecaf67514610123578063313ce5671461014a575b5f80fd5b6101107f000000000000000000000000000000000000000000000000000000000000000081565b6040519081526020015b60405180910390f35b6101107f000000000000000000000000000000000000000000000000000000000000000081565b6040516012815260200161011a565b5f546101789073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b6101787f000000000000000000000000000000000000000000000000000000000000000081565b6101106102d2565b6101787f000000000000000000000000000000000000000000000000000000000000000081565b6101fb6102e7565b60408051921515835260208301919091520161011a565b6001546101789073ffffffffffffffffffffffffffffffffffffffff1681565b61011060025481565b610243610325565b005b6101787f000000000000000000000000000000000000000000000000000000000000000081565b6101787f000000000000000000000000000000000000000000000000000000000000000081565b61029b6105e3565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161011a565b5f806102dc6105e3565b509195945050505050565b5f805f806002541180156102fc575060025442105b90508061030d57505f928392509050565b804260025461031c91906107ba565b92509250509091565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610394576040517fef6d0f0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000042106103ed576040517fdaa3fecb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002541015610429576104217f0000000000000000000000000000000000000000000000000000000000000000426107d3565b60025561042e565b5f6002555b5f5473ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000008116911603610509575f805473ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255600180547f00000000000000000000000000000000000000000000000000000000000000009093169290911691909117905561059f565b5f805473ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255600180547f0000000000000000000000000000000000000000000000000000000000000000909316929091169190911790555b5f805460405173ffffffffffffffffffffffffffffffffffffffff909116917f6da4629aa3ee6cfa8775a91874378314cd37320bd79b5389bfd2ebcc67f5fc9c91a2565b5f805f805f7f000000000000000000000000000000000000000000000000000000000000000042106106ab577f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610678573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061069c9190610804565b94509450945094509450610786565b600254421061071c575f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610678573d5f803e3d5ffd5b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610678573d5f803e3d5ffd5b9091929394565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b818103818111156107cd576107cd61078d565b92915050565b808201808211156107cd576107cd61078d565b805169ffffffffffffffffffff811681146107ff575f80fd5b919050565b5f805f805f60a08688031215610818575f80fd5b610821866107e6565b9450602086015193506040860151925060608601519150610844608087016107e6565b9050929550929590935056fea2646970667358221220f779c15bd7421c383812b63198139e6ea8c9b11ad454094a8ca014b0487d36b064736f6c634300081400330000000000000000000000005cb542eb054f81b8fa1760c077f44aa80271c75d0000000000000000000000006277cb27232f35c75d3d908b26f3670e7d167400000000000000000000000000b3c1d801a02d88adc96a294123c2daa382345058000000000000000000000000000000000000000000000000000000000000fd20000000000000000000000000e00bd3df25fb187d6abbb620b3dfd19839947b81000000000000000000000000e3ed95e130ad9e15643f5a5f232a3dae980784cd
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106100e5575f3560e01c8063668c50c511610088578063c6a304e711610063578063c6a304e71461023b578063d04f955114610245578063ea36a8eb1461026c578063feaf968c14610293575f80fd5b8063668c50c5146101f35780637e8de5ba14610212578063c0e6547814610232575f80fd5b806337a7b7d8116100c357806337a7b7d814610159578063452a93201461019d57806350d25bcd146101c457806363dab52f146101cc575f80fd5b8063204f83f9146100e95780632ecaf67514610123578063313ce5671461014a575b5f80fd5b6101107f0000000000000000000000000000000000000000000000000000000067e4950081565b6040519081526020015b60405180910390f35b6101107f000000000000000000000000000000000000000000000000000000000000fd2081565b6040516012815260200161011a565b5f546101789073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161011a565b6101787f000000000000000000000000e3ed95e130ad9e15643f5a5f232a3dae980784cd81565b6101106102d2565b6101787f0000000000000000000000005cb542eb054f81b8fa1760c077f44aa80271c75d81565b6101fb6102e7565b60408051921515835260208301919091520161011a565b6001546101789073ffffffffffffffffffffffffffffffffffffffff1681565b61011060025481565b610243610325565b005b6101787f000000000000000000000000b3c1d801a02d88adc96a294123c2daa38234505881565b6101787f0000000000000000000000006277cb27232f35c75d3d908b26f3670e7d16740081565b61029b6105e3565b6040805169ffffffffffffffffffff968716815260208101959095528401929092526060830152909116608082015260a00161011a565b5f806102dc6105e3565b509195945050505050565b5f805f806002541180156102fc575060025442105b90508061030d57505f928392509050565b804260025461031c91906107ba565b92509250509091565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000e3ed95e130ad9e15643f5a5f232a3dae980784cd1614610394576040517fef6d0f0200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f0000000000000000000000000000000000000000000000000000000067e4950042106103ed576040517fdaa3fecb00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b426002541015610429576104217f000000000000000000000000000000000000000000000000000000000000fd20426107d3565b60025561042e565b5f6002555b5f5473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000005cb542eb054f81b8fa1760c077f44aa80271c75d8116911603610509575f805473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000006277cb27232f35c75d3d908b26f3670e7d16740081167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255600180547f0000000000000000000000005cb542eb054f81b8fa1760c077f44aa80271c75d9093169290911691909117905561059f565b5f805473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000005cb542eb054f81b8fa1760c077f44aa80271c75d81167fffffffffffffffffffffffff000000000000000000000000000000000000000092831617909255600180547f0000000000000000000000006277cb27232f35c75d3d908b26f3670e7d167400909316929091169190911790555b5f805460405173ffffffffffffffffffffffffffffffffffffffff909116917f6da4629aa3ee6cfa8775a91874378314cd37320bd79b5389bfd2ebcc67f5fc9c91a2565b5f805f805f7f0000000000000000000000000000000000000000000000000000000067e4950042106106ab577f000000000000000000000000b3c1d801a02d88adc96a294123c2daa38234505873ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610678573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061069c9190610804565b94509450945094509450610786565b600254421061071c575f8054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610678573d5f803e3d5ffd5b60015f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663feaf968c6040518163ffffffff1660e01b815260040160a060405180830381865afa158015610678573d5f803e3d5ffd5b9091929394565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b818103818111156107cd576107cd61078d565b92915050565b808201808211156107cd576107cd61078d565b805169ffffffffffffffffffff811681146107ff575f80fd5b919050565b5f805f805f60a08688031215610818575f80fd5b610821866107e6565b9450602086015193506040860151925060608601519150610844608087016107e6565b9050929550929590935056fea2646970667358221220f779c15bd7421c383812b63198139e6ea8c9b11ad454094a8ca014b0487d36b064736f6c63430008140033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000005cb542eb054f81b8fa1760c077f44aa80271c75d0000000000000000000000006277cb27232f35c75d3d908b26f3670e7d167400000000000000000000000000b3c1d801a02d88adc96a294123c2daa382345058000000000000000000000000000000000000000000000000000000000000fd20000000000000000000000000e00bd3df25fb187d6abbb620b3dfd19839947b81000000000000000000000000e3ed95e130ad9e15643f5a5f232a3dae980784cd
-----Decoded View---------------
Arg [0] : _feed (address): 0x5CB542EB054f81b8Fa1760c077f44AA80271c75D
Arg [1] : _beforeMaturityFeed (address): 0x6277cB27232F35C75D3d908b26F3670e7d167400
Arg [2] : _afterMaturityFeed (address): 0xB3C1D801A02d88adC96A294123c2Daa382345058
Arg [3] : _timelockPeriod (uint256): 64800
Arg [4] : _pendlePT (address): 0xE00bd3Df25fb187d6ABBB620b3dfd19839947b81
Arg [5] : _guardian (address): 0xE3eD95e130ad9E15643f5A5f232a3daE980784cd
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000005cb542eb054f81b8fa1760c077f44aa80271c75d
Arg [1] : 0000000000000000000000006277cb27232f35c75d3d908b26f3670e7d167400
Arg [2] : 000000000000000000000000b3c1d801a02d88adc96a294123c2daa382345058
Arg [3] : 000000000000000000000000000000000000000000000000000000000000fd20
Arg [4] : 000000000000000000000000e00bd3df25fb187d6abbb620b3dfd19839947b81
Arg [5] : 000000000000000000000000e3ed95e130ad9e15643f5a5f232a3dae980784cd
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 30 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.