More Info
Private Name Tags
ContractCreator
Latest 25 from a total of 7,055 transactions
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
Add Round Data S... | 19300802 | 1 hr ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19296752 | 3 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19295701 | 4 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19294652 | 4 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19290904 | 6 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19289853 | 7 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19289703 | 7 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19287451 | 8 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19285951 | 9 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19282051 | 11 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19280251 | 12 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19279501 | 13 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19278451 | 13 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19276052 | 15 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19274253 | 16 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19273651 | 16 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19269004 | 19 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19263751 | 21 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19263152 | 22 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19261802 | 23 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19259851 | 24 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19249952 | 29 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19249653 | 29 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19247703 | 30 hrs ago | IN | 0 frxETH | 0.00000112 | ||||
Add Round Data S... | 19244251 | 32 hrs ago | IN | 0 frxETH | 0.00000112 |
Loading...
Loading
Contract Name:
MerkleProofPriceSourceSfrxEth
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.19; // ==================================================================== // | ______ _______ | // | / _____________ __ __ / ____(_____ ____ _____ ________ | // | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ | // | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ | // | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ | // | | // ==================================================================== // ====================== MerkleProofChainlink ======================== // ==================================================================== // Frax Finance: https://github.com/FraxFinance // ==================================================================== import { ERC165Storage } from "src/contracts/utils/ERC165Storage.sol"; import { Timelock2Step } from "frax-std/access-control/v1/Timelock2Step.sol"; import { ITimelock2Step } from "frax-std/access-control/v1/interfaces/ITimelock2Step.sol"; import { MerkleTreeProver } from "./lib/MerkleTreeProver.sol"; import { StateProofVerifier as Verifier } from "./lib/StateProofVerifier.sol"; import { IERC4626Receiver } from "src/contracts/interfaces/IERC4626Receiver.sol"; import { IStateRootOracle } from "./interfaces/IStateRootOracle.sol"; import { FixedPointMathLib } from "@solmate/utils/FixedPointMathLib.sol"; /// @title MerkleProofPriceSource /// @notice Proves price round data from an L1 Frax Oracle and pushes the price data to an L2 Frax Oracle contract MerkleProofPriceSourceSfrxEth is ERC165Storage, Timelock2Step { /// @notice The address of the StateRootOracle on Layer 2 IStateRootOracle public immutable STATE_ROOT_ORACLE; using FixedPointMathLib for uint256; struct OracleConfig { address layer1Oracle; uint96 lastBlockProofed; } /// @notice Configuration linking Frax Oracles for the same asset on L1 / L2 mapping(address layer2FraxOracle => OracleConfig layer1Config) public oracleLookup; /// @notice The ```constructor``` function /// @param _stateRootOracle Address of the L2 StateRootOracle /// @param _timelockAddress Address of Timelock contract on L2 constructor(address _stateRootOracle, address _timelockAddress) Timelock2Step() { _setTimelock({ _newTimelock: _timelockAddress }); _registerInterface({ interfaceId: type(ITimelock2Step).interfaceId }); STATE_ROOT_ORACLE = IStateRootOracle(_stateRootOracle); } // ==================================================================== // Events // ==================================================================== /// @notice The ```OraclePairAdded``` event is emitted when a new Frax Oracle pair is added /// @param fraxOracleLayer1 The address of the layer 1 Frax Oracle /// @param fraxOracleLayer2 The address of the layer 2 Frax Oracle event OraclePairAdded(address indexed fraxOracleLayer1, address indexed fraxOracleLayer2); // ==================================================================== // Configuration Setters // ==================================================================== /// @dev A pair of addresses that are the Frax Oracles for the same asset on layer 1 and layer 2 struct OraclePair { address layer1FraxOracle; address layer2FraxOracle; } /// @notice The ```addOraclePairs``` function sets an L1/L2 pair if they haven't been set already /// @param _oraclePairs List of OraclePairs representing the same oracle on L1 and L2 function addOraclePairs(OraclePair[] calldata _oraclePairs) external { _requireTimelock(); for (uint256 i = 0; i < _oraclePairs.length; ++i) { OraclePair memory _oraclePair = _oraclePairs[i]; if (oracleLookup[_oraclePair.layer2FraxOracle].layer1Oracle != address(0)) { revert OraclePairAlreadySet({ fraxOracleLayer1: oracleLookup[_oraclePair.layer2FraxOracle].layer1Oracle, fraxOracleLayer2: _oraclePair.layer2FraxOracle }); } oracleLookup[_oraclePair.layer2FraxOracle].layer1Oracle = _oraclePair.layer1FraxOracle; emit OraclePairAdded({ fraxOracleLayer1: _oraclePair.layer1FraxOracle, fraxOracleLayer2: _oraclePair.layer2FraxOracle }); } } // ==================================================================== // Proof / Add Price Function // ==================================================================== function _fetchAndProofSfrxEth( address _sfrxEthAddress, uint96 _blockNumber, bytes[] memory _accountProofSfrxEth, bytes[] memory _storageProofTotalSupply, bytes[] memory _storageProofTotalAssets, bytes[] memory _storageProofRewards ) internal view returns (uint256 totalSupply, uint256 totalAssets, uint192 lastRewards, uint32 rewardsCycleEnd, uint32 lastSync) { IStateRootOracle.BlockInfo memory _blockInfo = STATE_ROOT_ORACLE.getBlockInfo(_blockNumber); Verifier.Account memory _accountProofSfrxEth = MerkleTreeProver.proveStorageRoot({ stateRootHash: _blockInfo.stateRootHash, proofAddress: _sfrxEthAddress, accountProof: _accountProofSfrxEth }); totalSupply = uint256( MerkleTreeProver .proveStorageSlotValue({ storageRootHash: _accountProofSfrxEth.storageRoot, slot: bytes32(uint256(2)), storageProof: _storageProofTotalSupply }) .value ); totalAssets = uint256( MerkleTreeProver .proveStorageSlotValue({ storageRootHash: _accountProofSfrxEth.storageRoot, slot: bytes32(uint256(7)), storageProof: _storageProofTotalAssets }) .value ); uint256 rewardsPacked = uint256( MerkleTreeProver .proveStorageSlotValue({ storageRootHash: _accountProofSfrxEth.storageRoot, slot: bytes32(uint256(6)), storageProof: _storageProofRewards }) .value ); // Get the first 24 bytes on the slot lastRewards = uint192(bytes24(bytes32(rewardsPacked))); // get the last 8 bytes on the slot only take first 4 rewardsCycleEnd = uint32(bytes4(bytes32(rewardsPacked) << 192)); // get the last 4 bytes on the slot lastSync = uint32(bytes4(bytes32(rewardsPacked) << 224)); if (totalSupply == 0) revert MustBeGtZero(); if (lastRewards == 0) revert MustBeGtZero(); if (lastSync == 0) revert MustBeGtZero(); if (totalAssets == 0) revert MustBeGtZero(); } function addRoundDataSfrxEth( IERC4626Receiver _sfrxEthAddress, uint96 _blockNumber, bytes[] memory _accountProofSfrxEth, bytes[] memory _storageProofTotalSupply, bytes[] memory _storageProofTotalAssets, bytes[] memory _storageProofRewards ) external { uint96 lastBlockProofed = oracleLookup[address(_sfrxEthAddress)].lastBlockProofed; if (lastBlockProofed != 0) { if (_blockNumber < lastBlockProofed) revert StalePush(); } // Address of the L1 oracle address _proofAddress = oracleLookup[address(_sfrxEthAddress)].layer1Oracle; if (_proofAddress == address(0)) revert WrongOracleAddress(); ( uint256 totalSupply, uint256 totalStoredAssets, uint192 lastRewards, uint32 rewardsCycleEnd, uint32 lastSync ) = _fetchAndProofSfrxEth( _proofAddress, _blockNumber, _accountProofSfrxEth, _storageProofTotalSupply, _storageProofTotalAssets, _storageProofRewards ); _sfrxEthAddress.updateErc4262VaultData( _blockNumber, totalSupply, totalStoredAssets, lastRewards, rewardsCycleEnd, lastSync ); oracleLookup[address(_sfrxEthAddress)].lastBlockProofed = _blockNumber; } // ==================================================================== // Errors // ==================================================================== error OraclePairAlreadySet(address fraxOracleLayer1, address fraxOracleLayer2); error WrongOracleAddress(); error StalePush(); error MustBeGtZero(); }
// 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: 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; // ==================================================================== // | ______ _______ | // | / _____________ __ __ / ____(_____ ____ _____ ________ | // | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ | // | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ | // | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ | // | | // ==================================================================== // ========================= MerkleTreeProver ========================= // ==================================================================== // Frax Finance: https://github.com/FraxFinance // Authors // Jon Walch: https://github.com/jonwalch // Dennis: https://github.com/denett // Reviewers // Drake Evans: https://github.com/DrakeEvans // ==================================================================== import { RLPReader } from "rlp/RLPReader.sol"; import { StateProofVerifier as Verifier } from "./StateProofVerifier.sol"; /// @title MerkleTreeProver /// @author Jon Walch (Frax Finance) https://github.com/jonwalch /// @notice Helper function library for interacting with StateProofVerifier and RLPReader library MerkleTreeProver { using RLPReader for bytes; using RLPReader for RLPReader.RLPItem; /// @notice The ```proveStorageRoot``` function is a helper function for StateProofVerifier.extractAccountFromProof() /// @param stateRootHash The hash of the state root /// @param proofAddress The address of the contract we're proving /// @param accountProof The accountProof retrieved from eth_getProof function proveStorageRoot( bytes32 stateRootHash, address proofAddress, bytes[] memory accountProof ) internal view returns (Verifier.Account memory accountPool) { RLPReader.RLPItem[] memory accountProofRlp = new RLPReader.RLPItem[](accountProof.length); for (uint256 i = 0; i < accountProof.length; ++i) { accountProofRlp[i] = accountProof[i].toRlpItem(); } accountPool = Verifier.extractAccountFromProof({ _addressHash: keccak256(abi.encodePacked(proofAddress)), _stateRootHash: stateRootHash, _proof: accountProofRlp }); } /// @notice The ```proveStorageSlotValue``` function is a helper function for StateProofVerifier.extractSlotValueFromProof() /// @param storageRootHash The hash of the storage root /// @param slot The slot we want to prove for the contract /// @param storageProof The storageProof.proof retrieved from eth_getProof function proveStorageSlotValue( bytes32 storageRootHash, bytes32 slot, bytes[] memory storageProof ) internal view returns (Verifier.SlotValue memory slotValue) { RLPReader.RLPItem[] memory storageProofRlp = new RLPReader.RLPItem[](storageProof.length); for (uint256 i = 0; i < storageProof.length; ++i) { storageProofRlp[i] = storageProof[i].toRlpItem(); } slotValue = Verifier.extractSlotValueFromProof({ _slotHash: keccak256(abi.encodePacked(slot)), _storageRootHash: storageRootHash, _proof: storageProofRlp }); } }
// SPDX-License-Identifier: MIT // Copied from https://github.com/lidofinance/curve-merkle-oracle/blob/1033b3e84142317ffd8f366b52e489d5eb49c73f/contracts/StateProofVerifier.sol pragma solidity ^0.8.20; import { RLPReader } from "rlp/RLPReader.sol"; import { MerklePatriciaProofVerifier } from "./MerklePatriciaProofVerifier.sol"; /** * @title A helper library for verification of Merkle Patricia account and state proofs. */ library StateProofVerifier { using RLPReader for RLPReader.RLPItem; using RLPReader for bytes; uint256 constant HEADER_STATE_ROOT_INDEX = 3; uint256 constant HEADER_NUMBER_INDEX = 8; uint256 constant HEADER_TIMESTAMP_INDEX = 11; struct BlockHeader { bytes32 hash; bytes32 stateRootHash; uint256 number; uint256 timestamp; } struct Account { bool exists; uint256 nonce; uint256 balance; bytes32 storageRoot; bytes32 codeHash; } struct SlotValue { bool exists; uint256 value; } /** * @notice Parses block header and verifies its presence onchain within the latest 256 blocks. * @param _headerRlpBytes RLP-encoded block header. */ function verifyBlockHeader(bytes memory _headerRlpBytes) internal view returns (BlockHeader memory) { BlockHeader memory header = parseBlockHeader(_headerRlpBytes); // ensure that the block is actually in the blockchain require(header.hash == blockhash(header.number), "blockhash mismatch"); return header; } /** * @notice Parses RLP-encoded block header. * @param _headerRlpBytes RLP-encoded block header. */ function parseBlockHeader(bytes memory _headerRlpBytes) internal pure returns (BlockHeader memory) { BlockHeader memory result; RLPReader.RLPItem[] memory headerFields = _headerRlpBytes.toRlpItem().toList(); require(headerFields.length > HEADER_TIMESTAMP_INDEX); result.stateRootHash = bytes32(headerFields[HEADER_STATE_ROOT_INDEX].toUint()); result.number = headerFields[HEADER_NUMBER_INDEX].toUint(); result.timestamp = headerFields[HEADER_TIMESTAMP_INDEX].toUint(); result.hash = keccak256(_headerRlpBytes); return result; } /** * @notice Verifies Merkle Patricia proof of an account and extracts the account fields. * * @param _addressHash Keccak256 hash of the address corresponding to the account. * @param _stateRootHash MPT root hash of the Ethereum state trie. */ function extractAccountFromProof( bytes32 _addressHash, // keccak256(abi.encodePacked(address)) bytes32 _stateRootHash, RLPReader.RLPItem[] memory _proof ) internal pure returns (Account memory) { bytes memory acctRlpBytes = MerklePatriciaProofVerifier.extractProofValue( _stateRootHash, abi.encodePacked(_addressHash), _proof ); Account memory account; if (acctRlpBytes.length == 0) { return account; } RLPReader.RLPItem[] memory acctFields = acctRlpBytes.toRlpItem().toList(); require(acctFields.length == 4); account.exists = true; account.nonce = acctFields[0].toUint(); account.balance = acctFields[1].toUint(); account.storageRoot = bytes32(acctFields[2].toUint()); account.codeHash = bytes32(acctFields[3].toUint()); return account; } /** * @notice Verifies Merkle Patricia proof of a slot and extracts the slot's value. * * @param _slotHash Keccak256 hash of the slot position. * @param _storageRootHash MPT root hash of the account's storage trie. */ function extractSlotValueFromProof( bytes32 _slotHash, bytes32 _storageRootHash, RLPReader.RLPItem[] memory _proof ) internal pure returns (SlotValue memory) { bytes memory valueRlpBytes = MerklePatriciaProofVerifier.extractProofValue( _storageRootHash, abi.encodePacked(_slotHash), _proof ); SlotValue memory value; if (valueRlpBytes.length != 0) { value.exists = true; value.value = valueRlpBytes.toRlpItem().toUint(); } return value; } }
// SPDX-License-Identifier: ISC pragma solidity ^0.8.19; interface IERC4626Receiver { function updateErc4262VaultData( uint96 _l1BlockNumber, uint256 _totalSupply, uint256 _totalAssets, uint192 _lastRewardsAmount, uint32 _lastSync, uint32 _rewardsCycleEnd ) external; /// @notice Information about the current rewards cycle struct RewardsCycleData { uint40 cycleEnd; // Timestamp of the end of the current rewards cycle uint40 lastSync; // Timestamp of the last time the rewards cycle was synced uint216 rewardCycleAmount; // Amount of rewards to be distributed in the current cycle } function updatesFRAXData( uint96 _l1BlockNumber, uint256 _totalSupply, uint256 _totalAssets, uint256 _lastDistributionAmount, RewardsCycleData memory data ) external; function updateMaxDistributionPerSecond(uint96 _l1BlockNumber, uint256 maxPerSecond) external; function updateDaiVaultData(uint96 _l1BlockNumber, uint256 _dsr, uint256 _rho, uint256 _chi) external; function getPrices() external view returns (bool, uint256, uint256); function dsr() external view returns (uint256); function chi() external view returns (uint256); function rho() external view returns (uint256); function updateSUSDeVaultData( uint96 _l1BlockNumber, uint256 _totalSupply, uint256 _totalAssets, uint256 _vestingAmount, uint256 _lastDistributionTimestamp ) external; }
// SPDX-License-Identifier: ISC pragma solidity ^0.8.20; interface IStateRootOracle { struct BlockInfo { bytes32 stateRootHash; uint40 timestamp; } function getBlockInfo(uint256 blockNumber) external view returns (BlockInfo memory _blockInfo); }
// SPDX-License-Identifier: AGPL-3.0-only pragma solidity >=0.8.0; /// @notice Arithmetic library with operations for fixed-point numbers. /// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol) /// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol) library FixedPointMathLib { /*////////////////////////////////////////////////////////////// SIMPLIFIED FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s. function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down. } function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up. } function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down. } function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) { return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up. } /*////////////////////////////////////////////////////////////// LOW LEVEL FIXED POINT OPERATIONS //////////////////////////////////////////////////////////////*/ function mulDivDown( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // Divide z by the denominator. z := div(z, denominator) } } function mulDivUp( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 z) { assembly { // Store x * y in z for now. z := mul(x, y) // Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y)) if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) { revert(0, 0) } // First, divide z - 1 by the denominator and add 1. // We allow z - 1 to underflow if z is 0, because we multiply the // end result by 0 if z is zero, ensuring we return 0 if z is zero. z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1)) } } function rpow( uint256 x, uint256 n, uint256 scalar ) internal pure returns (uint256 z) { assembly { switch x case 0 { switch n case 0 { // 0 ** 0 = 1 z := scalar } default { // 0 ** n = 0 z := 0 } } default { switch mod(n, 2) case 0 { // If n is even, store scalar in z for now. z := scalar } default { // If n is odd, store x in z for now. z := x } // Shifting right by 1 is like dividing by 2. let half := shr(1, scalar) for { // Shift n right by 1 before looping to halve it. n := shr(1, n) } n { // Shift n right by 1 each iteration to halve it. n := shr(1, n) } { // Revert immediately if x ** 2 would overflow. // Equivalent to iszero(eq(div(xx, x), x)) here. if shr(128, x) { revert(0, 0) } // Store x squared. let xx := mul(x, x) // Round to the nearest number. let xxRound := add(xx, half) // Revert if xx + half overflowed. if lt(xxRound, xx) { revert(0, 0) } // Set x to scaled xxRound. x := div(xxRound, scalar) // If n is even: if mod(n, 2) { // Compute z * x. let zx := mul(z, x) // If z * x overflowed: if iszero(eq(div(zx, x), z)) { // Revert if x is non-zero. if iszero(iszero(x)) { revert(0, 0) } } // Round to the nearest number. let zxRound := add(zx, half) // Revert if zx + half overflowed. if lt(zxRound, zx) { revert(0, 0) } // Return properly scaled zxRound. z := div(zxRound, scalar) } } } } } /*////////////////////////////////////////////////////////////// GENERAL NUMBER UTILITIES //////////////////////////////////////////////////////////////*/ function sqrt(uint256 x) internal pure returns (uint256 z) { assembly { // Start off with z at 1. z := 1 // Used below to help find a nearby power of 2. let y := x // Find the lowest power of 2 that is at least sqrt(x). if iszero(lt(y, 0x100000000000000000000000000000000)) { y := shr(128, y) // Like dividing by 2 ** 128. z := shl(64, z) // Like multiplying by 2 ** 64. } if iszero(lt(y, 0x10000000000000000)) { y := shr(64, y) // Like dividing by 2 ** 64. z := shl(32, z) // Like multiplying by 2 ** 32. } if iszero(lt(y, 0x100000000)) { y := shr(32, y) // Like dividing by 2 ** 32. z := shl(16, z) // Like multiplying by 2 ** 16. } if iszero(lt(y, 0x10000)) { y := shr(16, y) // Like dividing by 2 ** 16. z := shl(8, z) // Like multiplying by 2 ** 8. } if iszero(lt(y, 0x100)) { y := shr(8, y) // Like dividing by 2 ** 8. z := shl(4, z) // Like multiplying by 2 ** 4. } if iszero(lt(y, 0x10)) { y := shr(4, y) // Like dividing by 2 ** 4. z := shl(2, z) // Like multiplying by 2 ** 2. } if iszero(lt(y, 0x8)) { // Equivalent to 2 ** z. z := shl(1, z) } // Shifting right by 1 is like dividing by 2. z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) z := shr(1, add(z, div(x, z))) // Compute a rounded down version of z. let zRoundDown := div(x, z) // If zRoundDown is smaller, use it. if lt(zRoundDown, z) { z := zRoundDown } } } }
// 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: Apache-2.0 /* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns */ pragma solidity >=0.5.10 <0.9.0; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint256 len; uint256 memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint256 nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint256 ptr = self.nextPtr; uint256 itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint256 memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint256 ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param the RLP item. */ function rlpLen(RLPItem memory item) internal pure returns (uint256) { return item.len; } /* * @param the RLP item. * @return (memPtr, len) pair: location of the item's payload in memory. */ function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) { uint256 offset = _payloadOffset(item.memPtr); uint256 memPtr = item.memPtr + offset; uint256 len = item.len - offset; // data length return (memPtr, len); } /* * @param the RLP item. */ function payloadLen(RLPItem memory item) internal pure returns (uint256) { (, uint256 len) = payloadLocation(item); return len; } /* * @param the RLP item containing the encoded list. */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint256 items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 dataLen; for (uint256 i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } return result; } // @return indicator whether encoded payload is a list. negate this function call for isData. function isList(RLPItem memory item) internal pure returns (bool) { if (item.len == 0) return false; uint8 byte0; uint256 memPtr = item.memPtr; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < LIST_SHORT_START) return false; return true; } /* * @dev A cheaper version of keccak256(toRlpBytes(item)) that avoids copying memory. * @return keccak256 hash of RLP encoded bytes. */ function rlpBytesKeccak256(RLPItem memory item) internal pure returns (bytes32) { uint256 ptr = item.memPtr; uint256 len = item.len; bytes32 result; assembly { result := keccak256(ptr, len) } return result; } /* * @dev A cheaper version of keccak256(toBytes(item)) that avoids copying memory. * @return keccak256 hash of the item payload. */ function payloadKeccak256(RLPItem memory item) internal pure returns (bytes32) { (uint256 memPtr, uint256 len) = payloadLocation(item); bytes32 result; assembly { result := keccak256(memPtr, len) } return result; } /** RLPItem conversions into data types **/ // @returns raw rlp encoding in bytes function toRlpBytes(RLPItem memory item) internal pure returns (bytes memory) { bytes memory result = new bytes(item.len); if (result.length == 0) return result; uint256 ptr; assembly { ptr := add(0x20, result) } copy(item.memPtr, ptr, item.len); return result; } // any non-zero byte except "0x80" is considered true function toBoolean(RLPItem memory item) internal pure returns (bool) { require(item.len == 1); uint256 result; uint256 memPtr = item.memPtr; assembly { result := byte(0, mload(memPtr)) } // SEE Github Issue #5. // Summary: Most commonly used RLP libraries (i.e Geth) will encode // "0" as "0x80" instead of as "0". We handle this edge case explicitly // here. if (result == 0 || result == STRING_SHORT_START) { return false; } else { return true; } } function toAddress(RLPItem memory item) internal pure returns (address) { // 1 byte for the length prefix require(item.len == 21); return address(uint160(toUint(item))); } function toUint(RLPItem memory item) internal pure returns (uint256) { require(item.len > 0 && item.len <= 33); (uint256 memPtr, uint256 len) = payloadLocation(item); uint256 result; assembly { result := mload(memPtr) // shift to the correct location if neccesary if lt(len, 32) { result := div(result, exp(256, sub(32, len))) } } return result; } // enforces 32 byte length function toUintStrict(RLPItem memory item) internal pure returns (uint256) { // one byte prefix require(item.len == 33); uint256 result; uint256 memPtr = item.memPtr + 1; assembly { result := mload(memPtr) } return result; } function toBytes(RLPItem memory item) internal pure returns (bytes memory) { require(item.len > 0); (uint256 memPtr, uint256 len) = payloadLocation(item); bytes memory result = new bytes(len); uint256 destPtr; assembly { destPtr := add(0x20, result) } copy(memPtr, destPtr, len); return result; } /* * Private Helpers */ // @return number of payload items inside an encoded list. function numItems(RLPItem memory item) private pure returns (uint256) { if (item.len == 0) return 0; uint256 count = 0; uint256 currPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 endPtr = item.memPtr + item.len; while (currPtr < endPtr) { currPtr = currPtr + _itemLength(currPtr); // skip over an item count++; } return count; } // @return entire rlp item byte length function _itemLength(uint256 memPtr) private pure returns (uint256) { uint256 itemLen; uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) { itemLen = 1; } else if (byte0 < STRING_LONG_START) { itemLen = byte0 - STRING_SHORT_START + 1; } else if (byte0 < LIST_SHORT_START) { assembly { let byteLen := sub(byte0, 0xb7) // # of bytes the actual length is memPtr := add(memPtr, 1) // skip over the first byte /* 32 byte word size */ let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to get the len itemLen := add(dataLen, add(byteLen, 1)) } } else if (byte0 < LIST_LONG_START) { itemLen = byte0 - LIST_SHORT_START + 1; } else { assembly { let byteLen := sub(byte0, 0xf7) memPtr := add(memPtr, 1) let dataLen := div(mload(memPtr), exp(256, sub(32, byteLen))) // right shifting to the correct length itemLen := add(dataLen, add(byteLen, 1)) } } return itemLen; } // @return number of bytes until the data function _payloadOffset(uint256 memPtr) private pure returns (uint256) { uint256 byte0; assembly { byte0 := byte(0, mload(memPtr)) } if (byte0 < STRING_SHORT_START) { return 0; } else if (byte0 < STRING_LONG_START || (byte0 >= LIST_SHORT_START && byte0 < LIST_LONG_START)) { return 1; } else if (byte0 < LIST_SHORT_START) { // being explicit return byte0 - (STRING_LONG_START - 1) + 1; } else { return byte0 - (LIST_LONG_START - 1) + 1; } } /* * @param src Pointer to source * @param dest Pointer to destination * @param len Amount of memory to copy from the source */ function copy(uint256 src, uint256 dest, uint256 len) private pure { if (len == 0) return; // copy as many word sizes as possible for (; len >= WORD_SIZE; len -= WORD_SIZE) { assembly { mstore(dest, mload(src)) } src += WORD_SIZE; dest += WORD_SIZE; } if (len > 0) { // left over bytes. Mask is used to remove unwanted bytes from the word uint256 mask = 256**(WORD_SIZE - len) - 1; assembly { let srcpart := and(mload(src), not(mask)) // zero out src let destpart := and(mload(dest), mask) // retrieve the bytes mstore(dest, or(destpart, srcpart)) } } } }
// SPDX-License-Identifier: MIT // Copied from https://github.com/lidofinance/curve-merkle-oracle/blob/1033b3e84142317ffd8f366b52e489d5eb49c73f/contracts/MerklePatriciaProofVerifier.sol /** * Copied from https://github.com/lorenzb/proveth/blob/c74b20e/onchain/ProvethVerifier.sol * with minor performance and code style-related modifications. */ pragma solidity ^0.8.20; import { RLPReader } from "rlp/RLPReader.sol"; library MerklePatriciaProofVerifier { using RLPReader for RLPReader.RLPItem; using RLPReader for bytes; /// @dev Validates a Merkle-Patricia-Trie proof. /// If the proof proves the inclusion of some key-value pair in the /// trie, the value is returned. Otherwise, i.e. if the proof proves /// the exclusion of a key from the trie, an empty byte array is /// returned. /// @param rootHash is the Keccak-256 hash of the root node of the MPT. /// @param path is the key of the node whose inclusion/exclusion we are /// proving. /// @param stack is the stack of MPT nodes (starting with the root) that /// need to be traversed during verification. /// @return value whose inclusion is proved or an empty byte array for /// a proof of exclusion function extractProofValue( bytes32 rootHash, bytes memory path, RLPReader.RLPItem[] memory stack ) internal pure returns (bytes memory value) { bytes memory mptKey = _decodeNibbles(path, 0); uint256 mptKeyOffset = 0; bytes32 nodeHashHash; RLPReader.RLPItem[] memory node; RLPReader.RLPItem memory rlpValue; if (stack.length == 0) { // Root hash of empty Merkle-Patricia-Trie require(rootHash == 0x56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b421); return new bytes(0); } // Traverse stack of nodes starting at root. for (uint256 i = 0; i < stack.length; i++) { // We use the fact that an rlp encoded list consists of some // encoding of its length plus the concatenation of its // *rlp-encoded* items. // The root node is hashed with Keccak-256 ... if (i == 0 && rootHash != stack[i].rlpBytesKeccak256()) { revert(); } // ... whereas all other nodes are hashed with the MPT // hash function. if (i != 0 && nodeHashHash != _mptHashHash(stack[i])) { revert(); } // We verified that stack[i] has the correct hash, so we // may safely decode it. node = stack[i].toList(); if (node.length == 2) { // Extension or Leaf node bool isLeaf; bytes memory nodeKey; (isLeaf, nodeKey) = _merklePatriciaCompactDecode(node[0].toBytes()); uint256 prefixLength = _sharedPrefixLength(mptKeyOffset, mptKey, nodeKey); mptKeyOffset += prefixLength; if (prefixLength < nodeKey.length) { // Proof claims divergent extension or leaf. (Only // relevant for proofs of exclusion.) // An Extension/Leaf node is divergent iff it "skips" over // the point at which a Branch node should have been had the // excluded key been included in the trie. // Example: Imagine a proof of exclusion for path [1, 4], // where the current node is a Leaf node with // path [1, 3, 3, 7]. For [1, 4] to be included, there // should have been a Branch node at [1] with a child // at 3 and a child at 4. // Sanity check if (i < stack.length - 1) { // divergent node must come last in proof revert(); } return new bytes(0); } if (isLeaf) { // Sanity check if (i < stack.length - 1) { // leaf node must come last in proof revert(); } if (mptKeyOffset < mptKey.length) { return new bytes(0); } rlpValue = node[1]; return rlpValue.toBytes(); } else { // extension // Sanity check if (i == stack.length - 1) { // shouldn't be at last level revert(); } if (!node[1].isList()) { // rlp(child) was at least 32 bytes. node[1] contains // Keccak256(rlp(child)). nodeHashHash = node[1].payloadKeccak256(); } else { // rlp(child) was less than 32 bytes. node[1] contains // rlp(child). nodeHashHash = node[1].rlpBytesKeccak256(); } } } else if (node.length == 17) { // Branch node if (mptKeyOffset != mptKey.length) { // we haven't consumed the entire path, so we need to look at a child uint8 nibble = uint8(mptKey[mptKeyOffset]); mptKeyOffset += 1; if (nibble >= 16) { // each element of the path has to be a nibble revert(); } if (_isEmptyBytesequence(node[nibble])) { // Sanity if (i != stack.length - 1) { // leaf node should be at last level revert(); } return new bytes(0); } else if (!node[nibble].isList()) { nodeHashHash = node[nibble].payloadKeccak256(); } else { nodeHashHash = node[nibble].rlpBytesKeccak256(); } } else { // we have consumed the entire mptKey, so we need to look at what's contained in this node. // Sanity if (i != stack.length - 1) { // should be at last level revert(); } return node[16].toBytes(); } } } } /// @dev Computes the hash of the Merkle-Patricia-Trie hash of the RLP item. /// Merkle-Patricia-Tries use a weird "hash function" that outputs /// *variable-length* hashes: If the item is shorter than 32 bytes, /// the MPT hash is the item. Otherwise, the MPT hash is the /// Keccak-256 hash of the item. /// The easiest way to compare variable-length byte sequences is /// to compare their Keccak-256 hashes. /// @param item The RLP item to be hashed. /// @return Keccak-256(MPT-hash(item)) function _mptHashHash(RLPReader.RLPItem memory item) private pure returns (bytes32) { if (item.len < 32) { return item.rlpBytesKeccak256(); } else { return keccak256(abi.encodePacked(item.rlpBytesKeccak256())); } } function _isEmptyBytesequence(RLPReader.RLPItem memory item) private pure returns (bool) { if (item.len != 1) { return false; } uint8 b; uint256 memPtr = item.memPtr; assembly { b := byte(0, mload(memPtr)) } return b == 0x80; /* empty byte string */ } function _merklePatriciaCompactDecode( bytes memory compact ) private pure returns (bool isLeaf, bytes memory nibbles) { require(compact.length > 0); uint256 first_nibble = (uint8(compact[0]) >> 4) & 0xF; uint256 skipNibbles; if (first_nibble == 0) { skipNibbles = 2; isLeaf = false; } else if (first_nibble == 1) { skipNibbles = 1; isLeaf = false; } else if (first_nibble == 2) { skipNibbles = 2; isLeaf = true; } else if (first_nibble == 3) { skipNibbles = 1; isLeaf = true; } else { // Not supposed to happen! revert(); } return (isLeaf, _decodeNibbles(compact, skipNibbles)); } function _decodeNibbles(bytes memory compact, uint256 skipNibbles) private pure returns (bytes memory nibbles) { require(compact.length > 0); uint256 length = compact.length * 2; require(skipNibbles <= length); length -= skipNibbles; nibbles = new bytes(length); uint256 nibblesLength = 0; for (uint256 i = skipNibbles; i < skipNibbles + length; i += 1) { if (i % 2 == 0) { nibbles[nibblesLength] = bytes1((uint8(compact[i / 2]) >> 4) & 0xF); } else { nibbles[nibblesLength] = bytes1((uint8(compact[i / 2]) >> 0) & 0xF); } nibblesLength += 1; } assert(nibblesLength == nibbles.length); } function _sharedPrefixLength(uint256 xsOffset, bytes memory xs, bytes memory ys) private pure returns (uint256) { uint256 i; for (i = 0; i + xsOffset < xs.length && i < ys.length; i++) { if (xs[i + xsOffset] != ys[i]) { return i; } } return i; } }
// 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); }
{ "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":[{"internalType":"address","name":"_stateRootOracle","type":"address"},{"internalType":"address","name":"_timelockAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"MustBeGtZero","type":"error"},{"inputs":[],"name":"OnlyPendingTimelock","type":"error"},{"inputs":[],"name":"OnlyTimelock","type":"error"},{"inputs":[{"internalType":"address","name":"fraxOracleLayer1","type":"address"},{"internalType":"address","name":"fraxOracleLayer2","type":"address"}],"name":"OraclePairAlreadySet","type":"error"},{"inputs":[],"name":"StalePush","type":"error"},{"inputs":[],"name":"WrongOracleAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"fraxOracleLayer1","type":"address"},{"indexed":true,"internalType":"address","name":"fraxOracleLayer2","type":"address"}],"name":"OraclePairAdded","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":"STATE_ROOT_ORACLE","outputs":[{"internalType":"contract IStateRootOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptTransferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"layer1FraxOracle","type":"address"},{"internalType":"address","name":"layer2FraxOracle","type":"address"}],"internalType":"struct MerkleProofPriceSourceSfrxEth.OraclePair[]","name":"_oraclePairs","type":"tuple[]"}],"name":"addOraclePairs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC4626Receiver","name":"_sfrxEthAddress","type":"address"},{"internalType":"uint96","name":"_blockNumber","type":"uint96"},{"internalType":"bytes[]","name":"_accountProofSfrxEth","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProofTotalSupply","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProofTotalAssets","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProofRewards","type":"bytes[]"}],"name":"addRoundDataSfrxEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"layer2FraxOracle","type":"address"}],"name":"oracleLookup","outputs":[{"internalType":"address","name":"layer1Oracle","type":"address"},{"internalType":"uint96","name":"lastBlockProofed","type":"uint96"}],"stateMutability":"view","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":"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"}]
Contract Creation Code
60a060405234801562000010575f80fd5b506040516200240c3803806200240c83398101604081905262000033916200016f565b600280546001600160a01b03191633179055620000508162000075565b62000062632fa3fc3160e21b620000d0565b506001600160a01b0316608052620001a5565b6002546040516001600160a01b038084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160e01b031980821690036200012f5760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319165f908152602081905260409020805460ff19166001179055565b80516001600160a01b03811681146200016a575f80fd5b919050565b5f806040838503121562000181575f80fd5b6200018c8362000153565b91506200019c6020840162000153565b90509250929050565b608051612247620001c55f395f818161016c01526108f601526122475ff3fe608060405234801561000f575f80fd5b50600436106100b9575f3560e01c80639378ca5611610072578063cba8df8e11610058578063cba8df8e146101a1578063edb219c0146101b4578063f6ccaad41461024a575f80fd5b80639378ca5614610167578063a6d7fdf21461018e575f80fd5b806345014095116100a2578063450140951461012a5780634bc66f321461013f5780634f8b4ae71461015f575f80fd5b806301ffc9a7146100bd578063090f3f50146100e5575b5f80fd5b6100d06100cb366004611bb2565b610252565b60405190151581526020015b60405180910390f35b6001546101059073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100dc565b61013d610138366004611c12565b6102d9565b005b6002546101059073ffffffffffffffffffffffffffffffffffffffff1681565b61013d6102ed565b6101057f000000000000000000000000000000000000000000000000000000000000000081565b61013d61019c366004611c2d565b610311565b61013d6101af366004611e73565b610496565b6102116101c2366004611c12565b60036020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff8116907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff9091166020830152016100dc565b61013d6106e4565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614806102d357507fffffffff0000000000000000000000000000000000000000000000000000000082165f9081526020819052604090205460ff165b92915050565b6102e16106f4565b6102ea81610745565b50565b6102f56106f4565b6102fd6107bb565b6103065f610745565b61030f5f61080c565b565b6103196106f4565b5f5b81811015610491575f83838381811061033657610336611f38565b90506040020180360381019061034c9190611f65565b60208082015173ffffffffffffffffffffffffffffffffffffffff9081165f908152600390925260409091205491925016156103f2576020818101805173ffffffffffffffffffffffffffffffffffffffff9081165f908152600390935260409283902054915183517f729d6d9c000000000000000000000000000000000000000000000000000000008152928216600484015216602482015290519081900360440190fd5b80516020808301805173ffffffffffffffffffffffffffffffffffffffff9081165f9081526003909352604080842080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169583169590951790945590518451935190821693909116917fc662d74d8469d456352095edb1ed6a69f64c66ace9fa3598de77edfccfad12a291a35061048a81611fd1565b905061031b565b505050565b73ffffffffffffffffffffffffffffffffffffffff86165f908152600360205260409020547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff16801561053d57806bffffffffffffffffffffffff16866bffffffffffffffffffffffff16101561053d576040517f011d308100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8088165f90815260036020526040902054168061059b576040517f17e740e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805f805f6105ae868d8d8d8d8d610899565b945094509450945094508c73ffffffffffffffffffffffffffffffffffffffff1663cb5571338d87878787876040518763ffffffff1660e01b8152600401610651969594939291906bffffffffffffffffffffffff9690961686526020860194909452604085019290925277ffffffffffffffffffffffffffffffffffffffffffffffff16606084015263ffffffff90811660808401521660a082015260c00190565b5f604051808303815f87803b158015610668575f80fd5b505af115801561067a573d5f803e3d5ffd5b50505073ffffffffffffffffffffffffffffffffffffffff9d8e165f90815260036020526040902080546bffffffffffffffffffffffff909e1674010000000000000000000000000000000000000000029d909e169c909c17909c55505050505050505050505050565b6106ec6107bb565b61030f610aeb565b60025473ffffffffffffffffffffffffffffffffffffffff16331461030f576040517f1c0be90a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600254604051919216907f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a905f90a350565b60015473ffffffffffffffffffffffffffffffffffffffff16331461030f576040517ff5c49e6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6040517fbb141cf40000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff861660048201525f908190819081908190819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063bb141cf4906024016040805180830381865afa15801561093a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061095e9190612008565b90505f61096f825f01518e8d610b1c565b9050610983816060015160025f1b8c610c87565b60200151965061099b816060015160075f1b8b610c87565b6020015195505f6109b4826060015160065f1b8b610c87565b602090810151604081901c975063ffffffff9181901c82169650908116945090505f889003610a0f576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8577ffffffffffffffffffffffffffffffffffffffffffffffff165f03610a62576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8363ffffffff165f03610aa1576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b865f03610ada576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050965096509650965096915050565b600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905561030f3361080c565b6040805160a0810182525f808252602082018190529181018290526060810182905260808101919091525f825167ffffffffffffffff811115610b6157610b61611cc2565b604051908082528060200260200182016040528015610ba557816020015b604080518082019091525f8082526020820152815260200190600190039081610b7f5790505b5090505f5b8351811015610c2a57610bfc848281518110610bc857610bc8611f38565b60200260200101516040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b828281518110610c0e57610c0e611f38565b602002602001018190525080610c2390611fd1565b9050610baa565b506040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b166020820152610c7e90603401604051602081830303815290604052805190602001208683610d7e565b95945050505050565b604080518082019091525f80825260208201525f825167ffffffffffffffff811115610cb557610cb5611cc2565b604051908082528060200260200182016040528015610cf957816020015b604080518082019091525f8082526020820152815260200190600190039081610cd35790505b5090505f5b8351811015610d4a57610d1c848281518110610bc857610bc8611f38565b828281518110610d2e57610d2e611f38565b602002602001018190525080610d4390611fd1565b9050610cfe565b50610c7e84604051602001610d6191815260200190565b604051602081830303815290604052805190602001208683610eed565b6040805160a0810182525f808252602082018190529181018290526060810182905260808101919091525f610dd58486604051602001610dc091815260200190565b60405160208183030381529060405285610f76565b6040805160a0810182525f8082526020820181905291810182905260608101829052608081019190915290915081515f03610e13579150610ee69050565b5f610e4c610e47846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b61139a565b90508051600414610e5b575f80fd5b600182528051610e829082905f90610e7557610e75611f38565b60200260200101516114aa565b60208301528051610ea09082906001908110610e7557610e75611f38565b60408301528051610ebe9082906002908110610e7557610e75611f38565b60608301528051610edc9082906003908110610e7557610e75611f38565b6080830152509150505b9392505050565b604080518082019091525f80825260208201525f610f188486604051602001610dc091815260200190565b604080518082019091525f8082526020820152909150815115610c7e57600181526040805180820182525f80825260209182015281518083019092528351825280840190820152610f68906114aa565b602082015295945050505050565b60605f610f83845f6114f5565b90505f806060610fa460405180604001604052805f81526020015f81525090565b86515f03610ff2577f56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218914610fd7575f80fd5b5050604080515f8152602081019091529350610ee692505050565b5f5b875181101561138d5780158015611033575061102f88828151811061101b5761101b611f38565b602002602001015160208101519051902090565b8a14155b1561103c575f80fd5b801580159061106c575061106888828151811061105b5761105b611f38565b60200260200101516116c2565b8414155b15611075575f80fd5b61109788828151811061108a5761108a611f38565b602002602001015161139a565b9250825160020361123b575f60606110cf6110ca865f815181106110bd576110bd611f38565b602002602001015161171a565b611795565b90925090505f6110e0888a84611828565b90506110ec818961203b565b9750815181101561114d5760018b51611105919061204e565b841015611110575f80fd5b5f5b6040519080825280601f01601f19166020018201604052801561113c576020820181803683370190505b509950505050505050505050610ee6565b82156111b15760018b51611161919061204e565b84101561116c575f80fd5b885188101561117b575f611112565b8560018151811061118e5761118e611f38565b602002602001015194506111a18561171a565b9950505050505050505050610ee6565b60018b516111bf919061204e565b84036111c9575f80fd5b6111ec866001815181106111df576111df611f38565b60200260200101516118e2565b61121a576112138660018151811061120657611206611f38565b6020026020010151611919565b9650611233565b6112308660018151811061101b5761101b611f38565b96505b50505061137b565b825160110361137b5785518514611340575f86868151811061125f5761125f611f38565b016020015160f81c905061127460018761203b565b955060108160ff1610611285575f80fd5b6112aa848260ff168151811061129d5761129d611f38565b602002602001015161192f565b156112e457600189516112bd919061204e565b82146112c7575f80fd5b5050604080515f8152602081019091529550610ee6945050505050565b6112fc848260ff16815181106111df576111df611f38565b61131f57611318848260ff168151811061120657611206611f38565b945061133a565b611337848260ff168151811061101b5761101b611f38565b94505b5061137b565b6001885161134e919061204e565b8114611358575f80fd5b61136e836010815181106110bd576110bd611f38565b9650505050505050610ee6565b8061138581611fd1565b915050610ff4565b5050505050509392505050565b60606113a5826118e2565b6113ad575f80fd5b5f6113b78361194f565b90505f8167ffffffffffffffff8111156113d3576113d3611cc2565b60405190808252806020026020018201604052801561141757816020015b604080518082019091525f80825260208201528152602001906001900390816113f15790505b5090505f61142885602001516119cf565b8560200151611437919061203b565b90505f805b8481101561149f5761144d83611a48565b915060405180604001604052808381526020018481525084828151811061147657611476611f38565b602090810291909101015261148b828461203b565b92508061149781611fd1565b91505061143c565b509195945050505050565b80515f90158015906114be57508151602110155b6114c6575f80fd5b5f806114d184611af0565b8151919350915060208210156114ed5760208290036101000a90045b949350505050565b60605f835111611503575f80fd5b5f835160026115129190612061565b905080831115611520575f80fd5b61152a838261204e565b90508067ffffffffffffffff81111561154557611545611cc2565b6040519080825280601f01601f19166020018201604052801561156f576020820181803683370190505b5091505f835b61157f838661203b565b8110156116a9576115916002826120a5565b5f03611613576004866115a56002846120b8565b815181106115b5576115b5611f38565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b8483815181106115e0576115e0611f38565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535061168a565b5f866116206002846120b8565b8151811061163057611630611f38565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b84838151811061165b5761165b611f38565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505b61169560018361203b565b91506116a260018261203b565b9050611575565b50825181146116ba576116ba6120cb565b505092915050565b5f6020825f015110156116dd576020820151825190206102d3565b6020820151825190206040516020016116f891815260200190565b604051602081830303815290604052805190602001209050919050565b919050565b8051606090611727575f80fd5b5f8061173284611af0565b915091505f8167ffffffffffffffff81111561175057611750611cc2565b6040519080825280601f01601f19166020018201604052801561177a576020820181803683370190505b5090506020810161178c848285611b32565b50949350505050565b5f60605f8351116117a4575f80fd5b5f6004845f815181106117b9576117b9611f38565b60209101015160f81c901c600f1690505f8181036117dc57505f92506002611812565b816001036117ef57505f92506001611812565b816002036118035750600192506002611812565b816003036100b9575060019250825b8361181d86836114f5565b935093505050915091565b5f805b8351611837868361203b565b1080156118445750825181105b156114ed5782818151811061185b5761185b611f38565b01602001517fff00000000000000000000000000000000000000000000000000000000000000168461188d878461203b565b8151811061189d5761189d611f38565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016146118d0579050610ee6565b806118da81611fd1565b91505061182b565b80515f9081036118f357505f919050565b602082015180515f1a9060c082101561190f57505f9392505050565b5060019392505050565b5f805f61192584611af0565b9020949350505050565b80515f9060011461194157505f919050565b5060200151515f1a60801490565b80515f90810361196057505f919050565b5f8061196f84602001516119cf565b846020015161197e919061203b565b90505f845f01518560200151611994919061203b565b90505b808210156119c6576119a882611a48565b6119b2908361203b565b9150826119be81611fd1565b935050611997565b50909392505050565b80515f90811a60808110156119e657505f92915050565b60b8811080611a01575060c08110801590611a01575060f881105b15611a0f5750600192915050565b60c0811015611a3c57611a24600160b86120f8565b611a319060ff168261204e565b610ee690600161203b565b611a24600160f86120f8565b80515f908190811a6080811015611a625760019150611ae9565b60b8811015611a8857611a7660808261204e565b611a8190600161203b565b9150611ae9565b60c0811015611ab55760b78103600185019450806020036101000a85510460018201810193505050611ae9565b60f8811015611ac957611a7660c08261204e565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b5f805f611b0084602001516119cf565b90505f818560200151611b13919061203b565b90505f82865f0151611b25919061204e565b9196919550909350505050565b805f03611b3e57505050565b60208110611b765782518252611b5560208461203b565b9250611b6260208361203b565b9150611b6f60208261204e565b9050611b3e565b8015610491575f6001611b8a83602061204e565b611b969061010061222f565b611ba0919061204e565b84518451821691191617835250505050565b5f60208284031215611bc2575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ee6575f80fd5b73ffffffffffffffffffffffffffffffffffffffff811681146102ea575f80fd5b5f60208284031215611c22575f80fd5b8135610ee681611bf1565b5f8060208385031215611c3e575f80fd5b823567ffffffffffffffff80821115611c55575f80fd5b818501915085601f830112611c68575f80fd5b813581811115611c76575f80fd5b8660208260061b8501011115611c8a575f80fd5b60209290920196919550909350505050565b803561171581611bf1565b80356bffffffffffffffffffffffff81168114611715575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715611d1257611d12611cc2565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d5f57611d5f611cc2565b604052919050565b5f601f8381840112611d77575f80fd5b8235602067ffffffffffffffff80831115611d9457611d94611cc2565b8260051b611da3838201611d18565b9384528681018301938381019089861115611dbc575f80fd5b84890192505b85831015611e6657823584811115611dd9575f8081fd5b8901603f81018b13611dea575f8081fd5b85810135604086821115611e0057611e00611cc2565b611e2f887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08c85011601611d18565b8281528d82848601011115611e43575f8081fd5b828285018a8301375f928101890192909252508352509184019190840190611dc2565b9998505050505050505050565b5f805f805f8060c08789031215611e88575f80fd5b611e9187611c9c565b9550611e9f60208801611ca7565b9450604087013567ffffffffffffffff80821115611ebb575f80fd5b611ec78a838b01611d67565b95506060890135915080821115611edc575f80fd5b611ee88a838b01611d67565b94506080890135915080821115611efd575f80fd5b611f098a838b01611d67565b935060a0890135915080821115611f1e575f80fd5b50611f2b89828a01611d67565b9150509295509295509295565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f60408284031215611f75575f80fd5b611f7d611cef565b8235611f8881611bf1565b81526020830135611f9881611bf1565b60208201529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200157612001611fa4565b5060010190565b5f60408284031215612018575f80fd5b612020611cef565b82518152602083015164ffffffffff81168114611f98575f80fd5b808201808211156102d3576102d3611fa4565b818103818111156102d3576102d3611fa4565b80820281158282048414176102d3576102d3611fa4565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f826120b3576120b3612078565b500690565b5f826120c6576120c6612078565b500490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b60ff82811682821603908111156102d3576102d3611fa4565b600181815b8085111561216a57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561215057612150611fa4565b8085161561215d57918102915b93841c9390800290612116565b509250929050565b5f82612180575060016102d3565b8161218c57505f6102d3565b81600181146121a257600281146121ac576121c8565b60019150506102d3565b60ff8411156121bd576121bd611fa4565b50506001821b6102d3565b5060208310610133831016604e8410600b84101617156121eb575081810a6102d3565b6121f58383612111565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561222757612227611fa4565b029392505050565b5f610ee6838361217256fea164736f6c6343000814000a000000000000000000000000ed403d48e2bc946438b5686aa1ad65056ccf951200000000000000000000000031562ae726afebe25417df01bedc72ef489f45b3
Deployed Bytecode
0x608060405234801561000f575f80fd5b50600436106100b9575f3560e01c80639378ca5611610072578063cba8df8e11610058578063cba8df8e146101a1578063edb219c0146101b4578063f6ccaad41461024a575f80fd5b80639378ca5614610167578063a6d7fdf21461018e575f80fd5b806345014095116100a2578063450140951461012a5780634bc66f321461013f5780634f8b4ae71461015f575f80fd5b806301ffc9a7146100bd578063090f3f50146100e5575b5f80fd5b6100d06100cb366004611bb2565b610252565b60405190151581526020015b60405180910390f35b6001546101059073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100dc565b61013d610138366004611c12565b6102d9565b005b6002546101059073ffffffffffffffffffffffffffffffffffffffff1681565b61013d6102ed565b6101057f000000000000000000000000ed403d48e2bc946438b5686aa1ad65056ccf951281565b61013d61019c366004611c2d565b610311565b61013d6101af366004611e73565b610496565b6102116101c2366004611c12565b60036020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff8116907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff9091166020830152016100dc565b61013d6106e4565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614806102d357507fffffffff0000000000000000000000000000000000000000000000000000000082165f9081526020819052604090205460ff165b92915050565b6102e16106f4565b6102ea81610745565b50565b6102f56106f4565b6102fd6107bb565b6103065f610745565b61030f5f61080c565b565b6103196106f4565b5f5b81811015610491575f83838381811061033657610336611f38565b90506040020180360381019061034c9190611f65565b60208082015173ffffffffffffffffffffffffffffffffffffffff9081165f908152600390925260409091205491925016156103f2576020818101805173ffffffffffffffffffffffffffffffffffffffff9081165f908152600390935260409283902054915183517f729d6d9c000000000000000000000000000000000000000000000000000000008152928216600484015216602482015290519081900360440190fd5b80516020808301805173ffffffffffffffffffffffffffffffffffffffff9081165f9081526003909352604080842080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169583169590951790945590518451935190821693909116917fc662d74d8469d456352095edb1ed6a69f64c66ace9fa3598de77edfccfad12a291a35061048a81611fd1565b905061031b565b505050565b73ffffffffffffffffffffffffffffffffffffffff86165f908152600360205260409020547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff16801561053d57806bffffffffffffffffffffffff16866bffffffffffffffffffffffff16101561053d576040517f011d308100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8088165f90815260036020526040902054168061059b576040517f17e740e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805f805f6105ae868d8d8d8d8d610899565b945094509450945094508c73ffffffffffffffffffffffffffffffffffffffff1663cb5571338d87878787876040518763ffffffff1660e01b8152600401610651969594939291906bffffffffffffffffffffffff9690961686526020860194909452604085019290925277ffffffffffffffffffffffffffffffffffffffffffffffff16606084015263ffffffff90811660808401521660a082015260c00190565b5f604051808303815f87803b158015610668575f80fd5b505af115801561067a573d5f803e3d5ffd5b50505073ffffffffffffffffffffffffffffffffffffffff9d8e165f90815260036020526040902080546bffffffffffffffffffffffff909e1674010000000000000000000000000000000000000000029d909e169c909c17909c55505050505050505050505050565b6106ec6107bb565b61030f610aeb565b60025473ffffffffffffffffffffffffffffffffffffffff16331461030f576040517f1c0be90a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600254604051919216907f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a905f90a350565b60015473ffffffffffffffffffffffffffffffffffffffff16331461030f576040517ff5c49e6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b6040517fbb141cf40000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff861660048201525f908190819081908190819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ed403d48e2bc946438b5686aa1ad65056ccf9512169063bb141cf4906024016040805180830381865afa15801561093a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061095e9190612008565b90505f61096f825f01518e8d610b1c565b9050610983816060015160025f1b8c610c87565b60200151965061099b816060015160075f1b8b610c87565b6020015195505f6109b4826060015160065f1b8b610c87565b602090810151604081901c975063ffffffff9181901c82169650908116945090505f889003610a0f576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8577ffffffffffffffffffffffffffffffffffffffffffffffff165f03610a62576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8363ffffffff165f03610aa1576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b865f03610ada576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050965096509650965096915050565b600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905561030f3361080c565b6040805160a0810182525f808252602082018190529181018290526060810182905260808101919091525f825167ffffffffffffffff811115610b6157610b61611cc2565b604051908082528060200260200182016040528015610ba557816020015b604080518082019091525f8082526020820152815260200190600190039081610b7f5790505b5090505f5b8351811015610c2a57610bfc848281518110610bc857610bc8611f38565b60200260200101516040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b828281518110610c0e57610c0e611f38565b602002602001018190525080610c2390611fd1565b9050610baa565b506040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b166020820152610c7e90603401604051602081830303815290604052805190602001208683610d7e565b95945050505050565b604080518082019091525f80825260208201525f825167ffffffffffffffff811115610cb557610cb5611cc2565b604051908082528060200260200182016040528015610cf957816020015b604080518082019091525f8082526020820152815260200190600190039081610cd35790505b5090505f5b8351811015610d4a57610d1c848281518110610bc857610bc8611f38565b828281518110610d2e57610d2e611f38565b602002602001018190525080610d4390611fd1565b9050610cfe565b50610c7e84604051602001610d6191815260200190565b604051602081830303815290604052805190602001208683610eed565b6040805160a0810182525f808252602082018190529181018290526060810182905260808101919091525f610dd58486604051602001610dc091815260200190565b60405160208183030381529060405285610f76565b6040805160a0810182525f8082526020820181905291810182905260608101829052608081019190915290915081515f03610e13579150610ee69050565b5f610e4c610e47846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b61139a565b90508051600414610e5b575f80fd5b600182528051610e829082905f90610e7557610e75611f38565b60200260200101516114aa565b60208301528051610ea09082906001908110610e7557610e75611f38565b60408301528051610ebe9082906002908110610e7557610e75611f38565b60608301528051610edc9082906003908110610e7557610e75611f38565b6080830152509150505b9392505050565b604080518082019091525f80825260208201525f610f188486604051602001610dc091815260200190565b604080518082019091525f8082526020820152909150815115610c7e57600181526040805180820182525f80825260209182015281518083019092528351825280840190820152610f68906114aa565b602082015295945050505050565b60605f610f83845f6114f5565b90505f806060610fa460405180604001604052805f81526020015f81525090565b86515f03610ff2577f56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b4218914610fd7575f80fd5b5050604080515f8152602081019091529350610ee692505050565b5f5b875181101561138d5780158015611033575061102f88828151811061101b5761101b611f38565b602002602001015160208101519051902090565b8a14155b1561103c575f80fd5b801580159061106c575061106888828151811061105b5761105b611f38565b60200260200101516116c2565b8414155b15611075575f80fd5b61109788828151811061108a5761108a611f38565b602002602001015161139a565b9250825160020361123b575f60606110cf6110ca865f815181106110bd576110bd611f38565b602002602001015161171a565b611795565b90925090505f6110e0888a84611828565b90506110ec818961203b565b9750815181101561114d5760018b51611105919061204e565b841015611110575f80fd5b5f5b6040519080825280601f01601f19166020018201604052801561113c576020820181803683370190505b509950505050505050505050610ee6565b82156111b15760018b51611161919061204e565b84101561116c575f80fd5b885188101561117b575f611112565b8560018151811061118e5761118e611f38565b602002602001015194506111a18561171a565b9950505050505050505050610ee6565b60018b516111bf919061204e565b84036111c9575f80fd5b6111ec866001815181106111df576111df611f38565b60200260200101516118e2565b61121a576112138660018151811061120657611206611f38565b6020026020010151611919565b9650611233565b6112308660018151811061101b5761101b611f38565b96505b50505061137b565b825160110361137b5785518514611340575f86868151811061125f5761125f611f38565b016020015160f81c905061127460018761203b565b955060108160ff1610611285575f80fd5b6112aa848260ff168151811061129d5761129d611f38565b602002602001015161192f565b156112e457600189516112bd919061204e565b82146112c7575f80fd5b5050604080515f8152602081019091529550610ee6945050505050565b6112fc848260ff16815181106111df576111df611f38565b61131f57611318848260ff168151811061120657611206611f38565b945061133a565b611337848260ff168151811061101b5761101b611f38565b94505b5061137b565b6001885161134e919061204e565b8114611358575f80fd5b61136e836010815181106110bd576110bd611f38565b9650505050505050610ee6565b8061138581611fd1565b915050610ff4565b5050505050509392505050565b60606113a5826118e2565b6113ad575f80fd5b5f6113b78361194f565b90505f8167ffffffffffffffff8111156113d3576113d3611cc2565b60405190808252806020026020018201604052801561141757816020015b604080518082019091525f80825260208201528152602001906001900390816113f15790505b5090505f61142885602001516119cf565b8560200151611437919061203b565b90505f805b8481101561149f5761144d83611a48565b915060405180604001604052808381526020018481525084828151811061147657611476611f38565b602090810291909101015261148b828461203b565b92508061149781611fd1565b91505061143c565b509195945050505050565b80515f90158015906114be57508151602110155b6114c6575f80fd5b5f806114d184611af0565b8151919350915060208210156114ed5760208290036101000a90045b949350505050565b60605f835111611503575f80fd5b5f835160026115129190612061565b905080831115611520575f80fd5b61152a838261204e565b90508067ffffffffffffffff81111561154557611545611cc2565b6040519080825280601f01601f19166020018201604052801561156f576020820181803683370190505b5091505f835b61157f838661203b565b8110156116a9576115916002826120a5565b5f03611613576004866115a56002846120b8565b815181106115b5576115b5611f38565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b8483815181106115e0576115e0611f38565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a90535061168a565b5f866116206002846120b8565b8151811061163057611630611f38565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b84838151811061165b5761165b611f38565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505b61169560018361203b565b91506116a260018261203b565b9050611575565b50825181146116ba576116ba6120cb565b505092915050565b5f6020825f015110156116dd576020820151825190206102d3565b6020820151825190206040516020016116f891815260200190565b604051602081830303815290604052805190602001209050919050565b919050565b8051606090611727575f80fd5b5f8061173284611af0565b915091505f8167ffffffffffffffff81111561175057611750611cc2565b6040519080825280601f01601f19166020018201604052801561177a576020820181803683370190505b5090506020810161178c848285611b32565b50949350505050565b5f60605f8351116117a4575f80fd5b5f6004845f815181106117b9576117b9611f38565b60209101015160f81c901c600f1690505f8181036117dc57505f92506002611812565b816001036117ef57505f92506001611812565b816002036118035750600192506002611812565b816003036100b9575060019250825b8361181d86836114f5565b935093505050915091565b5f805b8351611837868361203b565b1080156118445750825181105b156114ed5782818151811061185b5761185b611f38565b01602001517fff00000000000000000000000000000000000000000000000000000000000000168461188d878461203b565b8151811061189d5761189d611f38565b01602001517fff0000000000000000000000000000000000000000000000000000000000000016146118d0579050610ee6565b806118da81611fd1565b91505061182b565b80515f9081036118f357505f919050565b602082015180515f1a9060c082101561190f57505f9392505050565b5060019392505050565b5f805f61192584611af0565b9020949350505050565b80515f9060011461194157505f919050565b5060200151515f1a60801490565b80515f90810361196057505f919050565b5f8061196f84602001516119cf565b846020015161197e919061203b565b90505f845f01518560200151611994919061203b565b90505b808210156119c6576119a882611a48565b6119b2908361203b565b9150826119be81611fd1565b935050611997565b50909392505050565b80515f90811a60808110156119e657505f92915050565b60b8811080611a01575060c08110801590611a01575060f881105b15611a0f5750600192915050565b60c0811015611a3c57611a24600160b86120f8565b611a319060ff168261204e565b610ee690600161203b565b611a24600160f86120f8565b80515f908190811a6080811015611a625760019150611ae9565b60b8811015611a8857611a7660808261204e565b611a8190600161203b565b9150611ae9565b60c0811015611ab55760b78103600185019450806020036101000a85510460018201810193505050611ae9565b60f8811015611ac957611a7660c08261204e565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b5f805f611b0084602001516119cf565b90505f818560200151611b13919061203b565b90505f82865f0151611b25919061204e565b9196919550909350505050565b805f03611b3e57505050565b60208110611b765782518252611b5560208461203b565b9250611b6260208361203b565b9150611b6f60208261204e565b9050611b3e565b8015610491575f6001611b8a83602061204e565b611b969061010061222f565b611ba0919061204e565b84518451821691191617835250505050565b5f60208284031215611bc2575f80fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610ee6575f80fd5b73ffffffffffffffffffffffffffffffffffffffff811681146102ea575f80fd5b5f60208284031215611c22575f80fd5b8135610ee681611bf1565b5f8060208385031215611c3e575f80fd5b823567ffffffffffffffff80821115611c55575f80fd5b818501915085601f830112611c68575f80fd5b813581811115611c76575f80fd5b8660208260061b8501011115611c8a575f80fd5b60209290920196919550909350505050565b803561171581611bf1565b80356bffffffffffffffffffffffff81168114611715575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b6040805190810167ffffffffffffffff81118282101715611d1257611d12611cc2565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611d5f57611d5f611cc2565b604052919050565b5f601f8381840112611d77575f80fd5b8235602067ffffffffffffffff80831115611d9457611d94611cc2565b8260051b611da3838201611d18565b9384528681018301938381019089861115611dbc575f80fd5b84890192505b85831015611e6657823584811115611dd9575f8081fd5b8901603f81018b13611dea575f8081fd5b85810135604086821115611e0057611e00611cc2565b611e2f887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08c85011601611d18565b8281528d82848601011115611e43575f8081fd5b828285018a8301375f928101890192909252508352509184019190840190611dc2565b9998505050505050505050565b5f805f805f8060c08789031215611e88575f80fd5b611e9187611c9c565b9550611e9f60208801611ca7565b9450604087013567ffffffffffffffff80821115611ebb575f80fd5b611ec78a838b01611d67565b95506060890135915080821115611edc575f80fd5b611ee88a838b01611d67565b94506080890135915080821115611efd575f80fd5b611f098a838b01611d67565b935060a0890135915080821115611f1e575f80fd5b50611f2b89828a01611d67565b9150509295509295509295565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f60408284031215611f75575f80fd5b611f7d611cef565b8235611f8881611bf1565b81526020830135611f9881611bf1565b60208201529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361200157612001611fa4565b5060010190565b5f60408284031215612018575f80fd5b612020611cef565b82518152602083015164ffffffffff81168114611f98575f80fd5b808201808211156102d3576102d3611fa4565b818103818111156102d3576102d3611fa4565b80820281158282048414176102d3576102d3611fa4565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f826120b3576120b3612078565b500690565b5f826120c6576120c6612078565b500490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b60ff82811682821603908111156102d3576102d3611fa4565b600181815b8085111561216a57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561215057612150611fa4565b8085161561215d57918102915b93841c9390800290612116565b509250929050565b5f82612180575060016102d3565b8161218c57505f6102d3565b81600181146121a257600281146121ac576121c8565b60019150506102d3565b60ff8411156121bd576121bd611fa4565b50506001821b6102d3565b5060208310610133831016604e8410600b84101617156121eb575081810a6102d3565b6121f58383612111565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0482111561222757612227611fa4565b029392505050565b5f610ee6838361217256fea164736f6c6343000814000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ed403d48e2bc946438b5686aa1ad65056ccf951200000000000000000000000031562ae726afebe25417df01bedc72ef489f45b3
-----Decoded View---------------
Arg [0] : _stateRootOracle (address): 0xeD403d48e2bC946438B5686AA1AD65056Ccf9512
Arg [1] : _timelockAddress (address): 0x31562ae726AFEBe25417df01bEdC72EF489F45b3
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000ed403d48e2bc946438b5686aa1ad65056ccf9512
Arg [1] : 00000000000000000000000031562ae726afebe25417df01bedc72ef489f45b3
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 34 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
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.