Source Code
Latest 25 from a total of 39,261 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Prove State Root | 31446148 | 2 hrs ago | IN | 0 FRAX | 0.00142788 | ||||
| Prove State Root | 31444186 | 3 hrs ago | IN | 0 FRAX | 0.00051591 | ||||
| Prove State Root | 31441348 | 4 hrs ago | IN | 0 FRAX | 0.00009791 | ||||
| Prove State Root | 31439616 | 5 hrs ago | IN | 0 FRAX | 0.00003536 | ||||
| Prove State Root | 31436548 | 7 hrs ago | IN | 0 FRAX | 0.00002559 | ||||
| Prove State Root | 31435798 | 7 hrs ago | IN | 0 FRAX | 0.00002941 | ||||
| Prove State Root | 31428448 | 12 hrs ago | IN | 0 FRAX | 0.00002122 | ||||
| Prove State Root | 31426948 | 12 hrs ago | IN | 0 FRAX | 0.00002168 | ||||
| Prove State Root | 31426048 | 13 hrs ago | IN | 0 FRAX | 0.00002003 | ||||
| Prove State Root | 31424398 | 14 hrs ago | IN | 0 FRAX | 0.00002783 | ||||
| Prove State Root | 31423048 | 15 hrs ago | IN | 0 FRAX | 0.00002524 | ||||
| Prove State Root | 31422898 | 15 hrs ago | IN | 0 FRAX | 0.00002724 | ||||
| Prove State Root | 31422148 | 15 hrs ago | IN | 0 FRAX | 0.00003687 | ||||
| Prove State Root | 31421398 | 15 hrs ago | IN | 0 FRAX | 0.00002065 | ||||
| Prove State Root | 31417962 | 17 hrs ago | IN | 0 FRAX | 0.00003081 | ||||
| Prove State Root | 31417210 | 18 hrs ago | IN | 0 FRAX | 0.00003684 | ||||
| Prove State Root | 31417198 | 18 hrs ago | IN | 0 FRAX | 0.00003824 | ||||
| Prove State Root | 31416299 | 18 hrs ago | IN | 0 FRAX | 0.000024 | ||||
| Prove State Root | 31414949 | 19 hrs ago | IN | 0 FRAX | 0.00002554 | ||||
| Prove State Root | 31414810 | 19 hrs ago | IN | 0 FRAX | 0.0000255 | ||||
| Prove State Root | 31406998 | 23 hrs ago | IN | 0 FRAX | 0.00006758 | ||||
| Prove State Root | 31396413 | 29 hrs ago | IN | 0 FRAX | 0.00004541 | ||||
| Prove State Root | 31392599 | 31 hrs ago | IN | 0 FRAX | 0.00006264 | ||||
| Prove State Root | 31391099 | 32 hrs ago | IN | 0 FRAX | 0.00004858 | ||||
| Prove State Root | 31388549 | 34 hrs ago | IN | 0 FRAX | 0.00003339 |
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 31446149 | 2 hrs ago | 0 FRAX | |||||
| 31446149 | 2 hrs ago | 0 FRAX | |||||
| 31446148 | 2 hrs ago | 0 FRAX | |||||
| 31444186 | 3 hrs ago | 0 FRAX | |||||
| 31441348 | 4 hrs ago | 0 FRAX | |||||
| 31441348 | 4 hrs ago | 0 FRAX | |||||
| 31439616 | 5 hrs ago | 0 FRAX | |||||
| 31436549 | 7 hrs ago | 0 FRAX | |||||
| 31436549 | 7 hrs ago | 0 FRAX | |||||
| 31436548 | 7 hrs ago | 0 FRAX | |||||
| 31435799 | 7 hrs ago | 0 FRAX | |||||
| 31435798 | 7 hrs ago | 0 FRAX | |||||
| 31428448 | 12 hrs ago | 0 FRAX | |||||
| 31428448 | 12 hrs ago | 0 FRAX | |||||
| 31428448 | 12 hrs ago | 0 FRAX | |||||
| 31426949 | 12 hrs ago | 0 FRAX | |||||
| 31426948 | 12 hrs ago | 0 FRAX | |||||
| 31426049 | 13 hrs ago | 0 FRAX | |||||
| 31426049 | 13 hrs ago | 0 FRAX | |||||
| 31426048 | 13 hrs ago | 0 FRAX | |||||
| 31424398 | 14 hrs ago | 0 FRAX | |||||
| 31424398 | 14 hrs ago | 0 FRAX | |||||
| 31424398 | 14 hrs ago | 0 FRAX | |||||
| 31423049 | 15 hrs ago | 0 FRAX | |||||
| 31423049 | 15 hrs ago | 0 FRAX |
Cross-Chain Transactions
Loading...
Loading
Similar Match Source Code This contract matches the deployed Bytecode of the Source Code for Contract 0x28FB3520...213ACB383 The constructor portion of the code might be different and could alter the actual behaviour of the contract
Contract Name:
StateRootOracle
Compiler Version
v0.8.19+commit.7dd6d404
Optimization Enabled:
No with 1000000 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ========================= StateRootOracle ==========================
// ====================================================================
// 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 { ERC165Storage } from "@openzeppelin/contracts/utils/introspection/ERC165Storage.sol";
import { Timelock2Step } from "frax-std/access-control/v1/Timelock2Step.sol";
import { ITimelock2Step } from "frax-std/access-control/v1/interfaces/ITimelock2Step.sol";
import { StateProofVerifier as Verifier } from "./lib/StateProofVerifier.sol";
import { IBlockHashProvider } from "./interfaces/IBlockHashProvider.sol";
import { IStateRootOracle } from "./interfaces/IStateRootOracle.sol";
/// @title StateRootOracle
/// @author Jon Walch (Frax Finance) https://github.com/jonwalch
/// @notice Oracle for proving state root hashes on L2 that originate from L1 block headers
contract StateRootOracle is IStateRootOracle, ERC165Storage, Timelock2Step {
/// @notice Minimum number of block hash providers needed to prove the state root.
uint256 public minimumRequiredProviders;
/// @notice Mapping from block number to BlockInfo struct that stores proven state root data.
mapping(uint256 blockNumber => BlockInfo) public blockNumberToBlockInfo;
/// @notice List of configured block hash providers.
IBlockHashProvider[] public blockHashProviders;
/// @notice The ```constructor``` function
/// @param _providers List of block hash provider addresses
/// @param _minimumRequiredProviders Initial number of required block hash provider
/// @param _timelockAddress Address of Timelock contract on L2
constructor(
IBlockHashProvider[] memory _providers,
uint256 _minimumRequiredProviders,
address _timelockAddress
) Timelock2Step() {
_setTimelock({ _newTimelock: _timelockAddress });
_registerInterface({ interfaceId: type(ITimelock2Step).interfaceId });
_registerInterface({ interfaceId: type(IStateRootOracle).interfaceId });
_setMinimumRequiredProviders(_minimumRequiredProviders);
for (uint256 i = 0; i < _providers.length; ++i) {
_addProvider(_providers[i]);
}
}
// ====================================================================
// Events
// ====================================================================
/// @notice The ```BlockVerified``` event is emitted when a block is proven / verified
/// @param blockNumber The block number of the block that was verified
/// @param timestamp The timestamp corresponding to the block that was verified
/// @param stateRootHash The state root hash of the verified block
event BlockVerified(uint40 blockNumber, uint40 timestamp, bytes32 stateRootHash);
/// @notice The ```ProviderAdded``` event is emitted when a new block hash provider is added
/// @param provider Address of the provider that was added
event ProviderAdded(address provider);
/// @notice The ```ProviderRemoved``` event is emitted when an existing block hash provider is removed
/// @param provider Address of the provider that was removed
event ProviderRemoved(address provider);
/// @notice The ```SetMinimumRequiredProviders``` event is emitted when the value of minimumRequiredProviders is changed
/// @param oldMinimumRequiredProviders The old value of minimumRequiredProviders
/// @param newMinimumRequiredProviders The new value of minimumRequiredProviders
event SetMinimumRequiredProviders(uint256 oldMinimumRequiredProviders, uint256 newMinimumRequiredProviders);
// ====================================================================
// External Getters
// ====================================================================
/// @notice The ```getBlockHashProvidersCount``` function returns the number of configured block hash providers
/// @return _providersCount The number of configured block hash providers
function getBlockHashProvidersCount() external view returns (uint256 _providersCount) {
_providersCount = blockHashProviders.length;
}
/// @notice The ```getBlockInfo``` function returns the BlockInfo corresponding to _blockNumber
/// @param _blockNumber The block number
/// @return _blockInfo The BlockInfo struct corresponding to the _blockNumber
function getBlockInfo(uint256 _blockNumber) external view returns (BlockInfo memory _blockInfo) {
_blockInfo = blockNumberToBlockInfo[_blockNumber];
}
// ====================================================================
// Proof Function
// ====================================================================
/// @notice The ```proveStateRoot``` function proves a state root hash given enough block hash providers
/// @dev Since a _blockHeader can be forged, a higher number of reputable providers implies higher confidence in a block header
/// @param _blockHeader RLP encoded block header retrieved from eth_getBlockByNumber
function proveStateRoot(bytes memory _blockHeader) external {
Verifier.BlockHeader memory _parsedBlockHeader = Verifier.parseBlockHeader(_blockHeader);
BlockInfo memory currentBlockInfo = blockNumberToBlockInfo[_parsedBlockHeader.number];
if (currentBlockInfo.stateRootHash != 0) {
revert StateRootAlreadyProvenForBlockNumber(_parsedBlockHeader.number);
}
uint256 _count = 0;
uint256 _providersLength = blockHashProviders.length;
for (uint256 i = 0; i < _providersLength; ++i) {
if (blockHashProviders[i].blockHashStored(_parsedBlockHeader.hash)) {
++_count;
}
}
if (_count < minimumRequiredProviders) revert NotEnoughProviders();
blockNumberToBlockInfo[_parsedBlockHeader.number] = BlockInfo({
stateRootHash: _parsedBlockHeader.stateRootHash,
timestamp: uint40(_parsedBlockHeader.timestamp)
});
emit BlockVerified({
blockNumber: uint40(_parsedBlockHeader.number),
stateRootHash: _parsedBlockHeader.stateRootHash,
timestamp: uint40(_parsedBlockHeader.timestamp)
});
}
// ====================================================================
// Configuration Setters
// ====================================================================
/// @notice The ```_setMinimumRequiredProviders``` function sets the minimumRequiredProviders
/// @param _minimumRequiredProviders The new minimumRequiredProviders
function _setMinimumRequiredProviders(uint256 _minimumRequiredProviders) internal {
if (_minimumRequiredProviders == 0) revert MinimumRequiredProvidersTooLow();
uint256 _currentMinimumRequiredProviders = minimumRequiredProviders;
if (_minimumRequiredProviders == _currentMinimumRequiredProviders) revert SameMinimumRequiredProviders();
emit SetMinimumRequiredProviders({
oldMinimumRequiredProviders: _currentMinimumRequiredProviders,
newMinimumRequiredProviders: _minimumRequiredProviders
});
minimumRequiredProviders = _minimumRequiredProviders;
}
/// @notice The ```setMinimumRequiredProviders``` function sets the minimumRequiredProviders
/// @dev Requires msg.sender to be the timelock address
/// @param _minimumRequiredProviders The new minimumRequiredProviders
function setMinimumRequiredProviders(uint256 _minimumRequiredProviders) external {
_requireTimelock();
_setMinimumRequiredProviders(_minimumRequiredProviders);
}
/// @notice The ```_addProvider``` function adds a new block hash provider to blockHashProviders
/// @param _provider The block hash provider to add to blockHashProviders
function _addProvider(IBlockHashProvider _provider) internal {
uint256 providersLength = blockHashProviders.length;
for (uint256 i = 0; i < providersLength; ++i) {
if (blockHashProviders[i] == _provider) {
revert ProviderAlreadyAdded();
}
}
emit ProviderAdded(address(_provider));
blockHashProviders.push(_provider);
}
/// @notice The ```addProvider``` function adds a new block hash provider to blockHashProviders
/// @dev Requires msg.sender to be the timelock address
/// @param _provider The block hash provider to add to blockHashProviders
function addProvider(IBlockHashProvider _provider) external {
_requireTimelock();
_addProvider(_provider);
}
/// @notice The ```removeProvider``` function removes an existing block hash provider from blockHashProviders
/// @dev Requires msg.sender to be the timelock address
/// @param _provider The block hash provider to remove from blockHashProviders
function removeProvider(IBlockHashProvider _provider) external {
_requireTimelock();
uint256 providersLength = blockHashProviders.length;
for (uint256 i = 0; i < providersLength; ++i) {
if (blockHashProviders[i] == _provider) {
emit ProviderRemoved(address(_provider));
blockHashProviders[i] = blockHashProviders[providersLength - 1];
blockHashProviders.pop();
return;
}
}
revert ProviderNotFound();
}
// ====================================================================
// Errors
// ====================================================================
error MinimumRequiredProvidersTooLow();
error NotEnoughProviders();
error ProviderAlreadyAdded();
error ProviderNotFound();
error SameMinimumRequiredProviders();
error StateRootAlreadyProvenForBlockNumber(uint256 blockNumber);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)
pragma solidity ^0.8.0;
import "./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: MIT
// Copied from https://github.com/lidofinance/curve-merkle-oracle/blob/1033b3e84142317ffd8f366b52e489d5eb49c73f/contracts/StateProofVerifier.sol
pragma solidity ^0.8.19;
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 IBlockHashProvider {
function blockHashStored(bytes32 _hash) external view returns (bool _result);
}// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;
interface IStateRootOracle {
struct BlockInfo {
bytes32 stateRootHash;
uint40 timestamp;
}
function getBlockInfo(uint256 blockNumber) external view returns (BlockInfo memory _blockInfo);
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
pragma solidity ^0.8.0;
import "./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);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override 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.19;
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 v4.4.1 (utils/introspection/IERC165.sol)
pragma solidity ^0.8.0;
/**
* @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/",
"@arbitrum/=node_modules/@arbitrum/",
"@chainlink/=node_modules/@chainlink/",
"@eth-optimism/=node_modules/@eth-optimism/",
"@mean-finance/=node_modules/@mean-finance/",
"@offchainlabs/=node_modules/@offchainlabs/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@rari-capital/=node_modules/@rari-capital/",
"@safe-global/=node_modules/@safe-global/",
"@uniswap/=node_modules/@uniswap/",
"base64-sol/=node_modules/base64-sol/",
"frax-standard-solidity/=node_modules/frax-standard-solidity/",
"hardhat/=node_modules/hardhat/",
"prb-math/=node_modules/prb-math/",
"solidity-bytes-utils/=node_modules/solidity-bytes-utils/",
"solidity-rlp/=node_modules/solidity-rlp/"
],
"optimizer": {
"enabled": false,
"runs": 1000000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"evmVersion": "paris",
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"contract IBlockHashProvider[]","name":"_providers","type":"address[]"},{"internalType":"uint256","name":"_minimumRequiredProviders","type":"uint256"},{"internalType":"address","name":"_timelockAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"MinimumRequiredProvidersTooLow","type":"error"},{"inputs":[],"name":"NotEnoughProviders","type":"error"},{"inputs":[],"name":"OnlyPendingTimelock","type":"error"},{"inputs":[],"name":"OnlyTimelock","type":"error"},{"inputs":[],"name":"ProviderAlreadyAdded","type":"error"},{"inputs":[],"name":"ProviderNotFound","type":"error"},{"inputs":[],"name":"SameMinimumRequiredProviders","type":"error"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"StateRootAlreadyProvenForBlockNumber","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint40","name":"blockNumber","type":"uint40"},{"indexed":false,"internalType":"uint40","name":"timestamp","type":"uint40"},{"indexed":false,"internalType":"bytes32","name":"stateRootHash","type":"bytes32"}],"name":"BlockVerified","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"provider","type":"address"}],"name":"ProviderAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"provider","type":"address"}],"name":"ProviderRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldMinimumRequiredProviders","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newMinimumRequiredProviders","type":"uint256"}],"name":"SetMinimumRequiredProviders","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":"acceptTransferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IBlockHashProvider","name":"_provider","type":"address"}],"name":"addProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"blockHashProviders","outputs":[{"internalType":"contract IBlockHashProvider","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"blockNumber","type":"uint256"}],"name":"blockNumberToBlockInfo","outputs":[{"internalType":"bytes32","name":"stateRootHash","type":"bytes32"},{"internalType":"uint40","name":"timestamp","type":"uint40"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlockHashProvidersCount","outputs":[{"internalType":"uint256","name":"_providersCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_blockNumber","type":"uint256"}],"name":"getBlockInfo","outputs":[{"components":[{"internalType":"bytes32","name":"stateRootHash","type":"bytes32"},{"internalType":"uint40","name":"timestamp","type":"uint40"}],"internalType":"struct IStateRootOracle.BlockInfo","name":"_blockInfo","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minimumRequiredProviders","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingTimelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_blockHeader","type":"bytes"}],"name":"proveStateRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IBlockHashProvider","name":"_provider","type":"address"}],"name":"removeProvider","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minimumRequiredProviders","type":"uint256"}],"name":"setMinimumRequiredProviders","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
0x60806040523480156200001157600080fd5b50604051620026093803806200260983398181016040528101906200003791906200078e565b33600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062000089816200015560201b60201c565b620000ba7fbe8ff0c4000000000000000000000000000000000000000000000000000000006200021560201b60201c565b620000eb7fbb141cf4000000000000000000000000000000000000000000000000000000006200021560201b60201c565b620000fc82620002ec60201b60201c565b60005b83518110156200014b576200013784828151811062000123576200012262000809565b5b6020026020010151620003ae60201b60201c565b80620001439062000867565b9050620000ff565b50505050620009a3565b8073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc660405160405180910390a380600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19160362000280576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002779062000915565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000810362000327576040517ff2d124d200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6000600354905080820362000368576040517f41e6104d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f497686328021e5a6d7374aa49607cb27998184c5fee3e134799ed157c3ccee1981836040516200039b92919062000948565b60405180910390a1816003819055505050565b6000600580549050905060005b818110156200047f578273ffffffffffffffffffffffffffffffffffffffff1660058281548110620003f257620003f162000809565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16036200046b576040517f5c60f86b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80620004779062000867565b9050620003bb565b507fae9c2c6481964847714ce58f65a7f6dcc41d0d8394449bacdf161b5920c4744a82604051620004b1919062000986565b60405180910390a16005829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000604051905090565b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b620005848262000539565b810181811067ffffffffffffffff82111715620005a657620005a56200054a565b5b80604052505050565b6000620005bb62000520565b9050620005c9828262000579565b919050565b600067ffffffffffffffff821115620005ec57620005eb6200054a565b5b602082029050602081019050919050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006200062f8262000602565b9050919050565b6000620006438262000622565b9050919050565b620006558162000636565b81146200066157600080fd5b50565b60008151905062000675816200064a565b92915050565b6000620006926200068c84620005ce565b620005af565b90508083825260208201905060208402830185811115620006b857620006b7620005fd565b5b835b81811015620006e55780620006d0888262000664565b845260208401935050602081019050620006ba565b5050509392505050565b600082601f83011262000707576200070662000534565b5b8151620007198482602086016200067b565b91505092915050565b6000819050919050565b620007378162000722565b81146200074357600080fd5b50565b60008151905062000757816200072c565b92915050565b620007688162000622565b81146200077457600080fd5b50565b60008151905062000788816200075d565b92915050565b600080600060608486031215620007aa57620007a96200052a565b5b600084015167ffffffffffffffff811115620007cb57620007ca6200052f565b5b620007d986828701620006ef565b9350506020620007ec8682870162000746565b9250506040620007ff8682870162000777565b9150509250925092565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000620008748262000722565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203620008a957620008a862000838565b5b600182019050919050565b600082825260208201905092915050565b7f4552433136353a20696e76616c696420696e7465726661636520696400000000600082015250565b6000620008fd601c83620008b4565b91506200090a82620008c5565b602082019050919050565b600060208201905081810360008301526200093081620008ee565b9050919050565b620009428162000722565b82525050565b60006040820190506200095f600083018562000937565b6200096e602083018462000937565b9392505050565b620009808162000622565b82525050565b60006020820190506200099d600083018462000975565b92915050565b611c5680620009b36000396000f3fe608060405234801561001057600080fd5b50600436106100f55760003560e01c80634f8b4ae711610097578063dd000e7911610066578063dd000e791461024c578063e83c90621461027d578063f6ccaad414610299578063fdd9c9f6146102a3576100f5565b80634f8b4ae7146101d85780637aaae888146101e25780638a355a5714610200578063bb141cf41461021c576100f5565b806345014095116100d3578063450140951461016657806346e2577a146101825780634bc66f321461019e5780634d8864a4146101bc576100f5565b806301ffc9a7146100fa578063090f3f501461012a5780630f53912c14610148575b600080fd5b610114600480360381019061010f9190611513565b6102d3565b604051610121919061155b565b60405180910390f35b61013261034a565b60405161013f91906115b7565b60405180910390f35b610150610370565b60405161015d91906115eb565b60405180910390f35b610180600480360381019061017b9190611632565b61037d565b005b61019c6004803603810190610197919061169d565b610391565b005b6101a66103a5565b6040516101b391906115b7565b60405180910390f35b6101d660048036038101906101d19190611810565b6103cb565b005b6101e0610671565b005b6101ea610697565b6040516101f791906115eb565b60405180910390f35b61021a6004803603810190610215919061169d565b61069d565b005b61023660048036038101906102319190611885565b61089e565b604051610243919061191a565b60405180910390f35b61026660048036038101906102619190611885565b6108fe565b604051610274929190611953565b60405180910390f35b61029760048036038101906102929190611885565b610933565b005b6102a1610947565b005b6102bd60048036038101906102b89190611885565b610959565b6040516102ca91906119db565b60405180910390f35b60006102de82610998565b806103435750600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff165b9050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600580549050905090565b610385610a02565b61038e81610a8b565b50565b610399610a02565b6103a281610b4b565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006103d682610cb3565b905060006004600083604001518152602001908152602001600020604051806040016040529081600082015481526020016001820160009054906101000a900464ffffffffff1664ffffffffff1664ffffffffff168152505090506000801b8160000151146104805781604001516040517f42e86de400000000000000000000000000000000000000000000000000000000815260040161047791906115eb565b60405180910390fd5b600080600580549050905060005b8181101561057557600581815481106104aa576104a96119f6565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ebe86a5586600001516040518263ffffffff1660e01b81526004016105119190611a25565b602060405180830381865afa15801561052e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105529190611a6c565b15610564578261056190611ac8565b92505b8061056e90611ac8565b905061048e565b506003548210156105b2576040517fcf7f51ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051806040016040528085602001518152602001856060015164ffffffffff1681525060046000866040015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548164ffffffffff021916908364ffffffffff1602179055509050507f0b7da7443e74c2309ac1ec0190a5ffd10196779d3adab76a37ff147fb711e71e84604001518560600151866020015160405161066293929190611b10565b60405180910390a15050505050565b610679610a02565b610681610d8b565b61068b6000610a8b565b6106956000610e14565b565b60035481565b6106a5610a02565b6000600580549050905060005b81811015610868578273ffffffffffffffffffffffffffffffffffffffff16600582815481106106e5576106e46119f6565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610857577f1589f8555933761a3cff8aa925061be3b46e2dd43f621322ab611d300f62b1d98360405161075a91906115b7565b60405180910390a160056001836107719190611b47565b81548110610782576107816119f6565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600582815481106107c1576107c06119f6565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600580548061081b5761081a611b7b565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690559055505061089b565b8061086190611ac8565b90506106b2565b506040517fb1cd090300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6108a661143b565b60046000838152602001908152602001600020604051806040016040529081600082015481526020016001820160009054906101000a900464ffffffffff1664ffffffffff1664ffffffffff16815250509050919050565b60046020528060005260406000206000915090508060000154908060010160009054906101000a900464ffffffffff16905082565b61093b610a02565b61094481610ed4565b50565b61094f610d8b565b610957610f92565b565b6005818154811061096957600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a89576040517f1c0be90a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a60405160405180910390a350565b6000600580549050905060005b81811015610c14578273ffffffffffffffffffffffffffffffffffffffff1660058281548110610b8b57610b8a6119f6565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610c03576040517f5c60f86b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80610c0d90611ac8565b9050610b58565b507fae9c2c6481964847714ce58f65a7f6dcc41d0d8394449bacdf161b5920c4744a82604051610c4491906115b7565b60405180910390a16005829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b610cbb61145f565b610cc361145f565b6000610cd6610cd185610fdf565b61100d565b9050600b815111610ce657600080fd5b610d0a81600381518110610cfd57610cfc6119f6565b5b6020026020010151611122565b60001b826020018181525050610d3a81600881518110610d2d57610d2c6119f6565b5b6020026020010151611122565b826040018181525050610d6781600b81518110610d5a57610d596119f6565b5b6020026020010151611122565b82606001818152505083805190602001208260000181815250508192505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e12576040517ff5c49e6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b8073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc660405160405180910390a380600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008103610f0e576040517ff2d124d200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006003549050808203610f4e576040517f41e6104d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f497686328021e5a6d7374aa49607cb27998184c5fee3e134799ed157c3ccee198183604051610f7f929190611baa565b60405180910390a1816003819055505050565b6000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610fdd33610e14565b565b610fe761148d565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606110188261117c565b61102157600080fd5b600061102c836111c9565b905060008167ffffffffffffffff81111561104a576110496116e5565b5b60405190808252806020026020018201604052801561108357816020015b61107061148d565b8152602001906001900390816110685790505b50905060006110958560200151611256565b85602001516110a49190611bd3565b9050600080600090505b84811015611115576110bf83611315565b91506040518060400160405280838152602001848152508482815181106110e9576110e86119f6565b5b602002602001018190525081836111009190611bd3565b9250808061110d90611ac8565b9150506110ae565b5082945050505050919050565b600080826000015111801561113c57506021826000015111155b61114557600080fd5b600080611151846113f1565b91509150600082519050602082101561117157816020036101000a810490505b809350505050919050565b60008082600001510361119257600090506111c4565b60008083602001519050805160001a915060c060ff168260ff1610156111bd576000925050506111c4565b6001925050505b919050565b6000808260000151036111df5760009050611251565b6000806111ef8460200151611256565b84602001516111fe9190611bd3565b90506000846000015185602001516112169190611bd3565b90505b8082101561124a5761122a82611315565b826112359190611bd3565b9150828061124290611ac8565b935050611219565b8293505050505b919050565b600080825160001a9050608060ff16811015611276576000915050611310565b60b860ff1681108061129b575060c060ff16811015801561129a575060f860ff1681105b5b156112aa576001915050611310565b60c060ff168110156112e55760018060b86112c59190611c14565b60ff16826112d39190611b47565b6112dd9190611bd3565b915050611310565b60018060f86112f49190611c14565b60ff16826113029190611b47565b61130c9190611bd3565b9150505b919050565b6000806000835160001a9050608060ff1681101561133657600191506113e7565b60b860ff16811015611365576001608060ff16826113549190611b47565b61135e9190611bd3565b91506113e6565b60c060ff168110156113955760b78103600185019450806020036101000a855104600182018101935050506113e5565b60f860ff168110156113c457600160c060ff16826113b39190611b47565b6113bd9190611bd3565b91506113e4565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b60008060006114038460200151611256565b905060008185602001516114179190611bd3565b9050600082866000015161142b9190611b47565b9050818194509450505050915091565b604051806040016040528060008019168152602001600064ffffffffff1681525090565b6040518060800160405280600080191681526020016000801916815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6114f0816114bb565b81146114fb57600080fd5b50565b60008135905061150d816114e7565b92915050565b600060208284031215611529576115286114b1565b5b6000611537848285016114fe565b91505092915050565b60008115159050919050565b61155581611540565b82525050565b6000602082019050611570600083018461154c565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006115a182611576565b9050919050565b6115b181611596565b82525050565b60006020820190506115cc60008301846115a8565b92915050565b6000819050919050565b6115e5816115d2565b82525050565b600060208201905061160060008301846115dc565b92915050565b61160f81611596565b811461161a57600080fd5b50565b60008135905061162c81611606565b92915050565b600060208284031215611648576116476114b1565b5b60006116568482850161161d565b91505092915050565b600061166a82611596565b9050919050565b61167a8161165f565b811461168557600080fd5b50565b60008135905061169781611671565b92915050565b6000602082840312156116b3576116b26114b1565b5b60006116c184828501611688565b91505092915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61171d826116d4565b810181811067ffffffffffffffff8211171561173c5761173b6116e5565b5b80604052505050565b600061174f6114a7565b905061175b8282611714565b919050565b600067ffffffffffffffff82111561177b5761177a6116e5565b5b611784826116d4565b9050602081019050919050565b82818337600083830152505050565b60006117b36117ae84611760565b611745565b9050828152602081018484840111156117cf576117ce6116cf565b5b6117da848285611791565b509392505050565b600082601f8301126117f7576117f66116ca565b5b81356118078482602086016117a0565b91505092915050565b600060208284031215611826576118256114b1565b5b600082013567ffffffffffffffff811115611844576118436114b6565b5b611850848285016117e2565b91505092915050565b611862816115d2565b811461186d57600080fd5b50565b60008135905061187f81611859565b92915050565b60006020828403121561189b5761189a6114b1565b5b60006118a984828501611870565b91505092915050565b6000819050919050565b6118c5816118b2565b82525050565b600064ffffffffff82169050919050565b6118e5816118cb565b82525050565b60408201600082015161190160008501826118bc565b50602082015161191460208501826118dc565b50505050565b600060408201905061192f60008301846118eb565b92915050565b61193e816118b2565b82525050565b61194d816118cb565b82525050565b60006040820190506119686000830185611935565b6119756020830184611944565b9392505050565b6000819050919050565b60006119a161199c61199784611576565b61197c565b611576565b9050919050565b60006119b382611986565b9050919050565b60006119c5826119a8565b9050919050565b6119d5816119ba565b82525050565b60006020820190506119f060008301846119cc565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082019050611a3a6000830184611935565b92915050565b611a4981611540565b8114611a5457600080fd5b50565b600081519050611a6681611a40565b92915050565b600060208284031215611a8257611a816114b1565b5b6000611a9084828501611a57565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611ad3826115d2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611b0557611b04611a99565b5b600182019050919050565b6000606082019050611b256000830186611944565b611b326020830185611944565b611b3f6040830184611935565b949350505050565b6000611b52826115d2565b9150611b5d836115d2565b9250828203905081811115611b7557611b74611a99565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000604082019050611bbf60008301856115dc565b611bcc60208301846115dc565b9392505050565b6000611bde826115d2565b9150611be9836115d2565b9250828201905080821115611c0157611c00611a99565b5b92915050565b600060ff82169050919050565b6000611c1f82611c07565b9150611c2a83611c07565b9250828203905060ff811115611c4357611c42611a99565b5b9291505056fea164736f6c6343000813000a0000000000000000000000000000000000000000000000000000000000000060000000000000000000000000000000000000000000000000000000000000000100000000000000000000000031562ae726afebe25417df01bedc72ef489f45b300000000000000000000000000000000000000000000000000000000000000010000000000000000000000004200000000000000000000000000000000000015
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100f55760003560e01c80634f8b4ae711610097578063dd000e7911610066578063dd000e791461024c578063e83c90621461027d578063f6ccaad414610299578063fdd9c9f6146102a3576100f5565b80634f8b4ae7146101d85780637aaae888146101e25780638a355a5714610200578063bb141cf41461021c576100f5565b806345014095116100d3578063450140951461016657806346e2577a146101825780634bc66f321461019e5780634d8864a4146101bc576100f5565b806301ffc9a7146100fa578063090f3f501461012a5780630f53912c14610148575b600080fd5b610114600480360381019061010f9190611513565b6102d3565b604051610121919061155b565b60405180910390f35b61013261034a565b60405161013f91906115b7565b60405180910390f35b610150610370565b60405161015d91906115eb565b60405180910390f35b610180600480360381019061017b9190611632565b61037d565b005b61019c6004803603810190610197919061169d565b610391565b005b6101a66103a5565b6040516101b391906115b7565b60405180910390f35b6101d660048036038101906101d19190611810565b6103cb565b005b6101e0610671565b005b6101ea610697565b6040516101f791906115eb565b60405180910390f35b61021a6004803603810190610215919061169d565b61069d565b005b61023660048036038101906102319190611885565b61089e565b604051610243919061191a565b60405180910390f35b61026660048036038101906102619190611885565b6108fe565b604051610274929190611953565b60405180910390f35b61029760048036038101906102929190611885565b610933565b005b6102a1610947565b005b6102bd60048036038101906102b89190611885565b610959565b6040516102ca91906119db565b60405180910390f35b60006102de82610998565b806103435750600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff165b9050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b6000600580549050905090565b610385610a02565b61038e81610a8b565b50565b610399610a02565b6103a281610b4b565b50565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60006103d682610cb3565b905060006004600083604001518152602001908152602001600020604051806040016040529081600082015481526020016001820160009054906101000a900464ffffffffff1664ffffffffff1664ffffffffff168152505090506000801b8160000151146104805781604001516040517f42e86de400000000000000000000000000000000000000000000000000000000815260040161047791906115eb565b60405180910390fd5b600080600580549050905060005b8181101561057557600581815481106104aa576104a96119f6565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663ebe86a5586600001516040518263ffffffff1660e01b81526004016105119190611a25565b602060405180830381865afa15801561052e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906105529190611a6c565b15610564578261056190611ac8565b92505b8061056e90611ac8565b905061048e565b506003548210156105b2576040517fcf7f51ab00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604051806040016040528085602001518152602001856060015164ffffffffff1681525060046000866040015181526020019081526020016000206000820151816000015560208201518160010160006101000a81548164ffffffffff021916908364ffffffffff1602179055509050507f0b7da7443e74c2309ac1ec0190a5ffd10196779d3adab76a37ff147fb711e71e84604001518560600151866020015160405161066293929190611b10565b60405180910390a15050505050565b610679610a02565b610681610d8b565b61068b6000610a8b565b6106956000610e14565b565b60035481565b6106a5610a02565b6000600580549050905060005b81811015610868578273ffffffffffffffffffffffffffffffffffffffff16600582815481106106e5576106e46119f6565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610857577f1589f8555933761a3cff8aa925061be3b46e2dd43f621322ab611d300f62b1d98360405161075a91906115b7565b60405180910390a160056001836107719190611b47565b81548110610782576107816119f6565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600582815481106107c1576107c06119f6565b5b9060005260206000200160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550600580548061081b5761081a611b7b565b5b6001900381819060005260206000200160006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690559055505061089b565b8061086190611ac8565b90506106b2565b506040517fb1cd090300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50565b6108a661143b565b60046000838152602001908152602001600020604051806040016040529081600082015481526020016001820160009054906101000a900464ffffffffff1664ffffffffff1664ffffffffff16815250509050919050565b60046020528060005260406000206000915090508060000154908060010160009054906101000a900464ffffffffff16905082565b61093b610a02565b61094481610ed4565b50565b61094f610d8b565b610957610f92565b565b6005818154811061096957600080fd5b906000526020600020016000915054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610a89576040517f1c0be90a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b80600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a60405160405180910390a350565b6000600580549050905060005b81811015610c14578273ffffffffffffffffffffffffffffffffffffffff1660058281548110610b8b57610b8a6119f6565b5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1603610c03576040517f5c60f86b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80610c0d90611ac8565b9050610b58565b507fae9c2c6481964847714ce58f65a7f6dcc41d0d8394449bacdf161b5920c4744a82604051610c4491906115b7565b60405180910390a16005829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b610cbb61145f565b610cc361145f565b6000610cd6610cd185610fdf565b61100d565b9050600b815111610ce657600080fd5b610d0a81600381518110610cfd57610cfc6119f6565b5b6020026020010151611122565b60001b826020018181525050610d3a81600881518110610d2d57610d2c6119f6565b5b6020026020010151611122565b826040018181525050610d6781600b81518110610d5a57610d596119f6565b5b6020026020010151611122565b82606001818152505083805190602001208260000181815250508192505050919050565b600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614610e12576040517ff5c49e6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b565b8073ffffffffffffffffffffffffffffffffffffffff16600260009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc660405160405180910390a380600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60008103610f0e576040517ff2d124d200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006003549050808203610f4e576040517f41e6104d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f497686328021e5a6d7374aa49607cb27998184c5fee3e134799ed157c3ccee198183604051610f7f929190611baa565b60405180910390a1816003819055505050565b6000600160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550610fdd33610e14565b565b610fe761148d565b600060208301905060405180604001604052808451815260200182815250915050919050565b60606110188261117c565b61102157600080fd5b600061102c836111c9565b905060008167ffffffffffffffff81111561104a576110496116e5565b5b60405190808252806020026020018201604052801561108357816020015b61107061148d565b8152602001906001900390816110685790505b50905060006110958560200151611256565b85602001516110a49190611bd3565b9050600080600090505b84811015611115576110bf83611315565b91506040518060400160405280838152602001848152508482815181106110e9576110e86119f6565b5b602002602001018190525081836111009190611bd3565b9250808061110d90611ac8565b9150506110ae565b5082945050505050919050565b600080826000015111801561113c57506021826000015111155b61114557600080fd5b600080611151846113f1565b91509150600082519050602082101561117157816020036101000a810490505b809350505050919050565b60008082600001510361119257600090506111c4565b60008083602001519050805160001a915060c060ff168260ff1610156111bd576000925050506111c4565b6001925050505b919050565b6000808260000151036111df5760009050611251565b6000806111ef8460200151611256565b84602001516111fe9190611bd3565b90506000846000015185602001516112169190611bd3565b90505b8082101561124a5761122a82611315565b826112359190611bd3565b9150828061124290611ac8565b935050611219565b8293505050505b919050565b600080825160001a9050608060ff16811015611276576000915050611310565b60b860ff1681108061129b575060c060ff16811015801561129a575060f860ff1681105b5b156112aa576001915050611310565b60c060ff168110156112e55760018060b86112c59190611c14565b60ff16826112d39190611b47565b6112dd9190611bd3565b915050611310565b60018060f86112f49190611c14565b60ff16826113029190611b47565b61130c9190611bd3565b9150505b919050565b6000806000835160001a9050608060ff1681101561133657600191506113e7565b60b860ff16811015611365576001608060ff16826113549190611b47565b61135e9190611bd3565b91506113e6565b60c060ff168110156113955760b78103600185019450806020036101000a855104600182018101935050506113e5565b60f860ff168110156113c457600160c060ff16826113b39190611b47565b6113bd9190611bd3565b91506113e4565b60f78103600185019450806020036101000a855104600182018101935050505b5b5b5b8192505050919050565b60008060006114038460200151611256565b905060008185602001516114179190611bd3565b9050600082866000015161142b9190611b47565b9050818194509450505050915091565b604051806040016040528060008019168152602001600064ffffffffff1681525090565b6040518060800160405280600080191681526020016000801916815260200160008152602001600081525090565b604051806040016040528060008152602001600081525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6114f0816114bb565b81146114fb57600080fd5b50565b60008135905061150d816114e7565b92915050565b600060208284031215611529576115286114b1565b5b6000611537848285016114fe565b91505092915050565b60008115159050919050565b61155581611540565b82525050565b6000602082019050611570600083018461154c565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006115a182611576565b9050919050565b6115b181611596565b82525050565b60006020820190506115cc60008301846115a8565b92915050565b6000819050919050565b6115e5816115d2565b82525050565b600060208201905061160060008301846115dc565b92915050565b61160f81611596565b811461161a57600080fd5b50565b60008135905061162c81611606565b92915050565b600060208284031215611648576116476114b1565b5b60006116568482850161161d565b91505092915050565b600061166a82611596565b9050919050565b61167a8161165f565b811461168557600080fd5b50565b60008135905061169781611671565b92915050565b6000602082840312156116b3576116b26114b1565b5b60006116c184828501611688565b91505092915050565b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b61171d826116d4565b810181811067ffffffffffffffff8211171561173c5761173b6116e5565b5b80604052505050565b600061174f6114a7565b905061175b8282611714565b919050565b600067ffffffffffffffff82111561177b5761177a6116e5565b5b611784826116d4565b9050602081019050919050565b82818337600083830152505050565b60006117b36117ae84611760565b611745565b9050828152602081018484840111156117cf576117ce6116cf565b5b6117da848285611791565b509392505050565b600082601f8301126117f7576117f66116ca565b5b81356118078482602086016117a0565b91505092915050565b600060208284031215611826576118256114b1565b5b600082013567ffffffffffffffff811115611844576118436114b6565b5b611850848285016117e2565b91505092915050565b611862816115d2565b811461186d57600080fd5b50565b60008135905061187f81611859565b92915050565b60006020828403121561189b5761189a6114b1565b5b60006118a984828501611870565b91505092915050565b6000819050919050565b6118c5816118b2565b82525050565b600064ffffffffff82169050919050565b6118e5816118cb565b82525050565b60408201600082015161190160008501826118bc565b50602082015161191460208501826118dc565b50505050565b600060408201905061192f60008301846118eb565b92915050565b61193e816118b2565b82525050565b61194d816118cb565b82525050565b60006040820190506119686000830185611935565b6119756020830184611944565b9392505050565b6000819050919050565b60006119a161199c61199784611576565b61197c565b611576565b9050919050565b60006119b382611986565b9050919050565b60006119c5826119a8565b9050919050565b6119d5816119ba565b82525050565b60006020820190506119f060008301846119cc565b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000602082019050611a3a6000830184611935565b92915050565b611a4981611540565b8114611a5457600080fd5b50565b600081519050611a6681611a40565b92915050565b600060208284031215611a8257611a816114b1565b5b6000611a9084828501611a57565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000611ad3826115d2565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203611b0557611b04611a99565b5b600182019050919050565b6000606082019050611b256000830186611944565b611b326020830185611944565b611b3f6040830184611935565b949350505050565b6000611b52826115d2565b9150611b5d836115d2565b9250828203905081811115611b7557611b74611a99565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6000604082019050611bbf60008301856115dc565b611bcc60208301846115dc565b9392505050565b6000611bde826115d2565b9150611be9836115d2565b9250828201905080821115611c0157611c00611a99565b5b92915050565b600060ff82169050919050565b6000611c1f82611c07565b9150611c2a83611c07565b9250828203905060ff811115611c4357611c42611a99565b5b9291505056fea164736f6c6343000813000a
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ 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.