Source Code
Latest 1 from a total of 1 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Transfer Ownersh... | 2289384 | 670 days ago | IN | 0 FRAX | 0.00000526 |
Latest 1 internal transaction
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 2289073 | 670 days ago | Contract Creation | 0 FRAX |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
L1VeFXS
Compiler Version
v0.8.20+commit.a1b79de6
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ============================== L1VeFXS =============================
// ====================================================================
import { Ownable2StepUpgradeable } from "@openzeppelin/contracts-upgradeable/access/Ownable2StepUpgradeable.sol";
import { MerkleTreeProver } from "./lib/MerkleTreeProver.sol";
import { StateProofVerifier as Verifier } from "./lib/StateProofVerifier.sol";
import { IPriceSourceReceiver } from "./interfaces/IPriceSourceReceiver.sol";
import { IStateRootOracle } from "./interfaces/IStateRootOracle.sol";
/// @title L1VeFXS
/// @notice Holds proved veFXS balances from L1
/// @author Frax Finance (https://github.com/fraxfinance)
contract L1VeFXS is Ownable2StepUpgradeable {
/// @notice Slot index of the locked HashMap in the veFXS contract
uint256 public constant LOCKED_SLOT_INDEX = 2;
/// @notice veFXS address on L1
address public constant veFXSAddress = 0xc8418aF6358FFddA74e09Ca9CC3Fe03Ca6aDC5b0;
/// @notice max duration of lock = 4 years
uint256 constant MAXTIME = 4 * 365 * 86_400;
// keccak256(abi.encode(uint256(keccak256("frax.universal.L1VeFXS.storage")) - 1))
bytes32 private constant AppStorageLocation = 0xc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d40;
/// @dev amount and end of lock
struct LockedBalance {
uint128 amount;
uint64 end;
uint64 blockTimestamp;
}
struct AppStorage {
mapping(address => LockedBalance) locked;
/// @notice The address of the StateRootOracle on Layer 2
IStateRootOracle stateRootOracle;
}
function appStorage() private pure returns (AppStorage storage $) {
assembly {
$.slot := AppStorageLocation
}
}
/// @notice bridged locked data
function locked(address account) external view returns (LockedBalance memory) {
AppStorage storage $ = appStorage();
return $.locked[account];
}
/// @notice The ```veFXSUpdated ``` event is emitted when a veFXS data is updated
/// @param addr Users address
/// @param amount amount of FXS
/// @param end end time of the lock
/// @param blockTimestamp time stamp of the L1block that is used to proof the balance
event veFXSUpdated(address indexed addr, uint128 amount, uint64 end, uint64 blockTimestamp);
constructor() {
_disableInitializers();
}
/// @param _stateRootOracle Address of the L2 StateRootOracle
function initialize(address _stateRootOracle, address _owner) external initializer {
// initialize only once
AppStorage storage $ = appStorage();
require(address($.stateRootOracle) == address(0) && _stateRootOracle != address(0));
$.stateRootOracle = IStateRootOracle(_stateRootOracle);
_transferOwnership(_owner);
}
/// @notice The ```proofVeFXS``` function uses merkle proofs to prove L1 veFXS balance.
/// @dev Proves the storage root using block info from the L2 StateRootOracle. Then uses storage root hash to prove the amount and end lock time
/// @param _address the address to proof the veFXS locked amounts
/// @param _blockNumber The block number
/// @param _accountProof The accountProof retrieved from eth_getProof
/// @param _storageProof1 The storageProof.proof retrieved from eth_getProof, to proof the amount
/// @param _storageProof2 The storageProof.proof retrieved from eth_getProof, to proof the end lock time
function proofVeFXS(
address _address,
uint256 _blockNumber,
bytes[] memory _accountProof,
bytes[] memory _storageProof1,
bytes[] memory _storageProof2
) external {
AppStorage storage $ = appStorage();
IStateRootOracle.BlockInfo memory _blockInfo = $.stateRootOracle.getBlockInfo(_blockNumber);
require(
_blockInfo.timestamp > $.locked[_address].blockTimestamp,
"L1VeFXS: Can only update with later information"
);
Verifier.Account memory _accountPool = MerkleTreeProver.proveStorageRoot({
stateRootHash: _blockInfo.stateRootHash,
proofAddress: veFXSAddress,
accountProof: _accountProof
});
// slot index of LockedBalance of given address
uint256 _slot = uint256(
keccak256(abi.encodePacked(keccak256(abi.encodePacked(LOCKED_SLOT_INDEX, uint256(uint160(_address))))))
);
// amount is in the first slot;
uint256 _amount = uint256(
MerkleTreeProver
.proveStorageSlotValue({
storageRootHash: _accountPool.storageRoot,
slot: bytes32(_slot),
storageProof: _storageProof1
})
.value
);
// end is in the second slot;
uint256 _end = uint256(
MerkleTreeProver
.proveStorageSlotValue({
storageRootHash: _accountPool.storageRoot,
slot: bytes32(_slot + 1),
storageProof: _storageProof2
})
.value
);
// Sanity checks
require(_amount > 0, "L1VeFXS: amount is zero");
require(_amount < uint128(type(int128).max), "L1VeFXS: amount too large");
require(_end > block.timestamp, "L1VeFXS: lock expired");
require(_end - block.timestamp <= MAXTIME, "L1VeFXS: lock too long");
// Update storage
$.locked[_address].amount = uint128(_amount);
$.locked[_address].end = uint64(_end);
$.locked[_address].blockTimestamp = _blockInfo.timestamp;
// Emit events
emit veFXSUpdated(_address, $.locked[_address].amount, $.locked[_address].end, _blockInfo.timestamp);
}
/// @notice Get the voting power (at current block) of a proven L1 veFXS account
/// @param _address Account whose voting power we are querying
/// @return _balance uint256 voting power as
function balanceOf(address _address) external view returns (uint256 _balance) {
AppStorage storage $ = appStorage();
LockedBalance memory _lockedBalance = $.locked[_address];
if (_lockedBalance.end > block.timestamp) {
_balance =
_lockedBalance.amount +
(uint256(_lockedBalance.amount) * 3 * (_lockedBalance.end - block.timestamp)) /
MAXTIME;
}
}
/// @notice Utility method to allow owner to batch-add voting power balances of accounts
/// @dev Once an account proves a balance, the owner is unable to overwrite the proven balance.
function adminProofVeFXS(
address[] calldata _addresses,
LockedBalance[] calldata _lockedBalances
) external onlyOwner {
AppStorage storage $ = appStorage();
uint256 length = _addresses.length;
if (length != _lockedBalances.length) revert UnequalLengths();
for (uint256 i = 0; i < _addresses.length; ) {
address _address = _addresses[i];
LockedBalance memory _lockedBalance = _lockedBalances[i];
// Only prove balances that have not yet been proven by users
if ($.locked[_address].amount == 0) {
$.locked[_address] = _lockedBalance;
emit veFXSUpdated(_address, _lockedBalance.amount, _lockedBalance.end, _lockedBalance.blockTimestamp);
}
unchecked {
++i;
}
}
}
error UnequalLengths();
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable2Step.sol)
pragma solidity ^0.8.20;
import {OwnableUpgradeable} from "./OwnableUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is specified at deployment time in the constructor for `Ownable`. This
* can later be changed with {transferOwnership} and {acceptOwnership}.
*
* This module is used through inheritance. It will make available all functions
* from parent (Ownable).
*/
abstract contract Ownable2StepUpgradeable is Initializable, OwnableUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Ownable2Step
struct Ownable2StepStorage {
address _pendingOwner;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable2Step")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant Ownable2StepStorageLocation = 0x237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00;
function _getOwnable2StepStorage() private pure returns (Ownable2StepStorage storage $) {
assembly {
$.slot := Ownable2StepStorageLocation
}
}
event OwnershipTransferStarted(address indexed previousOwner, address indexed newOwner);
function __Ownable2Step_init() internal onlyInitializing {
}
function __Ownable2Step_init_unchained() internal onlyInitializing {
}
/**
* @dev Returns the address of the pending owner.
*/
function pendingOwner() public view virtual returns (address) {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
return $._pendingOwner;
}
/**
* @dev Starts the ownership transfer of the contract to a new account. Replaces the pending transfer if there is one.
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual override onlyOwner {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
$._pendingOwner = newOwner;
emit OwnershipTransferStarted(owner(), newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`) and deletes any pending owner.
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual override {
Ownable2StepStorage storage $ = _getOwnable2StepStorage();
delete $._pendingOwner;
super._transferOwnership(newOwner);
}
/**
* @dev The new owner accepts the ownership transfer.
*/
function acceptOwnership() public virtual {
address sender = _msgSender();
if (pendingOwner() != sender) {
revert OwnableUnauthorizedAccount(sender);
}
_transferOwnership(sender);
}
}//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.20;
interface IPriceSourceReceiver {
function addRoundData(bool isBadData, uint104 priceLow, uint104 priceHigh, uint40 timestamp) external;
function getPrices() external view returns (bool isBadData, uint256 priceLow, uint256 priceHigh);
}// 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: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)
pragma solidity ^0.8.20;
import {ContextUpgradeable} from "../utils/ContextUpgradeable.sol";
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* The initial owner is set to the address provided by the deployer. This can
* later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
/// @custom:storage-location erc7201:openzeppelin.storage.Ownable
struct OwnableStorage {
address _owner;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Ownable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant OwnableStorageLocation = 0x9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c199300;
function _getOwnableStorage() private pure returns (OwnableStorage storage $) {
assembly {
$.slot := OwnableStorageLocation
}
}
/**
* @dev The caller account is not authorized to perform an operation.
*/
error OwnableUnauthorizedAccount(address account);
/**
* @dev The owner is not a valid owner account. (eg. `address(0)`)
*/
error OwnableInvalidOwner(address owner);
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the address provided by the deployer as the initial owner.
*/
function __Ownable_init(address initialOwner) internal onlyInitializing {
__Ownable_init_unchained(initialOwner);
}
function __Ownable_init_unchained(address initialOwner) internal onlyInitializing {
if (initialOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(initialOwner);
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
OwnableStorage storage $ = _getOwnableStorage();
return $._owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
if (owner() != _msgSender()) {
revert OwnableUnauthorizedAccount(_msgSender());
}
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
if (newOwner == address(0)) {
revert OwnableInvalidOwner(address(0));
}
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
OwnableStorage storage $ = _getOwnableStorage();
address oldOwner = $._owner;
$._owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.0.0) (proxy/utils/Initializable.sol)
pragma solidity ^0.8.20;
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Storage of the initializable contract.
*
* It's implemented on a custom ERC-7201 namespace to reduce the risk of storage collisions
* when using with upgradeable contracts.
*
* @custom:storage-location erc7201:openzeppelin.storage.Initializable
*/
struct InitializableStorage {
/**
* @dev Indicates that the contract has been initialized.
*/
uint64 _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool _initializing;
}
// keccak256(abi.encode(uint256(keccak256("openzeppelin.storage.Initializable")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant INITIALIZABLE_STORAGE = 0xf0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00;
/**
* @dev The contract is already initialized.
*/
error InvalidInitialization();
/**
* @dev The contract is not initializing.
*/
error NotInitializing();
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint64 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that in the context of a constructor an `initializer` may be invoked any
* number of times. This behavior in the constructor can be useful during testing and is not expected to be used in
* production.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
// Cache values to avoid duplicated sloads
bool isTopLevelCall = !$._initializing;
uint64 initialized = $._initialized;
// Allowed calls:
// - initialSetup: the contract is not in the initializing state and no previous version was
// initialized
// - construction: the contract is initialized at version 1 (no reininitialization) and the
// current contract is just being deployed
bool initialSetup = initialized == 0 && isTopLevelCall;
bool construction = initialized == 1 && address(this).code.length == 0;
if (!initialSetup && !construction) {
revert InvalidInitialization();
}
$._initialized = 1;
if (isTopLevelCall) {
$._initializing = true;
}
_;
if (isTopLevelCall) {
$._initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: Setting the version to 2**64 - 1 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint64 version) {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing || $._initialized >= version) {
revert InvalidInitialization();
}
$._initialized = version;
$._initializing = true;
_;
$._initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
_checkInitializing();
_;
}
/**
* @dev Reverts if the contract is not in an initializing state. See {onlyInitializing}.
*/
function _checkInitializing() internal view virtual {
if (!_isInitializing()) {
revert NotInitializing();
}
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
// solhint-disable-next-line var-name-mixedcase
InitializableStorage storage $ = _getInitializableStorage();
if ($._initializing) {
revert InvalidInitialization();
}
if ($._initialized != type(uint64).max) {
$._initialized = type(uint64).max;
emit Initialized(type(uint64).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint64) {
return _getInitializableStorage()._initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _getInitializableStorage()._initializing;
}
/**
* @dev Returns a pointer to the storage namespace.
*/
// solhint-disable-next-line var-name-mixedcase
function _getInitializableStorage() private pure returns (InitializableStorage storage $) {
assembly {
$.slot := INITIALIZABLE_STORAGE
}
}
}// 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.1) (utils/Context.sol)
pragma solidity ^0.8.20;
import {Initializable} from "../proxy/utils/Initializable.sol";
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
function _contextSuffixLength() internal view virtual returns (uint256) {
return 0;
}
}{
"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/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@arbitrum/=node_modules/@arbitrum/",
"@chainlink/=node_modules/@chainlink/",
"@eth-optimism/=node_modules/@eth-optimism/",
"@mean-finance/=node_modules/@mean-finance/",
"@offchainlabs/=node_modules/@offchainlabs/",
"@rari-capital/=node_modules/@rari-capital/",
"@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": true,
"runs": 1000000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"evmVersion": "paris",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidInitialization","type":"error"},{"inputs":[],"name":"NotInitializing","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[],"name":"UnequalLengths","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint64","name":"version","type":"uint64"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"addr","type":"address"},{"indexed":false,"internalType":"uint128","name":"amount","type":"uint128"},{"indexed":false,"internalType":"uint64","name":"end","type":"uint64"},{"indexed":false,"internalType":"uint64","name":"blockTimestamp","type":"uint64"}],"name":"veFXSUpdated","type":"event"},{"inputs":[],"name":"LOCKED_SLOT_INDEX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"},{"components":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint64","name":"end","type":"uint64"},{"internalType":"uint64","name":"blockTimestamp","type":"uint64"}],"internalType":"struct L1VeFXS.LockedBalance[]","name":"_lockedBalances","type":"tuple[]"}],"name":"adminProofVeFXS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"_balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_stateRootOracle","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"locked","outputs":[{"components":[{"internalType":"uint128","name":"amount","type":"uint128"},{"internalType":"uint64","name":"end","type":"uint64"},{"internalType":"uint64","name":"blockTimestamp","type":"uint64"}],"internalType":"struct L1VeFXS.LockedBalance","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"},{"internalType":"uint256","name":"_blockNumber","type":"uint256"},{"internalType":"bytes[]","name":"_accountProof","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProof1","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProof2","type":"bytes[]"}],"name":"proofVeFXS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"veFXSAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b506200001c62000022565b620000d6565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000900460ff1615620000735760405163f92ee8a960e01b815260040160405180910390fd5b80546001600160401b0390811614620000d35780546001600160401b0319166001600160401b0390811782556040519081527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50565b61290180620000e66000396000f3fe608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063cc275e8d1161005b578063cc275e8d146102a2578063e30c3978146102b5578063f2fde38b146102bd57600080fd5b80638da5cb5b14610177578063cbd006e31461017f578063cbf9fe5f1461018757600080fd5b8063715018a6116100b2578063715018a61461015457806379ba50971461015c5780637eff66661461016457600080fd5b80633c45b87c146100d9578063485cc9551461011e57806370a0823114610133575b600080fd5b6100f473c8418af6358ffdda74e09ca9cc3fe03ca6adc5b081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61013161012c366004612211565b6102d0565b005b610146610141366004612244565b610519565b604051908152602001610115565b61013161064b565b61013161065f565b61013161017236600461225f565b6106df565b6100f4610901565b610146600281565b61025c610195366004612244565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff9490941684527fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d4082529282902082519384018352546fffffffffffffffffffffffffffffffff8116845267ffffffffffffffff700100000000000000000000000000000000820481169285019290925278010000000000000000000000000000000000000000000000009004169082015290565b6040805182516fffffffffffffffffffffffffffffffff16815260208084015167ffffffffffffffff908116918301919091529282015190921690820152606001610115565b6101316102b03660046124b8565b610943565b6100f4610ecd565b6101316102cb366004612244565b610ef6565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff1660008115801561031b5750825b905060008267ffffffffffffffff1660011480156103385750303b155b905081158015610346575080155b1561037d576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156103de5784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b7fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d41547fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d409073ffffffffffffffffffffffffffffffffffffffff1615801561045a575073ffffffffffffffffffffffffffffffffffffffff881615155b61046357600080fd5b6001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a161790556104ae87610fad565b5083156105105784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d4060208181526040808420815160608101835290546fffffffffffffffffffffffffffffffff8116825267ffffffffffffffff70010000000000000000000000000000000082048116948301859052780100000000000000000000000000000000000000000000000090910416918101919091529042101561064457630784ce0042826020015167ffffffffffffffff166105f0919061258a565b825161060f906fffffffffffffffffffffffffffffffff16600361259d565b610619919061259d565b61062391906125e3565b815161064191906fffffffffffffffffffffffffffffffff166125f7565b92505b5050919050565b610653611001565b61065d6000610fad565b565b3380610669610ecd565b73ffffffffffffffffffffffffffffffffffffffff16146106d3576040517f118cdaa700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b6106dc81610fad565b50565b6106e7611001565b7fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d4083828114610742576040517fccab218c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b858110156105105760008787838181106107615761076161260a565b90506020020160208101906107769190612244565b9050600086868481811061078c5761078c61260a565b9050606002018036038101906107a29190612651565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602087905260408120549192506fffffffffffffffffffffffffffffffff90911690036108f75773ffffffffffffffffffffffffffffffffffffffff8216600081815260208781526040918290208451815486840151878601516fffffffffffffffffffffffffffffffff9093167fffffffffffffffff000000000000000000000000000000000000000000000000909216821770010000000000000000000000000000000067ffffffffffffffff9283169081029190911777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009290941691820293909317909355845190815292830152918101919091527fd27db32ad6a2e889fcb35d08e573d9fd7c1bbed92246d3899fd73a80447900919060600160405180910390a25b5050600101610745565b6000807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b5473ffffffffffffffffffffffffffffffffffffffff1692915050565b60007fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d4060018101546040517fbb141cf40000000000000000000000000000000000000000000000000000000081526004810188905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063bb141cf4906024016040805180830381865afa1580156109dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0091906126d4565b73ffffffffffffffffffffffffffffffffffffffff881660009081526020848152604090912054908201519192507801000000000000000000000000000000000000000000000000900467ffffffffffffffff1664ffffffffff90911611610aea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c3156654658533a2043616e206f6e6c79207570646174652077697468206c6160448201527f74657220696e666f726d6174696f6e000000000000000000000000000000000060648201526084016106ca565b6000610b0f826000015173c8418af6358ffdda74e09ca9cc3fe03ca6adc5b088611059565b9050600060028973ffffffffffffffffffffffffffffffffffffffff16604051602001610b46929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830152016040516020818303038152906040528051906020012060001c90506000610bb083606001518360001b896111c9565b6020015190506000610bd38460600151846001610bcd91906125f7565b896111c9565b60200151905060008211610c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4c3156654658533a20616d6f756e74206973207a65726f00000000000000000060448201526064016106ca565b6f7fffffffffffffffffffffffffffffff8210610cbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4c3156654658533a20616d6f756e7420746f6f206c617267650000000000000060448201526064016106ca565b428111610d25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c3156654658533a206c6f636b2065787069726564000000000000000000000060448201526064016106ca565b630784ce00610d34428361258a565b1115610d9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c3156654658533a206c6f636b20746f6f206c6f6e670000000000000000000060448201526064016106ca565b73ffffffffffffffffffffffffffffffffffffffff8b16600081815260208881526040918290208054898301516fffffffffffffffffffffffffffffffff8881167fffffffffffffffff0000000000000000000000000000000000000000000000009093169290921770010000000000000000000000000000000067ffffffffffffffff89811682029290921777ffffffffffffffffffffffffffffffffffffffffffffffff811664ffffffffff909416780100000000000000000000000000000000000000000000000081029485179687905588519186169590941694909417845290930490921692810192909252918101919091527fd27db32ad6a2e889fcb35d08e573d9fd7c1bbed92246d3899fd73a80447900919060600160405180910390a25050505050505050505050565b6000807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00610926565b610efe611001565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255610f67610901565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155610ffd826112c4565b5050565b3361100a610901565b73ffffffffffffffffffffffffffffffffffffffff161461065d576040517f118cdaa70000000000000000000000000000000000000000000000000000000081523360048201526024016106ca565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526000825167ffffffffffffffff8111156110a0576110a0612327565b6040519080825280602002602001820160405280156110e557816020015b60408051808201909152600080825260208201528152602001906001900390816110be5790505b50905060005b835181101561116c5761113e8482815181106111095761110961260a565b602002602001015160408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b8282815181106111505761115061260a565b60200260200101819052508061116590612734565b90506110eb565b506040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660208201526111c09060340160405160208183030381529060405280519060200120868361135a565b95945050505050565b60408051808201909152600080825260208201526000825167ffffffffffffffff8111156111f9576111f9612327565b60405190808252806020026020018201604052801561123e57816020015b60408051808201909152600080825260208201528152602001906001900390816112175790505b50905060005b8351811015611290576112628482815181106111095761110961260a565b8282815181106112745761127461260a565b60200260200101819052508061128990612734565b9050611244565b506111c0846040516020016112a791815260200190565b6040516020818303038152906040528051906020012086836114d1565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915260006113b3848660405160200161139e91815260200190565b6040516020818303038152906040528561155e565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290915081516000036113f35791506114ca9050565b600061142e6114298460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b61199a565b9050805160041461143e57600080fd5b6001825280516114669082906000906114595761145961260a565b6020026020010151611ab0565b6020830152805161148490829060019081106114595761145961260a565b604083015280516114a290829060029081106114595761145961260a565b606083015280516114c090829060039081106114595761145961260a565b6080830152509150505b9392505050565b604080518082019091526000808252602082015260006114fe848660405160200161139e91815260200190565b60408051808201909152600080825260208201529091508151156111c0576001815260408051808201825260008082526020918201528151808301909252835182528084019082015261155090611ab0565b602082015295945050505050565b6060600061156d846000611afe565b90506000806060611591604051806040016040528060008152602001600081525090565b86516000036115e2577f56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42189146115c657600080fd5b505060408051600081526020810190915293506114ca92505050565b60005b875181101561198d5780158015611624575061162088828151811061160c5761160c61260a565b602002602001015160208101519051902090565b8a14155b1561162e57600080fd5b801580159061165e575061165a88828151811061164d5761164d61260a565b6020026020010151611cd4565b8414155b1561166857600080fd5b61168a88828151811061167d5761167d61260a565b602002602001015161199a565b9250825160020361183657600060606116c46116bf866000815181106116b2576116b261260a565b6020026020010151611d30565b611dae565b909250905060006116d6888a84611e49565b90506116e281896125f7565b975081518110156117455760018b516116fb919061258a565b84101561170757600080fd5b60005b6040519080825280601f01601f191660200182016040528015611734576020820181803683370190505b5099505050505050505050506114ca565b82156117ab5760018b51611759919061258a565b84101561176557600080fd5b885188101561177557600061170a565b856001815181106117885761178861260a565b6020026020010151945061179b85611d30565b99505050505050505050506114ca565b60018b516117b9919061258a565b84036117c457600080fd5b6117e7866001815181106117da576117da61260a565b6020026020010151611f04565b6118155761180e866001815181106118015761180161260a565b6020026020010151611f3f565b965061182e565b61182b8660018151811061160c5761160c61260a565b96505b50505061197b565b825160110361197b578551851461193f57600086868151811061185b5761185b61260a565b016020015160f81c90506118706001876125f7565b955060108160ff161061188257600080fd5b6118a7848260ff168151811061189a5761189a61260a565b6020026020010151611f57565b156118e357600189516118ba919061258a565b82146118c557600080fd5b505060408051600081526020810190915295506114ca945050505050565b6118fb848260ff16815181106117da576117da61260a565b61191e57611917848260ff16815181106118015761180161260a565b9450611939565b611936848260ff168151811061160c5761160c61260a565b94505b5061197b565b6001885161194d919061258a565b811461195857600080fd5b61196e836010815181106116b2576116b261260a565b96505050505050506114ca565b8061198581612734565b9150506115e5565b5050505050509392505050565b60606119a582611f04565b6119ae57600080fd5b60006119b983611f7a565b905060008167ffffffffffffffff8111156119d6576119d6612327565b604051908082528060200260200182016040528015611a1b57816020015b60408051808201909152600080825260208201528152602001906001900390816119f45790505b5090506000611a2d8560200151611fff565b8560200151611a3c91906125f7565b90506000805b84811015611aa557611a538361207a565b9150604051806040016040528083815260200184815250848281518110611a7c57611a7c61260a565b6020908102919091010152611a9182846125f7565b925080611a9d81612734565b915050611a42565b509195945050505050565b805160009015801590611ac557508151602110155b611ace57600080fd5b600080611ada84612123565b815191935091506020821015611af65760208290036101000a90045b949350505050565b60606000835111611b0e57600080fd5b600083516002611b1e919061259d565b905080831115611b2d57600080fd5b611b37838261258a565b90508067ffffffffffffffff811115611b5257611b52612327565b6040519080825280601f01601f191660200182016040528015611b7c576020820181803683370190505b5091506000835b611b8d83866125f7565b811015611cbb57611b9f60028261276c565b600003611c2357600486611bb46002846125e3565b81518110611bc457611bc461260a565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611bef57611bef61260a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611c9c565b600086611c316002846125e3565b81518110611c4157611c4161260a565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611c6c57611c6c61260a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b611ca76001836125f7565b9150611cb46001826125f7565b9050611b83565b5082518114611ccc57611ccc612780565b505092915050565b6000602082600001511015611cf3576020820151825190205b92915050565b602082015182519020604051602001611d0e91815260200190565b604051602081830303815290604052805190602001209050919050565b919050565b8051606090611d3e57600080fd5b600080611d4a84612123565b9150915060008167ffffffffffffffff811115611d6957611d69612327565b6040519080825280601f01601f191660200182016040528015611d93576020820181803683370190505b50905060208101611da584828561216a565b50949350505050565b600060606000835111611dc057600080fd5b6000600484600081518110611dd757611dd761260a565b60209101015160f81c901c600f1690506000818103611dfc5750600092506002611e33565b81600103611e105750600092506001611e33565b81600203611e245750600192506002611e33565b816003036100d4575060019250825b83611e3e8683611afe565b935093505050915091565b6000805b8351611e5986836125f7565b108015611e665750825181105b15611af657828181518110611e7d57611e7d61260a565b01602001517fff000000000000000000000000000000000000000000000000000000000000001684611eaf87846125f7565b81518110611ebf57611ebf61260a565b01602001517fff000000000000000000000000000000000000000000000000000000000000001614611ef25790506114ca565b80611efc81612734565b915050611e4d565b80516000908103611f1757506000919050565b6020820151805160001a9060c0821015611f35575060009392505050565b5060019392505050565b6000806000611f4d84612123565b9020949350505050565b8051600090600114611f6b57506000919050565b50602001515160001a60801490565b80516000908103611f8d57506000919050565b600080611f9d8460200151611fff565b8460200151611fac91906125f7565b9050600084600001518560200151611fc491906125f7565b90505b80821015611ff657611fd88261207a565b611fe290836125f7565b915082611fee81612734565b935050611fc7565b50909392505050565b8051600090811a60808110156120185750600092915050565b60b8811080612033575060c08110801590612033575060f881105b156120415750600192915050565b60c081101561206e57612056600160b86127af565b6120639060ff168261258a565b6114ca9060016125f7565b612056600160f86127af565b80516000908190811a6080811015612095576001915061211c565b60b88110156120bb576120a960808261258a565b6120b49060016125f7565b915061211c565b60c08110156120e85760b78103600185019450806020036101000a8551046001820181019350505061211c565b60f88110156120fc576120a960c08261258a565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b60008060006121358460200151611fff565b9050600081856020015161214991906125f7565b9050600082866000015161215d919061258a565b9196919550909350505050565b8060000361217757505050565b602081106121af578251825261218e6020846125f7565b925061219b6020836125f7565b91506121a860208261258a565b9050612177565b80156121e857600060016121c483602061258a565b6121d0906101006128e8565b6121da919061258a565b845184518216911916178352505b505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d2b57600080fd5b6000806040838503121561222457600080fd5b61222d836121ed565b915061223b602084016121ed565b90509250929050565b60006020828403121561225657600080fd5b6114ca826121ed565b6000806000806040858703121561227557600080fd5b843567ffffffffffffffff8082111561228d57600080fd5b818701915087601f8301126122a157600080fd5b8135818111156122b057600080fd5b8860208260051b85010111156122c557600080fd5b6020928301965094509086013590808211156122e057600080fd5b818701915087601f8301126122f457600080fd5b81358181111561230357600080fd5b88602060608302850101111561231857600080fd5b95989497505060200194505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561239d5761239d612327565b604052919050565b6000601f83818401126123b757600080fd5b8235602067ffffffffffffffff808311156123d4576123d4612327565b8260051b6123e3838201612356565b93845286810183019383810190898611156123fd57600080fd5b84890192505b858310156124ab5782358481111561241b5760008081fd5b8901603f81018b1361242d5760008081fd5b8581013560408682111561244357612443612327565b612472887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08c85011601612356565b8281528d828486010111156124875760008081fd5b828285018a8301376000928101890192909252508352509184019190840190612403565b9998505050505050505050565b600080600080600060a086880312156124d057600080fd5b6124d9866121ed565b945060208601359350604086013567ffffffffffffffff808211156124fd57600080fd5b61250989838a016123a5565b9450606088013591508082111561251f57600080fd5b61252b89838a016123a5565b9350608088013591508082111561254157600080fd5b5061254e888289016123a5565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115611ced57611ced61255b565b8082028115828204841417611ced57611ced61255b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826125f2576125f26125b4565b500490565b80820180821115611ced57611ced61255b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803567ffffffffffffffff81168114611d2b57600080fd5b60006060828403121561266357600080fd5b6040516060810181811067ffffffffffffffff8211171561268657612686612327565b60405282356fffffffffffffffffffffffffffffffff811681146126a957600080fd5b81526126b760208401612639565b60208201526126c860408401612639565b60408201529392505050565b6000604082840312156126e657600080fd5b6040516040810181811067ffffffffffffffff8211171561270957612709612327565b60405282518152602083015164ffffffffff8116811461272857600080fd5b60208201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036127655761276561255b565b5060010190565b60008261277b5761277b6125b4565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60ff8281168282160390811115611ced57611ced61255b565b600181815b8085111561282157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156128075761280761255b565b8085161561281457918102915b93841c93908002906127cd565b509250929050565b60008261283857506001611ced565b8161284557506000611ced565b816001811461285b576002811461286557612881565b6001915050611ced565b60ff8411156128765761287661255b565b50506001821b611ced565b5060208310610133831016604e8410600b84101617156128a4575081810a611ced565b6128ae83836127c8565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156128e0576128e061255b565b029392505050565b60006114ca838361282956fea164736f6c6343000814000a
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106100d45760003560e01c80638da5cb5b11610081578063cc275e8d1161005b578063cc275e8d146102a2578063e30c3978146102b5578063f2fde38b146102bd57600080fd5b80638da5cb5b14610177578063cbd006e31461017f578063cbf9fe5f1461018757600080fd5b8063715018a6116100b2578063715018a61461015457806379ba50971461015c5780637eff66661461016457600080fd5b80633c45b87c146100d9578063485cc9551461011e57806370a0823114610133575b600080fd5b6100f473c8418af6358ffdda74e09ca9cc3fe03ca6adc5b081565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020015b60405180910390f35b61013161012c366004612211565b6102d0565b005b610146610141366004612244565b610519565b604051908152602001610115565b61013161064b565b61013161065f565b61013161017236600461225f565b6106df565b6100f4610901565b610146600281565b61025c610195366004612244565b60408051606080820183526000808352602080840182905292840181905273ffffffffffffffffffffffffffffffffffffffff9490941684527fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d4082529282902082519384018352546fffffffffffffffffffffffffffffffff8116845267ffffffffffffffff700100000000000000000000000000000000820481169285019290925278010000000000000000000000000000000000000000000000009004169082015290565b6040805182516fffffffffffffffffffffffffffffffff16815260208084015167ffffffffffffffff908116918301919091529282015190921690820152606001610115565b6101316102b03660046124b8565b610943565b6100f4610ecd565b6101316102cb366004612244565b610ef6565b7ff0c57e16840df040f15088dc2f81fe391c3923bec73e23a9662efc9c229c6a00805468010000000000000000810460ff16159067ffffffffffffffff1660008115801561031b5750825b905060008267ffffffffffffffff1660011480156103385750303b155b905081158015610346575080155b1561037d576040517ff92ee8a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b84547fffffffffffffffffffffffffffffffffffffffffffffffff000000000000000016600117855583156103de5784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff16680100000000000000001785555b7fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d41547fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d409073ffffffffffffffffffffffffffffffffffffffff1615801561045a575073ffffffffffffffffffffffffffffffffffffffff881615155b61046357600080fd5b6001810180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8a161790556104ae87610fad565b5083156105105784547fffffffffffffffffffffffffffffffffffffffffffffff00ffffffffffffffff168555604051600181527fc7f505b2f371ae2175ee4913f4499e1f2633a7b5936321eed1cdaeb6115181d29060200160405180910390a15b50505050505050565b73ffffffffffffffffffffffffffffffffffffffff811660009081527fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d4060208181526040808420815160608101835290546fffffffffffffffffffffffffffffffff8116825267ffffffffffffffff70010000000000000000000000000000000082048116948301859052780100000000000000000000000000000000000000000000000090910416918101919091529042101561064457630784ce0042826020015167ffffffffffffffff166105f0919061258a565b825161060f906fffffffffffffffffffffffffffffffff16600361259d565b610619919061259d565b61062391906125e3565b815161064191906fffffffffffffffffffffffffffffffff166125f7565b92505b5050919050565b610653611001565b61065d6000610fad565b565b3380610669610ecd565b73ffffffffffffffffffffffffffffffffffffffff16146106d3576040517f118cdaa700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff821660048201526024015b60405180910390fd5b6106dc81610fad565b50565b6106e7611001565b7fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d4083828114610742576040517fccab218c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005b858110156105105760008787838181106107615761076161260a565b90506020020160208101906107769190612244565b9050600086868481811061078c5761078c61260a565b9050606002018036038101906107a29190612651565b73ffffffffffffffffffffffffffffffffffffffff83166000908152602087905260408120549192506fffffffffffffffffffffffffffffffff90911690036108f75773ffffffffffffffffffffffffffffffffffffffff8216600081815260208781526040918290208451815486840151878601516fffffffffffffffffffffffffffffffff9093167fffffffffffffffff000000000000000000000000000000000000000000000000909216821770010000000000000000000000000000000067ffffffffffffffff9283169081029190911777ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000009290941691820293909317909355845190815292830152918101919091527fd27db32ad6a2e889fcb35d08e573d9fd7c1bbed92246d3899fd73a80447900919060600160405180910390a25b5050600101610745565b6000807f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c1993005b5473ffffffffffffffffffffffffffffffffffffffff1692915050565b60007fc667da153497ef4116ec36eef54e190e9a94eda237a4c431c2176edb0ad62d4060018101546040517fbb141cf40000000000000000000000000000000000000000000000000000000081526004810188905291925060009173ffffffffffffffffffffffffffffffffffffffff9091169063bb141cf4906024016040805180830381865afa1580156109dc573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0091906126d4565b73ffffffffffffffffffffffffffffffffffffffff881660009081526020848152604090912054908201519192507801000000000000000000000000000000000000000000000000900467ffffffffffffffff1664ffffffffff90911611610aea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4c3156654658533a2043616e206f6e6c79207570646174652077697468206c6160448201527f74657220696e666f726d6174696f6e000000000000000000000000000000000060648201526084016106ca565b6000610b0f826000015173c8418af6358ffdda74e09ca9cc3fe03ca6adc5b088611059565b9050600060028973ffffffffffffffffffffffffffffffffffffffff16604051602001610b46929190918252602082015260400190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152828252805160209182012090830152016040516020818303038152906040528051906020012060001c90506000610bb083606001518360001b896111c9565b6020015190506000610bd38460600151846001610bcd91906125f7565b896111c9565b60200151905060008211610c43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f4c3156654658533a20616d6f756e74206973207a65726f00000000000000000060448201526064016106ca565b6f7fffffffffffffffffffffffffffffff8210610cbc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4c3156654658533a20616d6f756e7420746f6f206c617267650000000000000060448201526064016106ca565b428111610d25576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f4c3156654658533a206c6f636b2065787069726564000000000000000000000060448201526064016106ca565b630784ce00610d34428361258a565b1115610d9c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f4c3156654658533a206c6f636b20746f6f206c6f6e670000000000000000000060448201526064016106ca565b73ffffffffffffffffffffffffffffffffffffffff8b16600081815260208881526040918290208054898301516fffffffffffffffffffffffffffffffff8881167fffffffffffffffff0000000000000000000000000000000000000000000000009093169290921770010000000000000000000000000000000067ffffffffffffffff89811682029290921777ffffffffffffffffffffffffffffffffffffffffffffffff811664ffffffffff909416780100000000000000000000000000000000000000000000000081029485179687905588519186169590941694909417845290930490921692810192909252918101919091527fd27db32ad6a2e889fcb35d08e573d9fd7c1bbed92246d3899fd73a80447900919060600160405180910390a25050505050505050505050565b6000807f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c00610926565b610efe611001565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081178255610f67610901565b73ffffffffffffffffffffffffffffffffffffffff167f38d16b8cac22d99fc7c124b9cd0de2d3fa1faef420bfe791d8c362d765e2270060405160405180910390a35050565b7f237e158222e3e6968b72b9db0d8043aacf074ad9f650f0d1606b4d82ee432c0080547fffffffffffffffffffffffff0000000000000000000000000000000000000000168155610ffd826112c4565b5050565b3361100a610901565b73ffffffffffffffffffffffffffffffffffffffff161461065d576040517f118cdaa70000000000000000000000000000000000000000000000000000000081523360048201526024016106ca565b6040805160a0810182526000808252602082018190529181018290526060810182905260808101919091526000825167ffffffffffffffff8111156110a0576110a0612327565b6040519080825280602002602001820160405280156110e557816020015b60408051808201909152600080825260208201528152602001906001900390816110be5790505b50905060005b835181101561116c5761113e8482815181106111095761110961260a565b602002602001015160408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b8282815181106111505761115061260a565b60200260200101819052508061116590612734565b90506110eb565b506040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b1660208201526111c09060340160405160208183030381529060405280519060200120868361135a565b95945050505050565b60408051808201909152600080825260208201526000825167ffffffffffffffff8111156111f9576111f9612327565b60405190808252806020026020018201604052801561123e57816020015b60408051808201909152600080825260208201528152602001906001900390816112175790505b50905060005b8351811015611290576112628482815181106111095761110961260a565b8282815181106112745761127461260a565b60200260200101819052508061128990612734565b9050611244565b506111c0846040516020016112a791815260200190565b6040516020818303038152906040528051906020012086836114d1565b7f9016d09d72d40fdae2fd8ceac6b6234c7706214fd39c1cd1e609a0528c19930080547fffffffffffffffffffffffff0000000000000000000000000000000000000000811673ffffffffffffffffffffffffffffffffffffffff848116918217845560405192169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3505050565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915260006113b3848660405160200161139e91815260200190565b6040516020818303038152906040528561155e565b6040805160a08101825260008082526020820181905291810182905260608101829052608081019190915290915081516000036113f35791506114ca9050565b600061142e6114298460408051808201825260008082526020918201528151808301909252825182529182019181019190915290565b61199a565b9050805160041461143e57600080fd5b6001825280516114669082906000906114595761145961260a565b6020026020010151611ab0565b6020830152805161148490829060019081106114595761145961260a565b604083015280516114a290829060029081106114595761145961260a565b606083015280516114c090829060039081106114595761145961260a565b6080830152509150505b9392505050565b604080518082019091526000808252602082015260006114fe848660405160200161139e91815260200190565b60408051808201909152600080825260208201529091508151156111c0576001815260408051808201825260008082526020918201528151808301909252835182528084019082015261155090611ab0565b602082015295945050505050565b6060600061156d846000611afe565b90506000806060611591604051806040016040528060008152602001600081525090565b86516000036115e2577f56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42189146115c657600080fd5b505060408051600081526020810190915293506114ca92505050565b60005b875181101561198d5780158015611624575061162088828151811061160c5761160c61260a565b602002602001015160208101519051902090565b8a14155b1561162e57600080fd5b801580159061165e575061165a88828151811061164d5761164d61260a565b6020026020010151611cd4565b8414155b1561166857600080fd5b61168a88828151811061167d5761167d61260a565b602002602001015161199a565b9250825160020361183657600060606116c46116bf866000815181106116b2576116b261260a565b6020026020010151611d30565b611dae565b909250905060006116d6888a84611e49565b90506116e281896125f7565b975081518110156117455760018b516116fb919061258a565b84101561170757600080fd5b60005b6040519080825280601f01601f191660200182016040528015611734576020820181803683370190505b5099505050505050505050506114ca565b82156117ab5760018b51611759919061258a565b84101561176557600080fd5b885188101561177557600061170a565b856001815181106117885761178861260a565b6020026020010151945061179b85611d30565b99505050505050505050506114ca565b60018b516117b9919061258a565b84036117c457600080fd5b6117e7866001815181106117da576117da61260a565b6020026020010151611f04565b6118155761180e866001815181106118015761180161260a565b6020026020010151611f3f565b965061182e565b61182b8660018151811061160c5761160c61260a565b96505b50505061197b565b825160110361197b578551851461193f57600086868151811061185b5761185b61260a565b016020015160f81c90506118706001876125f7565b955060108160ff161061188257600080fd5b6118a7848260ff168151811061189a5761189a61260a565b6020026020010151611f57565b156118e357600189516118ba919061258a565b82146118c557600080fd5b505060408051600081526020810190915295506114ca945050505050565b6118fb848260ff16815181106117da576117da61260a565b61191e57611917848260ff16815181106118015761180161260a565b9450611939565b611936848260ff168151811061160c5761160c61260a565b94505b5061197b565b6001885161194d919061258a565b811461195857600080fd5b61196e836010815181106116b2576116b261260a565b96505050505050506114ca565b8061198581612734565b9150506115e5565b5050505050509392505050565b60606119a582611f04565b6119ae57600080fd5b60006119b983611f7a565b905060008167ffffffffffffffff8111156119d6576119d6612327565b604051908082528060200260200182016040528015611a1b57816020015b60408051808201909152600080825260208201528152602001906001900390816119f45790505b5090506000611a2d8560200151611fff565b8560200151611a3c91906125f7565b90506000805b84811015611aa557611a538361207a565b9150604051806040016040528083815260200184815250848281518110611a7c57611a7c61260a565b6020908102919091010152611a9182846125f7565b925080611a9d81612734565b915050611a42565b509195945050505050565b805160009015801590611ac557508151602110155b611ace57600080fd5b600080611ada84612123565b815191935091506020821015611af65760208290036101000a90045b949350505050565b60606000835111611b0e57600080fd5b600083516002611b1e919061259d565b905080831115611b2d57600080fd5b611b37838261258a565b90508067ffffffffffffffff811115611b5257611b52612327565b6040519080825280601f01601f191660200182016040528015611b7c576020820181803683370190505b5091506000835b611b8d83866125f7565b811015611cbb57611b9f60028261276c565b600003611c2357600486611bb46002846125e3565b81518110611bc457611bc461260a565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611bef57611bef61260a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611c9c565b600086611c316002846125e3565b81518110611c4157611c4161260a565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611c6c57611c6c61260a565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053505b611ca76001836125f7565b9150611cb46001826125f7565b9050611b83565b5082518114611ccc57611ccc612780565b505092915050565b6000602082600001511015611cf3576020820151825190205b92915050565b602082015182519020604051602001611d0e91815260200190565b604051602081830303815290604052805190602001209050919050565b919050565b8051606090611d3e57600080fd5b600080611d4a84612123565b9150915060008167ffffffffffffffff811115611d6957611d69612327565b6040519080825280601f01601f191660200182016040528015611d93576020820181803683370190505b50905060208101611da584828561216a565b50949350505050565b600060606000835111611dc057600080fd5b6000600484600081518110611dd757611dd761260a565b60209101015160f81c901c600f1690506000818103611dfc5750600092506002611e33565b81600103611e105750600092506001611e33565b81600203611e245750600192506002611e33565b816003036100d4575060019250825b83611e3e8683611afe565b935093505050915091565b6000805b8351611e5986836125f7565b108015611e665750825181105b15611af657828181518110611e7d57611e7d61260a565b01602001517fff000000000000000000000000000000000000000000000000000000000000001684611eaf87846125f7565b81518110611ebf57611ebf61260a565b01602001517fff000000000000000000000000000000000000000000000000000000000000001614611ef25790506114ca565b80611efc81612734565b915050611e4d565b80516000908103611f1757506000919050565b6020820151805160001a9060c0821015611f35575060009392505050565b5060019392505050565b6000806000611f4d84612123565b9020949350505050565b8051600090600114611f6b57506000919050565b50602001515160001a60801490565b80516000908103611f8d57506000919050565b600080611f9d8460200151611fff565b8460200151611fac91906125f7565b9050600084600001518560200151611fc491906125f7565b90505b80821015611ff657611fd88261207a565b611fe290836125f7565b915082611fee81612734565b935050611fc7565b50909392505050565b8051600090811a60808110156120185750600092915050565b60b8811080612033575060c08110801590612033575060f881105b156120415750600192915050565b60c081101561206e57612056600160b86127af565b6120639060ff168261258a565b6114ca9060016125f7565b612056600160f86127af565b80516000908190811a6080811015612095576001915061211c565b60b88110156120bb576120a960808261258a565b6120b49060016125f7565b915061211c565b60c08110156120e85760b78103600185019450806020036101000a8551046001820181019350505061211c565b60f88110156120fc576120a960c08261258a565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b60008060006121358460200151611fff565b9050600081856020015161214991906125f7565b9050600082866000015161215d919061258a565b9196919550909350505050565b8060000361217757505050565b602081106121af578251825261218e6020846125f7565b925061219b6020836125f7565b91506121a860208261258a565b9050612177565b80156121e857600060016121c483602061258a565b6121d0906101006128e8565b6121da919061258a565b845184518216911916178352505b505050565b803573ffffffffffffffffffffffffffffffffffffffff81168114611d2b57600080fd5b6000806040838503121561222457600080fd5b61222d836121ed565b915061223b602084016121ed565b90509250929050565b60006020828403121561225657600080fd5b6114ca826121ed565b6000806000806040858703121561227557600080fd5b843567ffffffffffffffff8082111561228d57600080fd5b818701915087601f8301126122a157600080fd5b8135818111156122b057600080fd5b8860208260051b85010111156122c557600080fd5b6020928301965094509086013590808211156122e057600080fd5b818701915087601f8301126122f457600080fd5b81358181111561230357600080fd5b88602060608302850101111561231857600080fd5b95989497505060200194505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561239d5761239d612327565b604052919050565b6000601f83818401126123b757600080fd5b8235602067ffffffffffffffff808311156123d4576123d4612327565b8260051b6123e3838201612356565b93845286810183019383810190898611156123fd57600080fd5b84890192505b858310156124ab5782358481111561241b5760008081fd5b8901603f81018b1361242d5760008081fd5b8581013560408682111561244357612443612327565b612472887fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08c85011601612356565b8281528d828486010111156124875760008081fd5b828285018a8301376000928101890192909252508352509184019190840190612403565b9998505050505050505050565b600080600080600060a086880312156124d057600080fd5b6124d9866121ed565b945060208601359350604086013567ffffffffffffffff808211156124fd57600080fd5b61250989838a016123a5565b9450606088013591508082111561251f57600080fd5b61252b89838a016123a5565b9350608088013591508082111561254157600080fd5b5061254e888289016123a5565b9150509295509295909350565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b81810381811115611ced57611ced61255b565b8082028115828204841417611ced57611ced61255b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000826125f2576125f26125b4565b500490565b80820180821115611ced57611ced61255b565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b803567ffffffffffffffff81168114611d2b57600080fd5b60006060828403121561266357600080fd5b6040516060810181811067ffffffffffffffff8211171561268657612686612327565b60405282356fffffffffffffffffffffffffffffffff811681146126a957600080fd5b81526126b760208401612639565b60208201526126c860408401612639565b60408201529392505050565b6000604082840312156126e657600080fd5b6040516040810181811067ffffffffffffffff8211171561270957612709612327565b60405282518152602083015164ffffffffff8116811461272857600080fd5b60208201529392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036127655761276561255b565b5060010190565b60008261277b5761277b6125b4565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b60ff8281168282160390811115611ced57611ced61255b565b600181815b8085111561282157817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156128075761280761255b565b8085161561281457918102915b93841c93908002906127cd565b509250929050565b60008261283857506001611ced565b8161284557506000611ced565b816001811461285b576002811461286557612881565b6001915050611ced565b60ff8411156128765761287661255b565b50506001821b611ced565b5060208310610133831016604e8410600b84101617156128a4575081810a611ced565b6128ae83836127c8565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156128e0576128e061255b565b029392505050565b60006114ca838361282956fea164736f6c6343000814000a
Deployed Bytecode Sourcemap
1309:6851:5:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1518:81;;1557:42;1518:81;;;;;190:42:11;178:55;;;160:74;;148:2;133:18;1518:81:5;;;;;;;;3107:360;;;;;;:::i;:::-;;:::i;:::-;;6629:442;;;;;;:::i;:::-;;:::i;:::-;;;1048:25:11;;;1036:2;1021:18;6629:442:5;902:177:11;3155:101:1;;;:::i;2774:229:0:-;;;:::i;7270:859:5:-;;;;;;:::i;:::-;;:::i;2441:144:1:-;;;:::i;1430:45:5:-;;1474:1;1430:45;;2428:164;;;;;;:::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;2568:17:5;;;;;;;2352:18;2568:17;;;;;;2561:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2428:164;;;;;2460:13:11;;2475:34;2456:54;2438:73;;2558:4;2546:17;;;2540:24;2583:18;2639:21;;;2617:20;;;2610:51;;;;2709:17;;;2703:24;2699:33;;;2677:20;;;2670:63;2426:2;2411:18;2428:164:5;2230:509:11;4114:2308:5;;;;;;:::i;:::-;;:::i;1680:168:0:-;;;:::i;2041:247::-;;;;;;:::i;:::-;;:::i;3107:360:5:-;8870:21:2;4302:15;;;;;;;4301:16;;4348:14;;4158:30;4726:16;;:34;;;;;4746:14;4726:34;4706:54;;4770:17;4790:11;:16;;4805:1;4790:16;:50;;;;-1:-1:-1;4818:4:2;4810:25;:30;4790:50;4770:70;;4856:12;4855:13;:30;;;;;4873:12;4872:13;4855:30;4851:91;;;4908:23;;;;;;;;;;;;;;4851:91;4951:18;;;;4968:1;4951:18;;;4979:67;;;;5013:22;;;;;;;;4979:67;3293:17:5;;2352:18;;3285:40:::1;3293:17;3285:40:::0;:74;::::1;;;-1:-1:-1::0;3329:30:5::1;::::0;::::1;::::0;::::1;3285:74;3277:83;;;::::0;::::1;;3370:17;::::0;::::1;:54:::0;;;::::1;;::::0;::::1;;::::0;;3434:26:::1;3453:6:::0;3434:18:::1;:26::i;:::-;3190:277;5070:14:2::0;5066:101;;;5100:23;;;;;;5142:14;;-1:-1:-1;6052:50:11;;5142:14:2;;6040:2:11;6025:18;5142:14:2;;;;;;;5066:101;4092:1081;;;;;3107:360:5;;:::o;6629:442::-;6800:18;;;6689:16;6800:18;;;2352;6800;;;;;;;;6762:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6853:15;-1:-1:-1;6828:237:5;;;1680:16;7011:15;6990:14;:18;;;:36;;;;;;:::i;:::-;6960:21;;6952:34;;:30;;6985:1;6952:34;:::i;:::-;:75;;;;:::i;:::-;6951:103;;;;:::i;:::-;6911:21;;:143;;;;;;:::i;:::-;6884:170;;6828:237;6707:364;;6629:442;;;:::o;3155:101:1:-;2334:13;:11;:13::i;:::-;3219:30:::1;3246:1;3219:18;:30::i;:::-;3155:101::o:0;2774:229:0:-;966:10:3;;2869:14:0;:12;:14::i;:::-;:24;;;2865:96;;2916:34;;;;;190:42:11;178:55;;2916:34:0;;;160:74:11;133:18;;2916:34:0;;;;;;;;2865:96;2970:26;2989:6;2970:18;:26::i;:::-;2816:187;2774:229::o;7270:859:5:-;2334:13:1;:11;:13::i;:::-;2352:18:5;7481:10;7512:32;;::::1;7508:61;;7553:16;;;;;;;;;;;;;;7508:61;7585:9;7580:543;7600:21:::0;;::::1;7580:543;;;7639:16;7658:10;;7669:1;7658:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;7639:32;;7685:35;7723:15;;7739:1;7723:18;;;;;;;:::i;:::-;;;;;;7685:56;;;;;;;;;;:::i;:::-;7834:18;::::0;::::1;:8;:18:::0;;;::::1;::::0;;;;;;:25;7685:56;;-1:-1:-1;7834:25:5::1;::::0;;::::1;:30:::0;;7830:223:::1;;7884:18;::::0;::::1;:8;:18:::0;;;::::1;::::0;;;;;;;;:35;;;;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;::::1;::::0;;;;;;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;7942:96;;8327:66:11;;;8446:18;;;8439:43;8498:18;;;8491:43;;;;7942:96:5::1;::::0;8315:2:11;8300:18;7942:96:5::1;;;;;;;7830:223;-1:-1:-1::0;;8095:3:5::1;;7580:543;;2441:144:1::0;2487:7;;1313:22;2533:20;2570:8;;;;2441:144;-1:-1:-1;;2441:144:1:o;4114:2308:5:-;4331:20;2352:18;4423:17;;;;:44;;;;;;;;1048:25:11;;;4423:17:5;;-1:-1:-1;4376:44:5;;4423:17;;;;;:30;;1021:18:11;;4423:44:5;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;4521:18;;;:8;:18;;;;;;;;;;;:33;4498:20;;;;;;-1:-1:-1;4521:33:5;;;;;4498:56;;;;;4477:150;;;;;;;9354:2:11;4477:150:5;;;9336:21:11;9393:2;9373:18;;;9366:30;9432:34;9412:18;;;9405:62;9503:17;9483:18;;;9476:45;9538:19;;4477:150:5;9152:411:11;4477:150:5;4638:36;4677:179;4740:10;:24;;;1557:42;4832:13;4677:33;:179::i;:::-;4638:218;;4923:13;1474:1;5049:8;5033:26;;4997:63;;;;;;;;9725:19:11;;;9769:2;9760:12;;9753:28;9806:2;9797:12;;9568:247;4997:63:5;;;;;;;;;;;;;;4987:74;;4997:63;4987:74;;;;4970:92;;;9949:19:11;9984:12;4970:92:5;;;;;;;;;;;;4960:103;;;;;;4939:134;;4923:150;;5124:15;5163:230;5258:12;:24;;;5318:5;5310:14;;5360;5163:55;:230::i;:::-;:253;;;5124:302;;5474:12;5510:234;5605:12;:24;;;5665:5;5673:1;5665:9;;;;:::i;:::-;5711:14;5510:55;:234::i;:::-;:257;;;5474:303;;5831:1;5821:7;:11;5813:47;;;;;;;10209:2:11;5813:47:5;;;10191:21:11;10248:2;10228:18;;;10221:30;10287:25;10267:18;;;10260:53;10330:18;;5813:47:5;10007:347:11;5813:47:5;5896:16;5878:35;;5870:73;;;;;;;10561:2:11;5870:73:5;;;10543:21:11;10600:2;10580:18;;;10573:30;10639:27;10619:18;;;10612:55;10684:18;;5870:73:5;10359:349:11;5870:73:5;5968:15;5961:4;:22;5953:56;;;;;;;10915:2:11;5953:56:5;;;10897:21:11;10954:2;10934:18;;;10927:30;10993:23;10973:18;;;10966:51;11034:18;;5953:56:5;10713:345:11;5953:56:5;1680:16;6027:22;6034:15;6027:4;:22;:::i;:::-;:33;;6019:68;;;;;;;11265:2:11;6019:68:5;;;11247:21:11;11304:2;11284:18;;;11277:30;11343:24;11323:18;;;11316:52;11385:18;;6019:68:5;11063:346:11;6019:68:5;6124:18;;;:8;:18;;;;;;;;;;;;:44;;6261:20;;;;6124:44;;;;6178:37;;;;;;;;;;;;;;;;;;;6225:56;;;;;;;;;;;;;;;;;6320:95;;6343:25;;;;;;;;;;;11612:66:11;;6370:22:5;;;;;;11694:18:11;;;11687:59;;;;11762:18;;;11755:53;;;;6320:95:5;;11600:2:11;11585:18;6320:95:5;;;;;;;4321:2101;;;;;;4114:2308;;;;;:::o;1680:168:0:-;1733:7;;1318:27;1784:25;1187:174;2041:247;2334:13:1;:11;:13::i;:::-;1318:27:0;2197:26;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;2263:7:::1;:5;:7::i;:::-;2238:43;;;;;;;;;;;;2120:168;2041:247:::0;:::o;2472:222::-;1318:27;2621:22;;;;;;2653:34;2678:8;2653:24;:34::i;:::-;2544:150;2472:222;:::o;2658:162:1:-;966:10:3;2717:7:1;:5;:7::i;:::-;:23;;;2713:101;;2763:40;;;;;966:10:3;2763:40:1;;;160:74:11;133:18;;2763:40:1;14:226:11;1782:645:9;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1982:42:9;2051:12;:19;2027:44;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;2027:44:9;;;;;;;;;;;;;;;;1982:89;;2086:9;2081:123;2105:12;:19;2101:1;:23;2081:123;;;2166:27;:12;2179:1;2166:15;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;1699:28:4;;;;;;;;1707:11;;1699:28;;1657:15;;;1699:28;;;;;;;;1513:221;2166:27:9;2145:15;2161:1;2145:18;;;;;;;;:::i;:::-;;;;;;:48;;;;2126:3;;;;:::i;:::-;;;2081:123;;;-1:-1:-1;2298:30:9;;12181:66:11;12168:2;12164:15;;;12160:88;2298:30:9;;;12148:101:11;2227:193:9;;12265:12:11;;2298:30:9;;;;;;;;;;;;2288:41;;;;;;2359:13;2394:15;2227:32;:193::i;:::-;2213:207;1782:645;-1:-1:-1;;;;;1782:645:9:o;2764:637::-;-1:-1:-1;;;;;;;;;;;;;;;;;2963:42:9;3032:12;:19;3008:44;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;3008:44:9;;;;;;;;;;;;;;;;2963:89;;3067:9;3062:123;3086:12;:19;3082:1;:23;3062:123;;;3147:27;:12;3160:1;3147:15;;;;;;;;:::i;:27::-;3126:15;3142:1;3126:18;;;;;;;;:::i;:::-;;;;;;:48;;;;3107:3;;;;:::i;:::-;;;3062:123;;;;3206:188;3293:4;3276:22;;;;;;9949:19:11;;9993:2;9984:12;;9820:182;3276:22:9;;;;;;;;;;;;;3266:33;;;;;;3331:15;3368;3206:34;:188::i;3774:248:1:-;1313:22;3923:8;;3941:19;;;3923:8;3941:19;;;;;;;;3975:40;;3923:8;;;;;3975:40;;3847:24;;3975:40;3837:185;;3774:248;:::o;2565:930:10:-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2798:25:10;2826:147;2885:14;2930:12;2913:30;;;;;;9949:19:11;;9993:2;9984:12;;9820:182;2913:30:10;;;;;;;;;;;;;2957:6;2826:45;:147::i;:::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2798:175:10;;-1:-1:-1;3021:12:10;:19;3044:1;3021:24;3017:69;;3068:7;-1:-1:-1;3061:14:10;;-1:-1:-1;3061:14:10;3017:69;3096:37;3136:33;:24;:12;-1:-1:-1;;;;;;;;;;;;;;;;;1699:28:4;;;;;;;;1707:11;;1699:28;;1657:15;;;1699:28;;;;;;;;1513:221;3136:24:10;:31;:33::i;:::-;3096:73;;3187:10;:17;3208:1;3187:22;3179:31;;;;;;3238:4;3221:21;;3268:13;;:22;;:10;;3221:14;;3268:13;;;;:::i;:::-;;;;;;;:20;:22::i;:::-;3252:13;;;:38;3318:13;;:22;;:10;;3329:1;;3318:13;;;;;;:::i;:22::-;3300:15;;;:40;3380:13;;:22;;:10;;3391:1;;3380:13;;;;;;:::i;:22::-;3350:19;;;:53;3440:13;;:22;;:10;;3451:1;;3440:13;;;;;;:::i;:22::-;3413:16;;;:50;-1:-1:-1;3413:7:10;-1:-1:-1;;2565:930:10;;;;;;:::o;3748:581::-;-1:-1:-1;;;;;;;;;;;;;;;;;3944:26:10;3973:146;4032:16;4079:9;4062:27;;;;;;9949:19:11;;9993:2;9984:12;;9820:182;3973:146:10;-1:-1:-1;;;;;;;;;;;;;;;;;3944:175:10;;-1:-1:-1;4167:20:10;;:25;4163:137;;4223:4;4208:19;;-1:-1:-1;;;;;;;;;;;;;;;;;1699:28:4;;;;;;;;1707:11;;1699:28;;1657:15;;;1699:28;;;;4255:34:10;;:32;:34::i;:::-;4241:11;;;:48;4317:5;3748:581;-1:-1:-1;;;;;3748:581:10:o;1267:5475:8:-;1418:18;1448:19;1470:23;1485:4;1491:1;1470:14;:23::i;:::-;1448:45;;1503:20;1538;1568:31;1610:33;-1:-1:-1;;;;;;;;;;;;;;;;;;;1610:33:8;1658:5;:12;1674:1;1658:17;1654:223;;1766:66;1754:78;;1746:87;;;;;;-1:-1:-1;;1854:12:8;;;1864:1;1854:12;;;;;;;;;-1:-1:-1;1847:19:8;;-1:-1:-1;;;1847:19:8;1654:223;1945:9;1940:4796;1964:5;:12;1960:1;:16;1940:4796;;;2238:6;;:50;;;;;2260:28;:5;2266:1;2260:8;;;;;;;;:::i;:::-;;;;;;;4156:11:4;;;;4191:8;;4266:19;;;4052:272;2260:28:8;2248:8;:40;;2238:50;2234:97;;;2308:8;;;2234:97;2445:6;;;;;:48;;;2471:22;2484:5;2490:1;2484:8;;;;;;;;:::i;:::-;;;;;;;2471:12;:22::i;:::-;2455:12;:38;;2445:48;2441:95;;;2513:8;;;2441:95;2662:17;:5;2668:1;2662:8;;;;;;;;:::i;:::-;;;;;;;:15;:17::i;:::-;2655:24;;2698:4;:11;2713:1;2698:16;2694:4032;;2777:11;2806:20;2864:47;2893:17;:4;2898:1;2893:7;;;;;;;;:::i;:::-;;;;;;;:15;:17::i;:::-;2864:28;:47::i;:::-;2844:67;;-1:-1:-1;2844:67:8;-1:-1:-1;2930:20:8;2953:50;2973:12;2987:6;2844:67;2953:19;:50::i;:::-;2930:73;-1:-1:-1;3021:28:8;2930:73;3021:28;;:::i;:::-;;;3087:7;:14;3072:12;:29;3068:994;;;3876:1;3861:5;:12;:16;;;;:::i;:::-;3857:1;:20;3853:149;;;3971:8;;;3853:149;4041:1;4031:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;4031:12:8;;4024:19;;;;;;;;;;;;;3068:994;4084:6;4080:1175;;;4173:1;4158:5;:12;:16;;;;:::i;:::-;4154:1;:20;4150:144;;;4263:8;;;4150:144;4335:6;:13;4320:12;:28;4316:102;;;4393:1;4383:12;;4316:102;4451:4;4456:1;4451:7;;;;;;;;:::i;:::-;;;;;;;4440:18;;4487;:8;:16;:18::i;:::-;4480:25;;;;;;;;;;;;;4080:1175;4645:1;4630:5;:12;:16;;;;:::i;:::-;4625:1;:21;4621:138;;4728:8;;;4621:138;4786:16;:4;4791:1;4786:7;;;;;;;;:::i;:::-;;;;;;;:14;:16::i;:::-;4781:456;;4973:26;:4;4978:1;4973:7;;;;;;;;:::i;:::-;;;;;;;:24;:26::i;:::-;4958:41;;4781:456;;;5187:27;:4;5192:1;5187:7;;;;;;;;:::i;:27::-;5172:42;;4781:456;2716:2553;;;2694:4032;;;5279:4;:11;5294:2;5279:17;5275:1451;;5368:6;:13;5352:12;:29;5348:1364;;5495:12;5516:6;5523:12;5516:20;;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;5559:17:8;5575:1;5559:17;;:::i;:::-;;;5612:2;5602:6;:12;;;5598:146;;5713:8;;;5598:146;5770:34;5791:4;5796:6;5791:12;;;;;;;;;;:::i;:::-;;;;;;;5770:20;:34::i;:::-;5766:556;;;5890:1;5875:5;:12;:16;;;;:::i;:::-;5870:1;:21;5866:157;;5988:8;;;5866:157;-1:-1:-1;;6056:12:8;;;6066:1;6056:12;;;;;;;;;-1:-1:-1;6049:19:8;;-1:-1:-1;;;;;6049:19:8;5766:556;6102:21;:4;6107:6;6102:12;;;;;;;;;;:::i;:21::-;6097:225;;6166:31;:4;6171:6;6166:12;;;;;;;;;;:::i;:31::-;6151:46;;6097:225;;;6267:32;:4;6272:6;6267:12;;;;;;;;;;:::i;:32::-;6252:47;;6097:225;5383:957;5348:1364;;;6535:1;6520:5;:12;:16;;;;:::i;:::-;6515:1;:21;6511:135;;6615:8;;;6511:135;6675:18;:4;6680:2;6675:8;;;;;;;;:::i;:18::-;6668:25;;;;;;;;;;5348:1364;1978:3;;;;:::i;:::-;;;;1940:4796;;;;1438:5304;;;;;1267:5475;;;;;:::o;2946:519:4:-;3006:16;3042:12;3049:4;3042:6;:12::i;:::-;3034:21;;;;;;3066:13;3082:14;3091:4;3082:8;:14::i;:::-;3066:30;;3106:23;3146:5;3132:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;3132:20:4;;;;;;;;;;;;;;;;3106:46;;3163:14;3194:27;3209:4;:11;;;3194:14;:27::i;:::-;3180:4;:11;;;:41;;;;:::i;:::-;3163:58;-1:-1:-1;3231:15:4;;3256:179;3280:5;3276:1;:9;3256:179;;;3316:19;3328:6;3316:11;:19::i;:::-;3306:29;;3361:24;;;;;;;;3369:7;3361:24;;;;3378:6;3361:24;;;3349:6;3356:1;3349:9;;;;;;;;:::i;:::-;;;;;;;;;;:36;3408:16;3417:7;3408:6;:16;:::i;:::-;3399:25;-1:-1:-1;3287:3:4;;;;:::i;:::-;;;;3256:179;;;-1:-1:-1;3452:6:4;;2946:519;-1:-1:-1;;;;;2946:519:4:o;6049:467::-;6136:8;;6109:7;;6136:12;;;;:30;;-1:-1:-1;6152:8:4;;6164:2;-1:-1:-1;6152:14:4;6136:30;6128:39;;;;;;6179:14;6195:11;6210:21;6226:4;6210:15;:21::i;:::-;6299:13;;6178:53;;-1:-1:-1;6178:53:4;-1:-1:-1;6395:2:4;6387:11;;6384:92;;;6452:2;6448:12;;;6443:3;6439:22;6427:35;;6384:92;6503:6;6049:467;-1:-1:-1;;;;6049:467:4:o;8723:747:8:-;8812:20;8869:1;8852:7;:14;:18;8844:27;;;;;;8882:14;8899:7;:14;8916:1;8899:18;;;;:::i;:::-;8882:35;;8950:6;8935:11;:21;;8927:30;;;;;;8967:21;8977:11;8967:21;;:::i;:::-;;;9019:6;9009:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9009:17:8;-1:-1:-1;8999:27:8;-1:-1:-1;9036:21:8;9089:11;9072:342;9106:20;9120:6;9106:11;:20;:::i;:::-;9102:1;:24;9072:342;;;9154:5;9158:1;9154;:5;:::i;:::-;9163:1;9154:10;9150:222;;9242:1;9223:7;9231:5;9235:1;9231;:5;:::i;:::-;9223:14;;;;;;;;:::i;:::-;;;;;;;;;9217:21;;:26;;;;9247:3;9216:34;9209:42;;9184:7;9192:13;9184:22;;;;;;;;:::i;:::-;;;;:67;;;;;;;;;;;9150:222;;;9348:1;9329:7;9337:5;9341:1;9337;:5;:::i;:::-;9329:14;;;;;;;;:::i;:::-;;;;;;;;;9323:21;;:26;;;;9353:3;9322:34;9315:42;;9290:7;9298:13;9290:22;;;;;;;;:::i;:::-;;;;:67;;;;;;;;;;;9150:222;9385:18;9402:1;9385:18;;:::i;:::-;;-1:-1:-1;9128:6:8;9133:1;9128:6;;:::i;:::-;;;9072:342;;;;9448:7;:14;9431:13;:31;9424:39;;;;:::i;:::-;8834:636;;8723:747;;;;:::o;7307:266::-;7382:7;7416:2;7405:4;:8;;;:13;7401:166;;;4156:11:4;;;;4191:8;;4266:19;;7441:24:8;7434:31;7307:266;-1:-1:-1;;7307:266:8:o;7401:166::-;4156:11:4;;;;4191:8;;4266:19;;7513:42:8;;;;;;9949:19:11;;9993:2;9984:12;;9820:182;7513:42:8;;;;;;;;;;;;;7503:53;;;;;;7496:60;;7307:266;;;:::o;7401:166::-;7307:266;;;:::o;6857:379:4:-;6950:8;;6918:12;;6942:21;;;;;;6975:14;6991:11;7006:21;7022:4;7006:15;:21::i;:::-;6974:53;;;;7037:19;7069:3;7059:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7059:14:4;-1:-1:-1;7037:36:4;-1:-1:-1;7147:4:4;7143:17;;7180:26;7185:6;7143:17;7202:3;7180:4;:26::i;:::-;-1:-1:-1;7223:6:4;6857:379;-1:-1:-1;;;;6857:379:4:o;7920:797:8:-;8016:11;8029:20;8086:1;8069:7;:14;:18;8061:27;;;;;;8098:20;8143:1;8128:7;8136:1;8128:10;;;;;;;;:::i;:::-;;;;;;;;8122:22;;8148:3;8121:30;;-1:-1:-1;8161:19:8;8194:17;;;8190:458;;-1:-1:-1;8265:5:8;;-1:-1:-1;8241:1:8;8190:458;;;8291:12;8307:1;8291:17;8287:361;;-1:-1:-1;8362:5:8;;-1:-1:-1;8338:1:8;8287:361;;;8388:12;8404:1;8388:17;8384:264;;-1:-1:-1;8459:4:8;;-1:-1:-1;8435:1:8;8384:264;;;8484:12;8500:1;8484:17;8480:168;;-1:-1:-1;8531:1:8;;-1:-1:-1;8531:1:8;8480:168;8665:6;8673:36;8688:7;8697:11;8673:14;:36::i;:::-;8657:53;;;;;;7920:797;;;:::o;9476:321::-;9579:7;;9617:156;9644:9;;9629:12;9633:8;9629:1;:12;:::i;:::-;:24;:41;;;;;9661:2;:9;9657:1;:13;9629:41;9617:156;;;9715:2;9718:1;9715:5;;;;;;;;:::i;:::-;;;;;;;9695:2;9698:12;9702:8;9698:1;:12;:::i;:::-;9695:16;;;;;;;;:::i;:::-;;;;;;;:25;9691:72;;9747:1;-1:-1:-1;9740:8:8;;9691:72;9672:3;;;;:::i;:::-;;;;9617:156;;3569:321:4;3649:8;;3629:4;;3649:13;;3645:31;;-1:-1:-1;3671:5:4;;3569:321;-1:-1:-1;3569:321:4:o;3645:31::-;3725:11;;;;3786:13;;3687:11;3778:22;;328:4;3824:24;;3820:42;;;-1:-1:-1;3857:5:4;;3569:321;-1:-1:-1;;;3569:321:4:o;3820:42::-;-1:-1:-1;3879:4:4;;3569:321;-1:-1:-1;;;3569:321:4:o;4482:270::-;4552:7;4572:14;4588:11;4603:21;4619:4;4603:15;:21::i;:::-;4691:22;;;4482:270;-1:-1:-1;;;;4482:270:4:o;7579:335:8:-;7682:8;;7662:4;;7694:1;7682:13;7678:56;;-1:-1:-1;7718:5:8;;7579:335;-1:-1:-1;7579:335:8:o;7678:56::-;-1:-1:-1;7777:11:8;;;7834:13;7743:7;7826:22;7879:4;7874:9;;7579:335::o;7344:424:4:-;7428:8;;7405:7;;7428:13;;7424:27;;-1:-1:-1;7450:1:4;;7344:424;-1:-1:-1;7344:424:4:o;7424:27::-;7462:13;7489:15;7521:27;7536:4;:11;;;7521:14;:27::i;:::-;7507:4;:11;;;:41;;;;:::i;:::-;7489:59;;7558:14;7589:4;:8;;;7575:4;:11;;;:22;;;;:::i;:::-;7558:39;;7607:132;7624:6;7614:7;:16;7607:132;;;7666:20;7678:7;7666:11;:20::i;:::-;7656:30;;:7;:30;:::i;:::-;7646:40;-1:-1:-1;7721:7:4;;;;:::i;:::-;;;;7607:132;;;-1:-1:-1;7756:5:4;;7344:424;-1:-1:-1;;;7344:424:4:o;9132:581::-;9276:13;;9194:7;;9268:22;;239:4;9314:26;;9310:397;;;-1:-1:-1;9363:1:4;;9132:581;-1:-1:-1;;9132:581:4:o;9310:397::-;284:4;9385:25;;;:83;;-1:-1:-1;328:4:4;9415:25;;;;;:52;;-1:-1:-1;371:4:4;9444:23;;9415:52;9381:326;;;-1:-1:-1;9491:1:4;;9132:581;-1:-1:-1;;9132:581:4:o;9381:326::-;328:4;9513:24;;9509:198;;;9599:21;9619:1;284:4;9599:21;:::i;:::-;9590:31;;;;:5;:31;:::i;:::-;:35;;9624:1;9590:35;:::i;9509:198::-;9672:19;9690:1;371:4;9672:19;:::i;7817:1263::-;7983:13;;7876:7;;;;7975:22;;239:4;8021:26;;8017:1032;;;8073:1;8063:11;;8017:1032;;;284:4;8095:25;;8091:958;;;8146:26;239:4;8146:5;:26;:::i;:::-;:30;;8175:1;8146:30;:::i;:::-;8136:40;;8091:958;;;328:4;8197:24;;8193:856;;;8290:4;8283:5;8279:16;8369:1;8361:6;8357:14;8347:24;;8508:7;8504:2;8500:16;8495:3;8491:26;8482:6;8476:13;8472:46;8605:1;8596:7;8592:15;8583:7;8579:29;8568:40;;;;8193:856;;;371:4;8642:23;;8638:411;;;8691:24;328:4;8691:5;:24;:::i;8638:411::-;8803:4;8796:5;8792:16;8847:1;8839:6;8835:14;8825:24;;8918:7;8914:2;8910:16;8905:3;8901:26;8892:6;8886:13;8882:46;9022:1;9013:7;9009:15;9000:7;8996:29;8985:40;;;;8638:411;-1:-1:-1;9066:7:4;7817:1263;-1:-1:-1;;7817:1263:4:o;2390:281::-;2459:7;2468;2487:14;2504:27;2519:4;:11;;;2504:14;:27::i;:::-;2487:44;;2541:14;2572:6;2558:4;:11;;;:20;;;;:::i;:::-;2541:37;;2588:11;2613:6;2602:4;:8;;;:17;;;;:::i;:::-;2652:6;;2588:31;;-1:-1:-1;2390:281:4;;-1:-1:-1;;;;2390:281:4:o;9871:768::-;9952:3;9959:1;9952:8;9948:21;;9871:768;;;:::o;9948:21::-;408:2;10033:16;;10026:194;;10123:10;;10110:24;;10162:16;408:2;10129:3;10162:16;:::i;:::-;;-1:-1:-1;10192:17:4;408:2;10192:17;;:::i;:::-;;-1:-1:-1;10051:16:4;408:2;10051:16;;:::i;:::-;;;10026:194;;;10234:7;;10230:403;;10341:12;10381:1;10362:15;10374:3;408:2;10362:15;:::i;:::-;10356:22;;:3;:22;:::i;:::-;:26;;;;:::i;:::-;10442:10;;10517:11;;10513:22;;10454:9;;10438:26;10587:21;10574:35;;-1:-1:-1;10230:403:4;9871:768;;;:::o;245:196:11:-;313:20;;373:42;362:54;;352:65;;342:93;;431:1;428;421:12;446:260;514:6;522;575:2;563:9;554:7;550:23;546:32;543:52;;;591:1;588;581:12;543:52;614:29;633:9;614:29;:::i;:::-;604:39;;662:38;696:2;685:9;681:18;662:38;:::i;:::-;652:48;;446:260;;;;;:::o;711:186::-;770:6;823:2;811:9;802:7;798:23;794:32;791:52;;;839:1;836;829:12;791:52;862:29;881:9;862:29;:::i;1084:1141::-;1239:6;1247;1255;1263;1316:2;1304:9;1295:7;1291:23;1287:32;1284:52;;;1332:1;1329;1322:12;1284:52;1372:9;1359:23;1401:18;1442:2;1434:6;1431:14;1428:34;;;1458:1;1455;1448:12;1428:34;1496:6;1485:9;1481:22;1471:32;;1541:7;1534:4;1530:2;1526:13;1522:27;1512:55;;1563:1;1560;1553:12;1512:55;1603:2;1590:16;1629:2;1621:6;1618:14;1615:34;;;1645:1;1642;1635:12;1615:34;1700:7;1693:4;1683:6;1680:1;1676:14;1672:2;1668:23;1664:34;1661:47;1658:67;;;1721:1;1718;1711:12;1658:67;1752:4;1744:13;;;;-1:-1:-1;1776:6:11;-1:-1:-1;1820:20:11;;;1807:34;;1853:16;;;1850:36;;;1882:1;1879;1872:12;1850:36;1920:8;1909:9;1905:24;1895:34;;1967:7;1960:4;1956:2;1952:13;1948:27;1938:55;;1989:1;1986;1979:12;1938:55;2031:2;2018:16;2059:2;2049:8;2046:16;2043:36;;;2075:1;2072;2065:12;2043:36;2135:7;2128:4;2120;2110:8;2106:19;2102:2;2098:28;2094:39;2091:52;2088:72;;;2156:1;2153;2146:12;2088:72;1084:1141;;;;-1:-1:-1;;2187:4:11;2179:13;;-1:-1:-1;;;1084:1141:11:o;2744:184::-;2796:77;2793:1;2786:88;2893:4;2890:1;2883:15;2917:4;2914:1;2907:15;2933:334;3004:2;2998:9;3060:2;3050:13;;3065:66;3046:86;3034:99;;3163:18;3148:34;;3184:22;;;3145:62;3142:88;;;3210:18;;:::i;:::-;3246:2;3239:22;2933:334;;-1:-1:-1;2933:334:11:o;3272:1631::-;3324:5;3354:4;3398:3;3393:2;3385:6;3381:15;3377:25;3367:53;;3416:1;3413;3406:12;3367:53;3452:6;3439:20;3478:4;3501:18;3538:2;3534;3531:10;3528:36;;;3544:18;;:::i;:::-;3590:2;3587:1;3583:10;3613:28;3637:2;3633;3629:11;3613:28;:::i;:::-;3675:15;;;3745;;;3741:24;;;3706:12;;;;3777:15;;;3774:35;;;3805:1;3802;3795:12;3774:35;3841:2;3833:6;3829:15;3818:26;;3853:1021;3869:6;3864:3;3861:15;3853:1021;;;3955:3;3942:17;3991:2;3978:11;3975:19;3972:109;;;4035:1;4064:2;4060;4053:14;3972:109;4104:24;;4163:2;4155:11;;4151:21;-1:-1:-1;4141:119:11;;4214:1;4243:2;4239;4232:14;4141:119;4304:2;4300;4296:11;4283:25;4332:2;4357;4353;4350:10;4347:36;;;4363:18;;:::i;:::-;4411:110;4517:2;4448:66;4443:2;4439;4435:11;4431:84;4427:93;4411:110;:::i;:::-;4550:2;4541:7;4534:19;4595:3;4589;4584:2;4580;4576:11;4572:21;4569:30;4566:123;;;4641:1;4671:3;4666;4659:16;4566:123;4747:2;4741:3;4737:2;4733:12;4728:2;4719:7;4715:16;4702:48;4797:1;4774:16;;;4770:25;;4763:36;;;;-1:-1:-1;4812:20:11;;-1:-1:-1;3886:12:11;;;;4852;;;;3853:1021;;;4892:5;3272:1631;-1:-1:-1;;;;;;;;;3272:1631:11:o;4908:986::-;5105:6;5113;5121;5129;5137;5190:3;5178:9;5169:7;5165:23;5161:33;5158:53;;;5207:1;5204;5197:12;5158:53;5230:29;5249:9;5230:29;:::i;:::-;5220:39;;5306:2;5295:9;5291:18;5278:32;5268:42;;5361:2;5350:9;5346:18;5333:32;5384:18;5425:2;5417:6;5414:14;5411:34;;;5441:1;5438;5431:12;5411:34;5464:59;5515:7;5506:6;5495:9;5491:22;5464:59;:::i;:::-;5454:69;;5576:2;5565:9;5561:18;5548:32;5532:48;;5605:2;5595:8;5592:16;5589:36;;;5621:1;5618;5611:12;5589:36;5644:61;5697:7;5686:8;5675:9;5671:24;5644:61;:::i;:::-;5634:71;;5758:3;5747:9;5743:19;5730:33;5714:49;;5788:2;5778:8;5775:16;5772:36;;;5804:1;5801;5794:12;5772:36;;5827:61;5880:7;5869:8;5858:9;5854:24;5827:61;:::i;:::-;5817:71;;;4908:986;;;;;;;;:::o;6113:184::-;6165:77;6162:1;6155:88;6262:4;6259:1;6252:15;6286:4;6283:1;6276:15;6302:128;6369:9;;;6390:11;;;6387:37;;;6404:18;;:::i;6435:168::-;6508:9;;;6539;;6556:15;;;6550:22;;6536:37;6526:71;;6577:18;;:::i;6608:184::-;6660:77;6657:1;6650:88;6757:4;6754:1;6747:15;6781:4;6778:1;6771:15;6797:120;6837:1;6863;6853:35;;6868:18;;:::i;:::-;-1:-1:-1;6902:9:11;;6797:120::o;6922:125::-;6987:9;;;7008:10;;;7005:36;;;7021:18;;:::i;7052:184::-;7104:77;7101:1;7094:88;7201:4;7198:1;7191:15;7225:4;7222:1;7215:15;7241:171;7308:20;;7368:18;7357:30;;7347:41;;7337:69;;7402:1;7399;7392:12;7417:707;7507:6;7560:2;7548:9;7539:7;7535:23;7531:32;7528:52;;;7576:1;7573;7566:12;7528:52;7609:2;7603:9;7651:2;7643:6;7639:15;7720:6;7708:10;7705:22;7684:18;7672:10;7669:34;7666:62;7663:88;;;7731:18;;:::i;:::-;7767:2;7760:22;7804:23;;7867:34;7856:46;;7846:57;;7836:85;;7917:1;7914;7907:12;7836:85;7930:21;;7984:37;8017:2;8002:18;;7984:37;:::i;:::-;7979:2;7971:6;7967:15;7960:62;8055:37;8088:2;8077:9;8073:18;8055:37;:::i;:::-;8050:2;8038:15;;8031:62;8042:6;7417:707;-1:-1:-1;;;7417:707:11:o;8545:602::-;8642:6;8695:2;8683:9;8674:7;8670:23;8666:32;8663:52;;;8711:1;8708;8701:12;8663:52;8744:2;8738:9;8786:2;8778:6;8774:15;8855:6;8843:10;8840:22;8819:18;8807:10;8804:34;8801:62;8798:88;;;8866:18;;:::i;:::-;8902:2;8895:22;8941:16;;8926:32;;9001:2;8986:18;;8980:25;9045:12;9034:24;;9024:35;;9014:63;;9073:1;9070;9063:12;9014:63;9105:2;9093:15;;9086:30;9097:6;8545:602;-1:-1:-1;;;8545:602:11:o;11819:195::-;11858:3;11889:66;11882:5;11879:77;11876:103;;11959:18;;:::i;:::-;-1:-1:-1;12006:1:11;11995:13;;11819:195::o;12288:112::-;12320:1;12346;12336:35;;12351:18;;:::i;:::-;-1:-1:-1;12385:9:11;;12288:112::o;12405:184::-;12457:77;12454:1;12447:88;12554:4;12551:1;12544:15;12578:4;12575:1;12568:15;12594:151;12684:4;12677:12;;;12663;;;12659:31;;12702:14;;12699:40;;;12719:18;;:::i;12750:482::-;12839:1;12882:5;12839:1;12896:330;12917:7;12907:8;12904:21;12896:330;;;13036:4;12968:66;12964:77;12958:4;12955:87;12952:113;;;13045:18;;:::i;:::-;13095:7;13085:8;13081:22;13078:55;;;13115:16;;;;13078:55;13194:22;;;;13154:15;;;;12896:330;;;12900:3;12750:482;;;;;:::o;13237:866::-;13286:5;13316:8;13306:80;;-1:-1:-1;13357:1:11;13371:5;;13306:80;13405:4;13395:76;;-1:-1:-1;13442:1:11;13456:5;;13395:76;13487:4;13505:1;13500:59;;;;13573:1;13568:130;;;;13480:218;;13500:59;13530:1;13521:10;;13544:5;;;13568:130;13605:3;13595:8;13592:17;13589:43;;;13612:18;;:::i;:::-;-1:-1:-1;;13668:1:11;13654:16;;13683:5;;13480:218;;13782:2;13772:8;13769:16;13763:3;13757:4;13754:13;13750:36;13744:2;13734:8;13731:16;13726:2;13720:4;13717:12;13713:35;13710:77;13707:159;;;-1:-1:-1;13819:19:11;;;13851:5;;13707:159;13898:34;13923:8;13917:4;13898:34;:::i;:::-;14028:6;13960:66;13956:79;13947:7;13944:92;13941:118;;;14039:18;;:::i;:::-;14077:20;;13237:866;-1:-1:-1;;;13237:866:11:o;14108:131::-;14168:5;14197:36;14224:8;14218:4;14197:36;:::i
Swarm Source
none://164736f6c6343000814000a
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 ]
[ 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.