Source Code
Latest 25 from a total of 361 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Add Round Data S... | 24973052 | 145 days ago | IN | 0 FRAX | 0.00547729 | ||||
| Add Round Data S... | 24961804 | 146 days ago | IN | 0 FRAX | 0.12649665 | ||||
| Add Round Data S... | 24930150 | 146 days ago | IN | 0 FRAX | 0.00143734 | ||||
| Add Round Data S... | 24887258 | 147 days ago | IN | 0 FRAX | 0.00085669 | ||||
| Add Round Data S... | 24882905 | 147 days ago | IN | 0 FRAX | 0.00083603 | ||||
| Add Round Data S... | 24844352 | 148 days ago | IN | 0 FRAX | 0.00172553 | ||||
| Add Round Data S... | 24801467 | 149 days ago | IN | 0 FRAX | 0.00147283 | ||||
| Add Round Data S... | 24801452 | 149 days ago | IN | 0 FRAX | 0.00148119 | ||||
| Add Max Distribu... | 24801307 | 149 days ago | IN | 0 FRAX | 0.00102751 | ||||
| Add Max Distribu... | 24801302 | 149 days ago | IN | 0 FRAX | 0.00102751 | ||||
| Add Round Data S... | 24764412 | 150 days ago | IN | 0 FRAX | 0.00234706 | ||||
| Add Round Data S... | 24764399 | 150 days ago | IN | 0 FRAX | 0.00250925 | ||||
| Add Round Data S... | 24750301 | 150 days ago | IN | 0 FRAX | 0.01394532 | ||||
| Add Round Data S... | 24707402 | 151 days ago | IN | 0 FRAX | 0.00638709 | ||||
| Add Round Data S... | 24698099 | 152 days ago | IN | 0 FRAX | 0.00202041 | ||||
| Add Round Data S... | 24664503 | 152 days ago | IN | 0 FRAX | 0.00279048 | ||||
| Add Round Data S... | 24621600 | 153 days ago | IN | 0 FRAX | 0.00272315 | ||||
| Add Round Data S... | 24618299 | 154 days ago | IN | 0 FRAX | 0.00210295 | ||||
| Add Round Data S... | 24578701 | 154 days ago | IN | 0 FRAX | 0.00382231 | ||||
| Add Round Data S... | 24535806 | 155 days ago | IN | 0 FRAX | 0.02393728 | ||||
| Add Round Data S... | 24535801 | 155 days ago | IN | 0 FRAX | 0.02391925 | ||||
| Add Max Distribu... | 24535667 | 155 days ago | IN | 0 FRAX | 0.01374498 | ||||
| Add Max Distribu... | 24535651 | 155 days ago | IN | 0 FRAX | 0.01459779 | ||||
| Add Round Data S... | 24504901 | 156 days ago | IN | 0 FRAX | 0.00090062 | ||||
| Add Round Data S... | 24462006 | 157 days ago | IN | 0 FRAX | 0.00114399 |
Advanced mode: Intended for advanced users or developers and will display all Internal Transactions including zero value transfers.
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | ||||
|---|---|---|---|---|---|---|---|
| 24973052 | 145 days ago | 0 FRAX | |||||
| 24973052 | 145 days ago | 0 FRAX | |||||
| 24961804 | 146 days ago | 0 FRAX | |||||
| 24961804 | 146 days ago | 0 FRAX | |||||
| 24930150 | 146 days ago | 0 FRAX | |||||
| 24930150 | 146 days ago | 0 FRAX | |||||
| 24887258 | 147 days ago | 0 FRAX | |||||
| 24887258 | 147 days ago | 0 FRAX | |||||
| 24882905 | 147 days ago | 0 FRAX | |||||
| 24882905 | 147 days ago | 0 FRAX | |||||
| 24844352 | 148 days ago | 0 FRAX | |||||
| 24844352 | 148 days ago | 0 FRAX | |||||
| 24801467 | 149 days ago | 0 FRAX | |||||
| 24801467 | 149 days ago | 0 FRAX | |||||
| 24801452 | 149 days ago | 0 FRAX | |||||
| 24801452 | 149 days ago | 0 FRAX | |||||
| 24801307 | 149 days ago | 0 FRAX | |||||
| 24801307 | 149 days ago | 0 FRAX | |||||
| 24801302 | 149 days ago | 0 FRAX | |||||
| 24801302 | 149 days ago | 0 FRAX | |||||
| 24764412 | 150 days ago | 0 FRAX | |||||
| 24764412 | 150 days ago | 0 FRAX | |||||
| 24764399 | 150 days ago | 0 FRAX | |||||
| 24764399 | 150 days ago | 0 FRAX | |||||
| 24750301 | 150 days ago | 0 FRAX |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
MerkleProofPriceSourceSfrxUsd
Compiler Version
v0.8.28+commit.7893614a
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ===================== MerkleProofSfrxUsd ===========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// ====================================================================
import { ERC165Storage } from "src/contracts/utils/ERC165Storage.sol";
import { Timelock2Step } from "frax-std/access-control/v1/Timelock2Step.sol";
import { ITimelock2Step } from "frax-std/access-control/v1/interfaces/ITimelock2Step.sol";
import { MerkleTreeProver } from "./lib/MerkleTreeProver.sol";
import { StateProofVerifier as Verifier } from "./lib/StateProofVerifier.sol";
import { IERC4626Receiver } from "src/contracts/interfaces/IERC4626Receiver.sol";
import { IStateRootOracle } from "./interfaces/IStateRootOracle.sol";
import { FixedPointMathLib } from "@solmate/utils/FixedPointMathLib.sol";
/// @title MerkleProofPriceSource
/// @notice Proves price round data from an L1 Frax Oracle and pushes the price data to an L2 Frax Oracle
contract MerkleProofPriceSourceSfrxUsd is ERC165Storage, Timelock2Step {
/// @notice The address of the StateRootOracle on Layer 2
IStateRootOracle public immutable STATE_ROOT_ORACLE;
using FixedPointMathLib for uint256;
struct OracleConfig {
address layer1Oracle;
uint96 lastBlockProofed;
}
struct ProofPackedSfrxUsd {
bytes[] _accountProofsfrxUsd;
bytes[] _storageProofTotalSupply;
bytes[] _storageProofTotalAssets;
bytes[] _storageProofLastDist;
bytes[] _storageProofRewardsPacked;
bytes[] _storageProofRewardsCycleAmount;
}
/// @notice Information about the current rewards cycle
struct RewardsCycleData {
uint40 cycleEnd; // Timestamp of the end of the current rewards cycle
uint40 lastSync; // Timestamp of the last time the rewards cycle was synced
uint216 rewardCycleAmount; // Amount of rewards to be distributed in the current cycle
}
/// @notice Configuration linking Frax Oracles for the same asset on L1 / L2
mapping(address layer2FraxOracle => OracleConfig layer1Config) public oracleLookup;
/// @notice The ```constructor``` function
/// @param _stateRootOracle Address of the L2 StateRootOracle
/// @param _timelockAddress Address of Timelock contract on L2
constructor(address _stateRootOracle, address _timelockAddress) Timelock2Step() {
_setTimelock({ _newTimelock: _timelockAddress });
_registerInterface({ interfaceId: type(ITimelock2Step).interfaceId });
STATE_ROOT_ORACLE = IStateRootOracle(_stateRootOracle);
}
// ====================================================================
// Events
// ====================================================================
/// @notice The ```OraclePairAdded``` event is emitted when a new Frax Oracle pair is added
/// @param fraxOracleLayer1 The address of the layer 1 Frax Oracle
/// @param fraxOracleLayer2 The address of the layer 2 Frax Oracle
event OraclePairAdded(address indexed fraxOracleLayer1, address indexed fraxOracleLayer2);
// ====================================================================
// Configuration Setters
// ====================================================================
/// @dev A pair of addresses that are the Frax Oracles for the same asset on layer 1 and layer 2
struct OraclePair {
address layer1FraxOracle;
address layer2FraxOracle;
}
/// @notice The ```addOraclePairs``` function sets an L1/L2 pair if they haven't been set already
/// @param _oraclePairs List of OraclePairs representing the same oracle on L1 and L2
function addOraclePairs(OraclePair[] calldata _oraclePairs) external {
_requireTimelock();
for (uint256 i = 0; i < _oraclePairs.length; ++i) {
OraclePair memory _oraclePair = _oraclePairs[i];
if (oracleLookup[_oraclePair.layer2FraxOracle].layer1Oracle != address(0)) {
revert OraclePairAlreadySet({
fraxOracleLayer1: oracleLookup[_oraclePair.layer2FraxOracle].layer1Oracle,
fraxOracleLayer2: _oraclePair.layer2FraxOracle
});
}
oracleLookup[_oraclePair.layer2FraxOracle].layer1Oracle = _oraclePair.layer1FraxOracle;
emit OraclePairAdded({
fraxOracleLayer1: _oraclePair.layer1FraxOracle,
fraxOracleLayer2: _oraclePair.layer2FraxOracle
});
}
}
// ====================================================================
// Proof / Add Price Function
// ====================================================================
function _fetchAndProofMaxRewards(
address _sfrxUsdAddress,
uint96 _blockNumber,
bytes[] memory _accountProofSfrxUsd,
bytes[] memory _storageProofMaxDistPerSecond
) public view returns (uint256 maxDistributionPerSecond) {
IStateRootOracle.BlockInfo memory _blockInfo = STATE_ROOT_ORACLE.getBlockInfo(_blockNumber);
Verifier.Account memory accountProofsfrxUsd = MerkleTreeProver.proveStorageRoot({
stateRootHash: _blockInfo.stateRootHash,
proofAddress: _sfrxUsdAddress,
accountProof: _accountProofSfrxUsd
});
maxDistributionPerSecond = uint256(
MerkleTreeProver
.proveStorageSlotValue({
storageRootHash: accountProofsfrxUsd.storageRoot,
slot: bytes32(uint256(12)),
storageProof: _storageProofMaxDistPerSecond
})
.value
);
if (maxDistributionPerSecond == 0) revert MustBeGtZero();
}
function _fetchAndProofsfrxUsd(
address _sfrxUsdEthAddress,
uint96 _blockNumber,
ProofPackedSfrxUsd memory proofPacked
)
internal
view
returns (
uint256 totalSupply,
uint256 totalAssets,
uint256 lastRewardsDistribution,
IERC4626Receiver.RewardsCycleData memory data
)
{
data = IERC4626Receiver.RewardsCycleData(0, 0, 0);
IStateRootOracle.BlockInfo memory _blockInfo = STATE_ROOT_ORACLE.getBlockInfo(_blockNumber);
Verifier.Account memory _accountProofSfrxUsd = MerkleTreeProver.proveStorageRoot({
stateRootHash: _blockInfo.stateRootHash,
proofAddress: _sfrxUsdEthAddress,
accountProof: proofPacked._accountProofsfrxUsd
});
totalSupply = uint256(
MerkleTreeProver
.proveStorageSlotValue({
storageRootHash: _accountProofSfrxUsd.storageRoot,
slot: bytes32(uint256(2)),
storageProof: proofPacked._storageProofTotalSupply
})
.value
);
totalAssets = uint256(
MerkleTreeProver
.proveStorageSlotValue({
storageRootHash: _accountProofSfrxUsd.storageRoot,
slot: bytes32(uint256(9)),
storageProof: proofPacked._storageProofTotalAssets
})
.value
);
lastRewardsDistribution = uint256(
MerkleTreeProver
.proveStorageSlotValue({
storageRootHash: _accountProofSfrxUsd.storageRoot,
slot: bytes32(uint256(8)),
storageProof: proofPacked._storageProofLastDist
})
.value
);
{
uint256 rewardsPacked = uint256(
MerkleTreeProver
.proveStorageSlotValue({
storageRootHash: _accountProofSfrxUsd.storageRoot,
slot: bytes32(uint256(6)),
storageProof: proofPacked._storageProofRewardsPacked
})
.value
);
uint256 rewardCycleAmount = uint256(
MerkleTreeProver
.proveStorageSlotValue({
storageRootHash: _accountProofSfrxUsd.storageRoot,
slot: bytes32(uint256(7)),
storageProof: proofPacked._storageProofRewardsCycleAmount
})
.value
);
data.lastSync = uint40(bytes5(bytes32(rewardsPacked) << 176));
data.cycleEnd = uint40(bytes5(bytes32(rewardsPacked) << 216));
data.rewardCycleAmount = uint216(bytes27(bytes32(rewardCycleAmount) << 40));
}
if (totalSupply == 0) revert MustBeGtZero();
if (data.lastSync == 0) revert MustBeGtZero();
if (totalAssets == 0) revert MustBeGtZero();
if (lastRewardsDistribution == 0) revert MustBeGtZero();
if (data.rewardCycleAmount == 0) revert MustBeGtZero();
}
function addMaxDistributionPerSecond(
IERC4626Receiver _sfrxUsdOracle,
uint96 _blockNumber,
bytes[] memory _accountProofsfrxUsd,
bytes[] memory _storageProofMaxDistPerSecond
) external {
uint96 lastBlockProofed = oracleLookup[address(_sfrxUsdOracle)].lastBlockProofed;
if (lastBlockProofed != 0) {
if (_blockNumber < lastBlockProofed) revert StalePush();
}
// Address of the L1 oracle
address _proofAddress = oracleLookup[address(_sfrxUsdOracle)].layer1Oracle;
if (_proofAddress == address(0)) revert WrongOracleAddress();
uint256 maxPerSecond = _fetchAndProofMaxRewards(
_proofAddress,
_blockNumber,
_accountProofsfrxUsd,
_storageProofMaxDistPerSecond
);
_sfrxUsdOracle.updateMaxDistributionPerSecond(_blockNumber, maxPerSecond);
}
function addRoundDataSfrxUsd(
IERC4626Receiver _sfrxUsdOracle,
uint96 _blockNumber,
ProofPackedSfrxUsd memory proof
) external {
uint96 lastBlockProofed = oracleLookup[address(_sfrxUsdOracle)].lastBlockProofed;
address _proofAddress;
{
if (lastBlockProofed != 0) {
if (_blockNumber < lastBlockProofed) revert StalePush();
}
// Address of the L1 oracle
_proofAddress = oracleLookup[address(_sfrxUsdOracle)].layer1Oracle;
if (_proofAddress == address(0)) revert WrongOracleAddress();
}
(
uint256 totalSupply,
uint256 totalStoredAssets,
uint256 lastRewardsDistribution,
IERC4626Receiver.RewardsCycleData memory data
) = _fetchAndProofsfrxUsd(_proofAddress, _blockNumber, proof);
_sfrxUsdOracle.updatesFRAXData(_blockNumber, totalSupply, totalStoredAssets, lastRewardsDistribution, data);
oracleLookup[address(_sfrxUsdOracle)].lastBlockProofed = _blockNumber;
}
// ====================================================================
// Errors
// ====================================================================
error OraclePairAlreadySet(address fraxOracleLayer1, address fraxOracleLayer2);
error WrongOracleAddress();
error StalePush();
error MustBeGtZero();
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165Storage.sol)
pragma solidity ^0.8.0;
import { ERC165 } from "@openzeppelin/contracts/utils/introspection/ERC165.sol";
/**
* @dev Storage based implementation of the {IERC165} interface.
*
* Contracts may inherit from this and call {_registerInterface} to declare
* their support of an interface.
*/
abstract contract ERC165Storage is ERC165 {
/**
* @dev Mapping of interface ids to whether or not it's supported.
*/
mapping(bytes4 => bool) private _supportedInterfaces;
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return super.supportsInterface(interfaceId) || _supportedInterfaces[interfaceId];
}
/**
* @dev Registers the contract as an implementer of the interface defined by
* `interfaceId`. Support of the actual ERC165 interface is automatic and
* registering its interface id is not required.
*
* See {IERC165-supportsInterface}.
*
* Requirements:
*
* - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
*/
function _registerInterface(bytes4 interfaceId) internal virtual {
require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
_supportedInterfaces[interfaceId] = true;
}
}// SPDX-License-Identifier: ISC
pragma solidity >=0.8.0;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ========================== Timelock2Step ===========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Primary Author
// Drake Evans: https://github.com/DrakeEvans
// Reviewers
// Dennis: https://github.com/denett
// ====================================================================
/// @title Timelock2Step
/// @author Drake Evans (Frax Finance) https://github.com/drakeevans
/// @dev Inspired by the OpenZeppelin's Ownable2Step contract
/// @notice An abstract contract which contains 2-step transfer and renounce logic for a timelock address
abstract contract Timelock2Step {
/// @notice The pending timelock address
address public pendingTimelockAddress;
/// @notice The current timelock address
address public timelockAddress;
constructor() {
timelockAddress = msg.sender;
}
/// @notice Emitted when timelock is transferred
error OnlyTimelock();
/// @notice Emitted when pending timelock is transferred
error OnlyPendingTimelock();
/// @notice The ```TimelockTransferStarted``` event is emitted when the timelock transfer is initiated
/// @param previousTimelock The address of the previous timelock
/// @param newTimelock The address of the new timelock
event TimelockTransferStarted(address indexed previousTimelock, address indexed newTimelock);
/// @notice The ```TimelockTransferred``` event is emitted when the timelock transfer is completed
/// @param previousTimelock The address of the previous timelock
/// @param newTimelock The address of the new timelock
event TimelockTransferred(address indexed previousTimelock, address indexed newTimelock);
/// @notice The ```_isSenderTimelock``` function checks if msg.sender is current timelock address
/// @return Whether or not msg.sender is current timelock address
function _isSenderTimelock() internal view returns (bool) {
return msg.sender == timelockAddress;
}
/// @notice The ```_requireTimelock``` function reverts if msg.sender is not current timelock address
function _requireTimelock() internal view {
if (msg.sender != timelockAddress) revert OnlyTimelock();
}
/// @notice The ```_isSenderPendingTimelock``` function checks if msg.sender is pending timelock address
/// @return Whether or not msg.sender is pending timelock address
function _isSenderPendingTimelock() internal view returns (bool) {
return msg.sender == pendingTimelockAddress;
}
/// @notice The ```_requirePendingTimelock``` function reverts if msg.sender is not pending timelock address
function _requirePendingTimelock() internal view {
if (msg.sender != pendingTimelockAddress) revert OnlyPendingTimelock();
}
/// @notice The ```_transferTimelock``` function initiates the timelock transfer
/// @dev This function is to be implemented by a public function
/// @param _newTimelock The address of the nominated (pending) timelock
function _transferTimelock(address _newTimelock) internal {
pendingTimelockAddress = _newTimelock;
emit TimelockTransferStarted(timelockAddress, _newTimelock);
}
/// @notice The ```_acceptTransferTimelock``` function completes the timelock transfer
/// @dev This function is to be implemented by a public function
function _acceptTransferTimelock() internal {
pendingTimelockAddress = address(0);
_setTimelock(msg.sender);
}
/// @notice The ```_setTimelock``` function sets the timelock address
/// @dev This function is to be implemented by a public function
/// @param _newTimelock The address of the new timelock
function _setTimelock(address _newTimelock) internal {
emit TimelockTransferred(timelockAddress, _newTimelock);
timelockAddress = _newTimelock;
}
/// @notice The ```transferTimelock``` function initiates the timelock transfer
/// @dev Must be called by the current timelock
/// @param _newTimelock The address of the nominated (pending) timelock
function transferTimelock(address _newTimelock) external virtual {
_requireTimelock();
_transferTimelock(_newTimelock);
}
/// @notice The ```acceptTransferTimelock``` function completes the timelock transfer
/// @dev Must be called by the pending timelock
function acceptTransferTimelock() external virtual {
_requirePendingTimelock();
_acceptTransferTimelock();
}
/// @notice The ```renounceTimelock``` function renounces the timelock after setting pending timelock to current timelock
/// @dev Pending timelock must be set to current timelock before renouncing, creating a 2-step renounce process
function renounceTimelock() external virtual {
_requireTimelock();
_requirePendingTimelock();
_transferTimelock(address(0));
_setTimelock(address(0));
}
}// SPDX-License-Identifier: UNLICENSED
pragma solidity >=0.8.0;
interface ITimelock2Step {
event TimelockTransferStarted(address indexed previousTimelock, address indexed newTimelock);
event TimelockTransferred(address indexed previousTimelock, address indexed newTimelock);
function acceptTransferTimelock() external;
function pendingTimelockAddress() external view returns (address);
function renounceTimelock() external;
function timelockAddress() external view returns (address);
function transferTimelock(address _newTimelock) external;
}//SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
// ====================================================================
// | ______ _______ |
// | / _____________ __ __ / ____(_____ ____ _____ ________ |
// | / /_ / ___/ __ `| |/_/ / /_ / / __ \/ __ `/ __ \/ ___/ _ \ |
// | / __/ / / / /_/ _> < / __/ / / / / / /_/ / / / / /__/ __/ |
// | /_/ /_/ \__,_/_/|_| /_/ /_/_/ /_/\__,_/_/ /_/\___/\___/ |
// | |
// ====================================================================
// ========================= MerkleTreeProver =========================
// ====================================================================
// Frax Finance: https://github.com/FraxFinance
// Authors
// Jon Walch: https://github.com/jonwalch
// Dennis: https://github.com/denett
// Reviewers
// Drake Evans: https://github.com/DrakeEvans
// ====================================================================
import { RLPReader } from "rlp/RLPReader.sol";
import { StateProofVerifier as Verifier } from "./StateProofVerifier.sol";
/// @title MerkleTreeProver
/// @author Jon Walch (Frax Finance) https://github.com/jonwalch
/// @notice Helper function library for interacting with StateProofVerifier and RLPReader
library MerkleTreeProver {
using RLPReader for bytes;
using RLPReader for RLPReader.RLPItem;
/// @notice The ```proveStorageRoot``` function is a helper function for StateProofVerifier.extractAccountFromProof()
/// @param stateRootHash The hash of the state root
/// @param proofAddress The address of the contract we're proving
/// @param accountProof The accountProof retrieved from eth_getProof
function proveStorageRoot(
bytes32 stateRootHash,
address proofAddress,
bytes[] memory accountProof
) internal view returns (Verifier.Account memory accountPool) {
RLPReader.RLPItem[] memory accountProofRlp = new RLPReader.RLPItem[](accountProof.length);
for (uint256 i = 0; i < accountProof.length; ++i) {
accountProofRlp[i] = accountProof[i].toRlpItem();
}
accountPool = Verifier.extractAccountFromProof({
_addressHash: keccak256(abi.encodePacked(proofAddress)),
_stateRootHash: stateRootHash,
_proof: accountProofRlp
});
}
/// @notice The ```proveStorageSlotValue``` function is a helper function for StateProofVerifier.extractSlotValueFromProof()
/// @param storageRootHash The hash of the storage root
/// @param slot The slot we want to prove for the contract
/// @param storageProof The storageProof.proof retrieved from eth_getProof
function proveStorageSlotValue(
bytes32 storageRootHash,
bytes32 slot,
bytes[] memory storageProof
) internal view returns (Verifier.SlotValue memory slotValue) {
RLPReader.RLPItem[] memory storageProofRlp = new RLPReader.RLPItem[](storageProof.length);
for (uint256 i = 0; i < storageProof.length; ++i) {
storageProofRlp[i] = storageProof[i].toRlpItem();
}
slotValue = Verifier.extractSlotValueFromProof({
_slotHash: keccak256(abi.encodePacked(slot)),
_storageRootHash: storageRootHash,
_proof: storageProofRlp
});
}
}// SPDX-License-Identifier: MIT
// Copied from https://github.com/lidofinance/curve-merkle-oracle/blob/1033b3e84142317ffd8f366b52e489d5eb49c73f/contracts/StateProofVerifier.sol
pragma solidity ^0.8.20;
import { RLPReader } from "rlp/RLPReader.sol";
import { MerklePatriciaProofVerifier } from "./MerklePatriciaProofVerifier.sol";
/**
* @title A helper library for verification of Merkle Patricia account and state proofs.
*/
library StateProofVerifier {
using RLPReader for RLPReader.RLPItem;
using RLPReader for bytes;
uint256 constant HEADER_STATE_ROOT_INDEX = 3;
uint256 constant HEADER_NUMBER_INDEX = 8;
uint256 constant HEADER_TIMESTAMP_INDEX = 11;
struct BlockHeader {
bytes32 hash;
bytes32 stateRootHash;
uint256 number;
uint256 timestamp;
}
struct Account {
bool exists;
uint256 nonce;
uint256 balance;
bytes32 storageRoot;
bytes32 codeHash;
}
struct SlotValue {
bool exists;
uint256 value;
}
/**
* @notice Parses block header and verifies its presence onchain within the latest 256 blocks.
* @param _headerRlpBytes RLP-encoded block header.
*/
function verifyBlockHeader(bytes memory _headerRlpBytes) internal view returns (BlockHeader memory) {
BlockHeader memory header = parseBlockHeader(_headerRlpBytes);
// ensure that the block is actually in the blockchain
require(header.hash == blockhash(header.number), "blockhash mismatch");
return header;
}
/**
* @notice Parses RLP-encoded block header.
* @param _headerRlpBytes RLP-encoded block header.
*/
function parseBlockHeader(bytes memory _headerRlpBytes) internal pure returns (BlockHeader memory) {
BlockHeader memory result;
RLPReader.RLPItem[] memory headerFields = _headerRlpBytes.toRlpItem().toList();
require(headerFields.length > HEADER_TIMESTAMP_INDEX);
result.stateRootHash = bytes32(headerFields[HEADER_STATE_ROOT_INDEX].toUint());
result.number = headerFields[HEADER_NUMBER_INDEX].toUint();
result.timestamp = headerFields[HEADER_TIMESTAMP_INDEX].toUint();
result.hash = keccak256(_headerRlpBytes);
return result;
}
/**
* @notice Verifies Merkle Patricia proof of an account and extracts the account fields.
*
* @param _addressHash Keccak256 hash of the address corresponding to the account.
* @param _stateRootHash MPT root hash of the Ethereum state trie.
*/
function extractAccountFromProof(
bytes32 _addressHash, // keccak256(abi.encodePacked(address))
bytes32 _stateRootHash,
RLPReader.RLPItem[] memory _proof
) internal pure returns (Account memory) {
bytes memory acctRlpBytes = MerklePatriciaProofVerifier.extractProofValue(
_stateRootHash,
abi.encodePacked(_addressHash),
_proof
);
Account memory account;
if (acctRlpBytes.length == 0) {
return account;
}
RLPReader.RLPItem[] memory acctFields = acctRlpBytes.toRlpItem().toList();
require(acctFields.length == 4);
account.exists = true;
account.nonce = acctFields[0].toUint();
account.balance = acctFields[1].toUint();
account.storageRoot = bytes32(acctFields[2].toUint());
account.codeHash = bytes32(acctFields[3].toUint());
return account;
}
/**
* @notice Verifies Merkle Patricia proof of a slot and extracts the slot's value.
*
* @param _slotHash Keccak256 hash of the slot position.
* @param _storageRootHash MPT root hash of the account's storage trie.
*/
function extractSlotValueFromProof(
bytes32 _slotHash,
bytes32 _storageRootHash,
RLPReader.RLPItem[] memory _proof
) internal pure returns (SlotValue memory) {
bytes memory valueRlpBytes = MerklePatriciaProofVerifier.extractProofValue(
_storageRootHash,
abi.encodePacked(_slotHash),
_proof
);
SlotValue memory value;
if (valueRlpBytes.length != 0) {
value.exists = true;
value.value = valueRlpBytes.toRlpItem().toUint();
}
return value;
}
}// SPDX-License-Identifier: ISC
pragma solidity ^0.8.19;
interface IERC4626Receiver {
function updateErc4262VaultData(
uint96 _l1BlockNumber,
uint256 _totalSupply,
uint256 _totalAssets,
uint192 _lastRewardsAmount,
uint32 _lastSync,
uint32 _rewardsCycleEnd
) external;
function updateErc4262VaultData(
uint256 _totalSupply,
uint256 _totalAssets,
uint192 _lastRewardsAmount,
uint32 _lastSync,
uint32 _rewardsCycleEnd
) external;
/// @notice Information about the current rewards cycle
struct RewardsCycleData {
uint40 cycleEnd; // Timestamp of the end of the current rewards cycle
uint40 lastSync; // Timestamp of the last time the rewards cycle was synced
uint216 rewardCycleAmount; // Amount of rewards to be distributed in the current cycle
}
function updatesFRAXData(
uint96 _l1BlockNumber,
uint256 _totalSupply,
uint256 _totalAssets,
uint256 _lastDistributionAmount,
RewardsCycleData memory data
) external;
function updateMaxDistributionPerSecond(uint96 _l1BlockNumber, uint256 maxPerSecond) external;
function updateDaiVaultData(uint96 _l1BlockNumber, uint256 _dsr, uint256 _rho, uint256 _chi) external;
function getPrices() external view returns (bool, uint256, uint256);
function dsr() external view returns (uint256);
function chi() external view returns (uint256);
function rho() external view returns (uint256);
function updateSUSDeVaultData(
uint96 _l1BlockNumber,
uint256 _totalSupply,
uint256 _totalAssets,
uint256 _vestingAmount,
uint256 _lastDistributionTimestamp
) external;
function updateEzEthRateData(uint96 _l1BlockNumber, uint256 _l1Timestamp, uint256 _ezEthRate) external;
function updateFpiOracleData(
uint96 _l1BlockNumber,
uint256 _rampPeriod,
uint256 _lastUpdateTime,
uint256 _pegPriceTarget,
uint256 _pegpriceLast
) external;
function updateRsEthOracle(uint96 _l1blockNumber, uint256 _l1Timestamp, uint256 _rsEthPrice) external;
function pricePerShare() external view returns (uint256);
function updateWstEthRateData(uint96 _l1BlockNumber, uint256 _l1Timestamp, uint256 _wstEthRate) external;
}// SPDX-License-Identifier: ISC
pragma solidity ^0.8.20;
interface IStateRootOracle {
struct BlockInfo {
bytes32 stateRootHash;
uint40 timestamp;
}
function getBlockInfo(uint256 blockNumber) external view returns (BlockInfo memory _blockInfo);
}// SPDX-License-Identifier: AGPL-3.0-only
pragma solidity >=0.8.0;
/// @notice Arithmetic library with operations for fixed-point numbers.
/// @author Solmate (https://github.com/Rari-Capital/solmate/blob/main/src/utils/FixedPointMathLib.sol)
/// @author Inspired by USM (https://github.com/usmfum/USM/blob/master/contracts/WadMath.sol)
library FixedPointMathLib {
/*//////////////////////////////////////////////////////////////
SIMPLIFIED FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
uint256 internal constant WAD = 1e18; // The scalar of ETH and most ERC20s.
function mulWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, y, WAD); // Equivalent to (x * y) / WAD rounded down.
}
function mulWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, y, WAD); // Equivalent to (x * y) / WAD rounded up.
}
function divWadDown(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivDown(x, WAD, y); // Equivalent to (x * WAD) / y rounded down.
}
function divWadUp(uint256 x, uint256 y) internal pure returns (uint256) {
return mulDivUp(x, WAD, y); // Equivalent to (x * WAD) / y rounded up.
}
/*//////////////////////////////////////////////////////////////
LOW LEVEL FIXED POINT OPERATIONS
//////////////////////////////////////////////////////////////*/
function mulDivDown(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)
// Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
revert(0, 0)
}
// Divide z by the denominator.
z := div(z, denominator)
}
}
function mulDivUp(
uint256 x,
uint256 y,
uint256 denominator
) internal pure returns (uint256 z) {
assembly {
// Store x * y in z for now.
z := mul(x, y)
// Equivalent to require(denominator != 0 && (x == 0 || (x * y) / x == y))
if iszero(and(iszero(iszero(denominator)), or(iszero(x), eq(div(z, x), y)))) {
revert(0, 0)
}
// First, divide z - 1 by the denominator and add 1.
// We allow z - 1 to underflow if z is 0, because we multiply the
// end result by 0 if z is zero, ensuring we return 0 if z is zero.
z := mul(iszero(iszero(z)), add(div(sub(z, 1), denominator), 1))
}
}
function rpow(
uint256 x,
uint256 n,
uint256 scalar
) internal pure returns (uint256 z) {
assembly {
switch x
case 0 {
switch n
case 0 {
// 0 ** 0 = 1
z := scalar
}
default {
// 0 ** n = 0
z := 0
}
}
default {
switch mod(n, 2)
case 0 {
// If n is even, store scalar in z for now.
z := scalar
}
default {
// If n is odd, store x in z for now.
z := x
}
// Shifting right by 1 is like dividing by 2.
let half := shr(1, scalar)
for {
// Shift n right by 1 before looping to halve it.
n := shr(1, n)
} n {
// Shift n right by 1 each iteration to halve it.
n := shr(1, n)
} {
// Revert immediately if x ** 2 would overflow.
// Equivalent to iszero(eq(div(xx, x), x)) here.
if shr(128, x) {
revert(0, 0)
}
// Store x squared.
let xx := mul(x, x)
// Round to the nearest number.
let xxRound := add(xx, half)
// Revert if xx + half overflowed.
if lt(xxRound, xx) {
revert(0, 0)
}
// Set x to scaled xxRound.
x := div(xxRound, scalar)
// If n is even:
if mod(n, 2) {
// Compute z * x.
let zx := mul(z, x)
// If z * x overflowed:
if iszero(eq(div(zx, x), z)) {
// Revert if x is non-zero.
if iszero(iszero(x)) {
revert(0, 0)
}
}
// Round to the nearest number.
let zxRound := add(zx, half)
// Revert if zx + half overflowed.
if lt(zxRound, zx) {
revert(0, 0)
}
// Return properly scaled zxRound.
z := div(zxRound, scalar)
}
}
}
}
}
/*//////////////////////////////////////////////////////////////
GENERAL NUMBER UTILITIES
//////////////////////////////////////////////////////////////*/
function sqrt(uint256 x) internal pure returns (uint256 z) {
assembly {
// Start off with z at 1.
z := 1
// Used below to help find a nearby power of 2.
let y := x
// Find the lowest power of 2 that is at least sqrt(x).
if iszero(lt(y, 0x100000000000000000000000000000000)) {
y := shr(128, y) // Like dividing by 2 ** 128.
z := shl(64, z) // Like multiplying by 2 ** 64.
}
if iszero(lt(y, 0x10000000000000000)) {
y := shr(64, y) // Like dividing by 2 ** 64.
z := shl(32, z) // Like multiplying by 2 ** 32.
}
if iszero(lt(y, 0x100000000)) {
y := shr(32, y) // Like dividing by 2 ** 32.
z := shl(16, z) // Like multiplying by 2 ** 16.
}
if iszero(lt(y, 0x10000)) {
y := shr(16, y) // Like dividing by 2 ** 16.
z := shl(8, z) // Like multiplying by 2 ** 8.
}
if iszero(lt(y, 0x100)) {
y := shr(8, y) // Like dividing by 2 ** 8.
z := shl(4, z) // Like multiplying by 2 ** 4.
}
if iszero(lt(y, 0x10)) {
y := shr(4, y) // Like dividing by 2 ** 4.
z := shl(2, z) // Like multiplying by 2 ** 2.
}
if iszero(lt(y, 0x8)) {
// Equivalent to 2 ** z.
z := shl(1, z)
}
// Shifting right by 1 is like dividing by 2.
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
z := shr(1, add(z, div(x, z)))
// Compute a rounded down version of z.
let zRoundDown := div(x, z)
// If zRoundDown is smaller, use it.
if lt(zRoundDown, z) {
z := zRoundDown
}
}
}
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v5.1.0) (utils/introspection/ERC165.sol)
pragma solidity ^0.8.20;
import {IERC165} from "./IERC165.sol";
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC-165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}// SPDX-License-Identifier: Apache-2.0 /* * @author Hamdi Allam [email protected] * Please reach out with any questions or concerns */ pragma solidity >=0.5.10 <0.9.0; library RLPReader { uint8 constant STRING_SHORT_START = 0x80; uint8 constant STRING_LONG_START = 0xb8; uint8 constant LIST_SHORT_START = 0xc0; uint8 constant LIST_LONG_START = 0xf8; uint8 constant WORD_SIZE = 32; struct RLPItem { uint256 len; uint256 memPtr; } struct Iterator { RLPItem item; // Item that's being iterated over. uint256 nextPtr; // Position of the next item in the list. } /* * @dev Returns the next element in the iteration. Reverts if it has not next element. * @param self The iterator. * @return The next element in the iteration. */ function next(Iterator memory self) internal pure returns (RLPItem memory) { require(hasNext(self)); uint256 ptr = self.nextPtr; uint256 itemLength = _itemLength(ptr); self.nextPtr = ptr + itemLength; return RLPItem(itemLength, ptr); } /* * @dev Returns true if the iteration has more elements. * @param self The iterator. * @return true if the iteration has more elements. */ function hasNext(Iterator memory self) internal pure returns (bool) { RLPItem memory item = self.item; return self.nextPtr < item.memPtr + item.len; } /* * @param item RLP encoded bytes */ function toRlpItem(bytes memory item) internal pure returns (RLPItem memory) { uint256 memPtr; assembly { memPtr := add(item, 0x20) } return RLPItem(item.length, memPtr); } /* * @dev Create an iterator. Reverts if item is not a list. * @param self The RLP item. * @return An 'Iterator' over the item. */ function iterator(RLPItem memory self) internal pure returns (Iterator memory) { require(isList(self)); uint256 ptr = self.memPtr + _payloadOffset(self.memPtr); return Iterator(self, ptr); } /* * @param the RLP item. */ function rlpLen(RLPItem memory item) internal pure returns (uint256) { return item.len; } /* * @param the RLP item. * @return (memPtr, len) pair: location of the item's payload in memory. */ function payloadLocation(RLPItem memory item) internal pure returns (uint256, uint256) { uint256 offset = _payloadOffset(item.memPtr); uint256 memPtr = item.memPtr + offset; uint256 len = item.len - offset; // data length return (memPtr, len); } /* * @param the RLP item. */ function payloadLen(RLPItem memory item) internal pure returns (uint256) { (, uint256 len) = payloadLocation(item); return len; } /* * @param the RLP item containing the encoded list. */ function toList(RLPItem memory item) internal pure returns (RLPItem[] memory) { require(isList(item)); uint256 items = numItems(item); RLPItem[] memory result = new RLPItem[](items); uint256 memPtr = item.memPtr + _payloadOffset(item.memPtr); uint256 dataLen; for (uint256 i = 0; i < items; i++) { dataLen = _itemLength(memPtr); result[i] = RLPItem(dataLen, memPtr); memPtr = memPtr + dataLen; } require(memPtr - item.memPtr == item.len); 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();
}
if (i == stack.length - 1) {
// need to process the child now
revert();
}
} 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.1.0) (utils/introspection/IERC165.sol)
pragma solidity ^0.8.20;
/**
* @dev Interface of the ERC-165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[ERC].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[ERC section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}{
"remappings": [
"ds-test/=node_modules/ds-test/src/",
"forge-std/=node_modules/forge-std/src/",
"frax-std/=node_modules/frax-standard-solidity/src/",
"script/=src/script/",
"src/=src/",
"test/=src/test/",
"interfaces/=src/contracts/interfaces/",
"arbitrum/=node_modules/@arbitrum/",
"rlp/=node_modules/solidity-rlp/contracts/",
"@solmate/=node_modules/@rari-capital/solmate/src/",
"@arbitrum/=node_modules/@arbitrum/",
"@chainlink/=node_modules/@chainlink/",
"@mean-finance/=node_modules/@mean-finance/",
"@openzeppelin/=node_modules/@openzeppelin/",
"@rari-capital/=node_modules/@rari-capital/",
"@uniswap/=node_modules/@uniswap/",
"dev-fraxswap/=node_modules/dev-fraxswap/",
"frax-standard-solidity/=node_modules/frax-standard-solidity/",
"prb-math/=node_modules/prb-math/",
"solidity-bytes-utils/=node_modules/solidity-bytes-utils/",
"solidity-rlp/=node_modules/solidity-rlp/"
],
"optimizer": {
"enabled": true,
"runs": 1000000
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "none",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"evmVersion": "shanghai",
"viaIR": false,
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_stateRootOracle","type":"address"},{"internalType":"address","name":"_timelockAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"MustBeGtZero","type":"error"},{"inputs":[],"name":"OnlyPendingTimelock","type":"error"},{"inputs":[],"name":"OnlyTimelock","type":"error"},{"inputs":[{"internalType":"address","name":"fraxOracleLayer1","type":"address"},{"internalType":"address","name":"fraxOracleLayer2","type":"address"}],"name":"OraclePairAlreadySet","type":"error"},{"inputs":[],"name":"StalePush","type":"error"},{"inputs":[],"name":"WrongOracleAddress","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"fraxOracleLayer1","type":"address"},{"indexed":true,"internalType":"address","name":"fraxOracleLayer2","type":"address"}],"name":"OraclePairAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousTimelock","type":"address"},{"indexed":true,"internalType":"address","name":"newTimelock","type":"address"}],"name":"TimelockTransferred","type":"event"},{"inputs":[],"name":"STATE_ROOT_ORACLE","outputs":[{"internalType":"contract IStateRootOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_sfrxUsdAddress","type":"address"},{"internalType":"uint96","name":"_blockNumber","type":"uint96"},{"internalType":"bytes[]","name":"_accountProofSfrxUsd","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProofMaxDistPerSecond","type":"bytes[]"}],"name":"_fetchAndProofMaxRewards","outputs":[{"internalType":"uint256","name":"maxDistributionPerSecond","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"acceptTransferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC4626Receiver","name":"_sfrxUsdOracle","type":"address"},{"internalType":"uint96","name":"_blockNumber","type":"uint96"},{"internalType":"bytes[]","name":"_accountProofsfrxUsd","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProofMaxDistPerSecond","type":"bytes[]"}],"name":"addMaxDistributionPerSecond","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"layer1FraxOracle","type":"address"},{"internalType":"address","name":"layer2FraxOracle","type":"address"}],"internalType":"struct MerkleProofPriceSourceSfrxUsd.OraclePair[]","name":"_oraclePairs","type":"tuple[]"}],"name":"addOraclePairs","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC4626Receiver","name":"_sfrxUsdOracle","type":"address"},{"internalType":"uint96","name":"_blockNumber","type":"uint96"},{"components":[{"internalType":"bytes[]","name":"_accountProofsfrxUsd","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProofTotalSupply","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProofTotalAssets","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProofLastDist","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProofRewardsPacked","type":"bytes[]"},{"internalType":"bytes[]","name":"_storageProofRewardsCycleAmount","type":"bytes[]"}],"internalType":"struct MerkleProofPriceSourceSfrxUsd.ProofPackedSfrxUsd","name":"proof","type":"tuple"}],"name":"addRoundDataSfrxUsd","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"layer2FraxOracle","type":"address"}],"name":"oracleLookup","outputs":[{"internalType":"address","name":"layer1Oracle","type":"address"},{"internalType":"uint96","name":"lastBlockProofed","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingTimelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"timelockAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_newTimelock","type":"address"}],"name":"transferTimelock","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60a060405234801561000f575f5ffd5b5060405161298238038061298283398101604081905261002e91610163565b600280546001600160a01b031916331790556100498161006b565b610059632fa3fc3160e21b6100c6565b506001600160a01b0316608052610194565b6002546040516001600160a01b038084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b6001600160e01b031980821690036101245760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319165f908152602081905260409020805460ff19166001179055565b80516001600160a01b038116811461015e575f5ffd5b919050565b5f5f60408385031215610174575f5ffd5b61017d83610148565b915061018b60208401610148565b90509250929050565b6080516127c86101ba5f395f81816101b60152818161038c0152610e9401526127c85ff3fe608060405234801561000f575f5ffd5b50600436106100cf575f3560e01c80638c16b3ba1161007d578063edb219c011610058578063edb219c0146101eb578063f430500a14610281578063f6ccaad414610294575f5ffd5b80638c16b3ba1461019e5780639378ca56146101b1578063a6d7fdf2146101d8575f5ffd5b80634bc66f32116100ad5780634bc66f32146101555780634dd4ee5f146101755780634f8b4ae714610196575f5ffd5b806301ffc9a7146100d3578063090f3f50146100fb5780634501409514610140575b5f5ffd5b6100e66100e1366004611fd7565b61029c565b60405190151581526020015b60405180910390f35b60015461011b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f2565b61015361014e366004612037565b610323565b005b60025461011b9073ffffffffffffffffffffffffffffffffffffffff1681565b610188610183366004612253565b610337565b6040519081526020016100f2565b610153610462565b6101536101ac366004612253565b610486565b61011b7f000000000000000000000000000000000000000000000000000000000000000081565b6101536101e63660046122da565b610633565b6102486101f9366004612037565b60036020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff8116907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff9091166020830152016100f2565b61015361028f36600461234b565b6107b0565b610153610a11565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061031d57507fffffffff0000000000000000000000000000000000000000000000000000000082165f9081526020819052604090205460ff165b92915050565b61032b610a21565b61033481610a72565b50565b6040517fbb141cf40000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff841660048201525f90819073ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169063bb141cf4906024016040805180830381865afa1580156103d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103f491906124b2565b90505f610405825f01518887610ae8565b90506104198160600151600c5f1b86610c4f565b602001519250825f03610458576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050949350505050565b61046a610a21565b610472610d3d565b61047b5f610a72565b6104845f610d8e565b565b73ffffffffffffffffffffffffffffffffffffffff84165f908152600360205260409020547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff16801561052d57806bffffffffffffffffffffffff16846bffffffffffffffffffffffff16101561052d576040517f011d308100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8086165f90815260036020526040902054168061058b576040517f17e740e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61059882878787610337565b6040517f330a73550000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff881660048201526024810182905290915073ffffffffffffffffffffffffffffffffffffffff88169063330a7355906044015f604051808303815f87803b158015610614575f5ffd5b505af1158015610626573d5f5f3e3d5ffd5b5050505050505050505050565b61063b610a21565b5f5b818110156107ab575f838383818110610658576106586124f3565b90506040020180360381019061066e9190612520565b60208082015173ffffffffffffffffffffffffffffffffffffffff9081165f90815260039092526040909120549192501615610714576020818101805173ffffffffffffffffffffffffffffffffffffffff9081165f908152600390935260409283902054915183517f729d6d9c000000000000000000000000000000000000000000000000000000008152928216600484015216602482015290519081900360440190fd5b80516020808301805173ffffffffffffffffffffffffffffffffffffffff9081165f9081526003909352604080842080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169583169590951790945590518451935190821693909116917fc662d74d8469d456352095edb1ed6a69f64c66ace9fa3598de77edfccfad12a291a35060010161063d565b505050565b73ffffffffffffffffffffffffffffffffffffffff83165f908152600360205260408120547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1690811561085857816bffffffffffffffffffffffff16846bffffffffffffffffffffffff161015610858576040517f011d308100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff8085165f9081526003602052604090205416806108b7576040517f17e740e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f5f5f6108c6858989610e1b565b604080517fc473071e0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff8e166004820152602481018690526044810185905260648101849052825164ffffffffff908116608483015260208401511660a4820152908201517affffffffffffffffffffffffffffffffffffffffffffffffffffff1660c48201529397509195509350915073ffffffffffffffffffffffffffffffffffffffff8a169063c473071e9060e4015f604051808303815f87803b158015610999575f5ffd5b505af11580156109ab573d5f5f3e3d5ffd5b50505073ffffffffffffffffffffffffffffffffffffffff998a165f90815260036020526040902080546bffffffffffffffffffffffff909a16740100000000000000000000000000000000000000000299909a16989098179098555050505050505050565b610a19610d3d565b610484611145565b60025473ffffffffffffffffffffffffffffffffffffffff163314610484576040517f1c0be90a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600254604051919216907f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a905f90a350565b610b176040518060a001604052805f151581526020015f81526020015f81526020015f81526020015f81525090565b5f825167ffffffffffffffff811115610b3257610b3261206d565b604051908082528060200260200182016040528015610b7657816020015b604080518082019091525f8082526020820152815260200190600190039081610b505790505b5090505f5b8351811015610bf257610bcd848281518110610b9957610b996124f3565b60200260200101516040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b828281518110610bdf57610bdf6124f3565b6020908102919091010152600101610b7b565b506040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b166020820152610c4690603401604051602081830303815290604052805190602001208683611176565b95945050505050565b604080518082019091525f80825260208201525f825167ffffffffffffffff811115610c7d57610c7d61206d565b604051908082528060200260200182016040528015610cc157816020015b604080518082019091525f8082526020820152815260200190600190039081610c9b5790505b5090505f5b8351811015610d0957610ce4848281518110610b9957610b996124f3565b828281518110610cf657610cf66124f3565b6020908102919091010152600101610cc6565b50610c4684604051602001610d2091815260200190565b6040516020818303038152906040528051906020012086836112ee565b60015473ffffffffffffffffffffffffffffffffffffffff163314610484576040517ff5c49e6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b604080516060810182525f808252602082018190529181018290528190819050604080516060810182525f8082526020820181905281830181905291517fbb141cf40000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff881660048201529091907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff169063bb141cf4906024016040805180830381865afa158015610eed573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f1191906124b2565b90505f610f25825f01518a895f0151610ae8565b9050610f3d816060015160025f1b8960200151610c4f565b602001519550610f59816060015160095f1b8960400151610c4f565b602001519450610f75816060015160085f1b8960600151610c4f565b6020015193505f610f92826060015160065f1b8a60800151610c4f565b6020015190505f610faf836060015160075f1b8b60a00151610c4f565b60209081015164ffffffffff602885901c81169288019290925292168552507affffffffffffffffffffffffffffffffffffffffffffffffffffff1660408401525f86900361102a576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015164ffffffffff165f0361106e576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845f036110a7576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835f036110e0576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82604001517affffffffffffffffffffffffffffffffffffffffffffffffffffff165f0361113a576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505093509350935093565b600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905561048433610d8e565b6111a56040518060a001604052805f151581526020015f81526020015f81526020015f81526020015f81525090565b5f6111d284866040516020016111bd91815260200190565b60405160208183030381529060405285611377565b90506112036040518060a001604052805f151581526020015f81526020015f81526020015f81526020015f81525090565b81515f036112145791506112e79050565b5f61124d611248846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b6117ac565b9050805160041461125c575f5ffd5b6001825280516112839082905f90611276576112766124f3565b60200260200101516118cc565b602083015280516112a19082906001908110611276576112766124f3565b604083015280516112bf9082906002908110611276576112766124f3565b606083015280516112dd9082906003908110611276576112766124f3565b6080830152509150505b9392505050565b604080518082019091525f80825260208201525f61131984866040516020016111bd91815260200190565b604080518082019091525f8082526020820152909150815115610c4657600181526040805180820182525f80825260209182015281518083019092528351825280840190820152611369906118cc565b602082015295945050505050565b60605f611384845f611917565b90505f5f90505f60606113a860405180604001604052805f81526020015f81525090565b86515f036113f6577f56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42189146113db575f5ffd5b5050604080515f81526020810190915293506112e792505050565b5f5b875181101561179f5780158015611437575061143388828151811061141f5761141f6124f3565b602002602001015160208101519051902090565b8a14155b15611440575f5ffd5b8015801590611470575061146c88828151811061145f5761145f6124f3565b6020026020010151611ae4565b8414155b15611479575f5ffd5b61149b88828151811061148e5761148e6124f3565b60200260200101516117ac565b9250825160020361163f575f60606114d36114ce865f815181106114c1576114c16124f3565b6020026020010151611b3c565b611bb7565b90925090505f6114e4888a84611c4a565b90506114f08189612582565b975081518110156115515760018b516115099190612595565b841015611514575f5ffd5b5f5b6040519080825280601f01601f191660200182016040528015611540576020820181803683370190505b5099505050505050505050506112e7565b82156115b55760018b516115659190612595565b841015611570575f5ffd5b885188101561157f575f611516565b85600181518110611592576115926124f3565b602002602001015194506115a585611b3c565b99505050505050505050506112e7565b60018b516115c39190612595565b84036115cd575f5ffd5b6115f0866001815181106115e3576115e36124f3565b6020026020010151611d04565b61161e576116178660018151811061160a5761160a6124f3565b6020026020010151611d3b565b9650611637565b6116348660018151811061141f5761141f6124f3565b96505b505050611797565b8251601103611797578551851461175c575f868681518110611663576116636124f3565b016020015160f81c9050611678600187612582565b955060108160ff1610611689575f5ffd5b6116ae848260ff16815181106116a1576116a16124f3565b6020026020010151611d51565b156116e857600189516116c19190612595565b82146116cb575f5ffd5b5050604080515f81526020810190915295506112e7945050505050565b611700848260ff16815181106115e3576115e36124f3565b6117235761171c848260ff168151811061160a5761160a6124f3565b945061173e565b61173b848260ff168151811061141f5761141f6124f3565b94505b6001895161174c9190612595565b8203611756575f5ffd5b50611797565b6001885161176a9190612595565b8114611774575f5ffd5b61178a836010815181106114c1576114c16124f3565b96505050505050506112e7565b6001016113f8565b5050505050509392505050565b60606117b782611d04565b6117bf575f5ffd5b5f6117c983611d71565b90505f8167ffffffffffffffff8111156117e5576117e561206d565b60405190808252806020026020018201604052801561182957816020015b604080518082019091525f80825260208201528152602001906001900390816118035790505b5090505f61183a8560200151611df4565b85602001516118499190612582565b90505f805b848110156118a75761185f83611e6d565b9150604051806040016040528083815260200184815250848281518110611888576118886124f3565b602090810291909101015261189d8284612582565b925060010161184e565b50855160208701516118b99084612595565b146118c2575f5ffd5b5090949350505050565b80515f90158015906118e057508151602110155b6118e8575f5ffd5b5f5f6118f384611f15565b81519193509150602082101561190f5760208290036101000a90045b949350505050565b60605f835111611925575f5ffd5b5f8351600261193491906125a8565b905080831115611942575f5ffd5b61194c8382612595565b90508067ffffffffffffffff8111156119675761196761206d565b6040519080825280601f01601f191660200182016040528015611991576020820181803683370190505b5091505f835b6119a18386612582565b811015611acb576119b36002826125ec565b5f03611a35576004866119c76002846125ff565b815181106119d7576119d76124f3565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611a0257611a026124f3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350611aac565b5f86611a426002846125ff565b81518110611a5257611a526124f3565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611a7d57611a7d6124f3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505b611ab7600183612582565b9150611ac4600182612582565b9050611997565b5082518114611adc57611adc612612565b505092915050565b5f6020825f01511015611aff5760208201518251902061031d565b602082015182519020604051602001611b1a91815260200190565b604051602081830303815290604052805190602001209050919050565b919050565b8051606090611b49575f5ffd5b5f5f611b5484611f15565b915091505f8167ffffffffffffffff811115611b7257611b7261206d565b6040519080825280601f01601f191660200182016040528015611b9c576020820181803683370190505b50905060208101611bae848285611f57565b50949350505050565b5f60605f835111611bc6575f5ffd5b5f6004845f81518110611bdb57611bdb6124f3565b60209101015160f81c901c600f1690505f818103611bfe57505f92506002611c34565b81600103611c1157505f92506001611c34565b81600203611c255750600192506002611c34565b816003036100cf575060019250825b83611c3f8683611917565b935093505050915091565b5f805b8351611c598683612582565b108015611c665750825181105b1561190f57828181518110611c7d57611c7d6124f3565b01602001517fff000000000000000000000000000000000000000000000000000000000000001684611caf8784612582565b81518110611cbf57611cbf6124f3565b01602001517fff000000000000000000000000000000000000000000000000000000000000001614611cf25790506112e7565b80611cfc8161263f565b915050611c4d565b80515f908103611d1557505f919050565b602082015180515f1a9060c0821015611d3157505f9392505050565b5060019392505050565b5f5f5f611d4784611f15565b9020949350505050565b80515f90600114611d6357505f919050565b5060200151515f1a60801490565b80515f908103611d8257505f919050565b5f5f90505f611d948460200151611df4565b8460200151611da39190612582565b90505f845f01518560200151611db99190612582565b90505b80821015611deb57611dcd82611e6d565b611dd79083612582565b915082611de38161263f565b935050611dbc565b50909392505050565b80515f90811a6080811015611e0b57505f92915050565b60b8811080611e26575060c08110801590611e26575060f881105b15611e345750600192915050565b60c0811015611e6157611e49600160b8612676565b611e569060ff1682612595565b6112e7906001612582565b611e49600160f8612676565b80515f908190811a6080811015611e875760019150611f0e565b60b8811015611ead57611e9b608082612595565b611ea6906001612582565b9150611f0e565b60c0811015611eda5760b78103600185019450806020036101000a85510460018201810193505050611f0e565b60f8811015611eee57611e9b60c082612595565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b5f5f5f611f258460200151611df4565b90505f818560200151611f389190612582565b90505f82865f0151611f4a9190612595565b9196919550909350505050565b805f03611f6357505050565b60208110611f9b5782518252611f7a602084612582565b9250611f87602083612582565b9150611f94602082612595565b9050611f63565b80156107ab575f6001611faf836020612595565b611fbb906101006127b0565b611fc59190612595565b84518451821691191617835250505050565b5f60208284031215611fe7575f5ffd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146112e7575f5ffd5b73ffffffffffffffffffffffffffffffffffffffff81168114610334575f5ffd5b5f60208284031215612047575f5ffd5b81356112e781612016565b80356bffffffffffffffffffffffff81168114611b37575f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b60405160c0810167ffffffffffffffff811182821017156120bd576120bd61206d565b60405290565b6040805190810167ffffffffffffffff811182821017156120bd576120bd61206d565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212d5761212d61206d565b604052919050565b5f82601f830112612144575f5ffd5b813567ffffffffffffffff81111561215e5761215e61206d565b8060051b61216e602082016120e6565b91825260208185018101929081019086841115612189575f5ffd5b6020860192505b8383101561224957823567ffffffffffffffff8111156121ae575f5ffd5b8601603f810188136121be575f5ffd5b602081013567ffffffffffffffff8111156121db576121db61206d565b61220c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016120e6565b8181526040838301018a1015612220575f5ffd5b816040840160208301375f60208383010152808552505050602082019150602083019250612190565b9695505050505050565b5f5f5f5f60808587031215612266575f5ffd5b843561227181612016565b935061227f60208601612052565b9250604085013567ffffffffffffffff81111561229a575f5ffd5b6122a687828801612135565b925050606085013567ffffffffffffffff8111156122c2575f5ffd5b6122ce87828801612135565b91505092959194509250565b5f5f602083850312156122eb575f5ffd5b823567ffffffffffffffff811115612301575f5ffd5b8301601f81018513612311575f5ffd5b803567ffffffffffffffff811115612327575f5ffd5b8560208260061b840101111561233b575f5ffd5b6020919091019590945092505050565b5f5f5f6060848603121561235d575f5ffd5b833561236881612016565b925061237660208501612052565b9150604084013567ffffffffffffffff811115612391575f5ffd5b840160c081870312156123a2575f5ffd5b6123aa61209a565b813567ffffffffffffffff8111156123c0575f5ffd5b6123cc88828501612135565b825250602082013567ffffffffffffffff8111156123e8575f5ffd5b6123f488828501612135565b602083015250604082013567ffffffffffffffff811115612413575f5ffd5b61241f88828501612135565b604083015250606082013567ffffffffffffffff81111561243e575f5ffd5b61244a88828501612135565b606083015250608082013567ffffffffffffffff811115612469575f5ffd5b61247588828501612135565b60808301525060a082013567ffffffffffffffff811115612494575f5ffd5b6124a088828501612135565b60a08301525080925050509250925092565b5f60408284031280156124c3575f5ffd5b506124cc6120c3565b82518152602083015164ffffffffff811681146124e7575f5ffd5b60208201529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6040828403128015612531575f5ffd5b5061253a6120c3565b823561254581612016565b815260208301356124e781612016565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8082018082111561031d5761031d612555565b8181038181111561031d5761031d612555565b808202811582820484141761031d5761031d612555565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f826125fa576125fa6125bf565b500690565b5f8261260d5761260d6125bf565b500490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361266f5761266f612555565b5060010190565b60ff828116828216039081111561031d5761031d612555565b6001815b60018411156126ca578085048111156126ae576126ae612555565b60018416156126bc57908102905b60019390931c928002612693565b935093915050565b5f826126e05750600161031d565b816126ec57505f61031d565b8160018114612702576002811461270c57612728565b600191505061031d565b60ff84111561271d5761271d612555565b50506001821b61031d565b5060208310610133831016604e8410600b841016171561274b575081810a61031d565b6127767fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461268f565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156127a8576127a8612555565b029392505050565b5f6112e783836126d256fea164736f6c634300081c000a000000000000000000000000ed403d48e2bc946438b5686aa1ad65056ccf9512000000000000000000000000b26b24e6aaa874a428d7eef6002b291d24ccf271
Deployed Bytecode
0x608060405234801561000f575f5ffd5b50600436106100cf575f3560e01c80638c16b3ba1161007d578063edb219c011610058578063edb219c0146101eb578063f430500a14610281578063f6ccaad414610294575f5ffd5b80638c16b3ba1461019e5780639378ca56146101b1578063a6d7fdf2146101d8575f5ffd5b80634bc66f32116100ad5780634bc66f32146101555780634dd4ee5f146101755780634f8b4ae714610196575f5ffd5b806301ffc9a7146100d3578063090f3f50146100fb5780634501409514610140575b5f5ffd5b6100e66100e1366004611fd7565b61029c565b60405190151581526020015b60405180910390f35b60015461011b9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016100f2565b61015361014e366004612037565b610323565b005b60025461011b9073ffffffffffffffffffffffffffffffffffffffff1681565b610188610183366004612253565b610337565b6040519081526020016100f2565b610153610462565b6101536101ac366004612253565b610486565b61011b7f000000000000000000000000ed403d48e2bc946438b5686aa1ad65056ccf951281565b6101536101e63660046122da565b610633565b6102486101f9366004612037565b60036020525f908152604090205473ffffffffffffffffffffffffffffffffffffffff8116907401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1682565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526bffffffffffffffffffffffff9091166020830152016100f2565b61015361028f36600461234b565b6107b0565b610153610a11565b5f7f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316148061031d57507fffffffff0000000000000000000000000000000000000000000000000000000082165f9081526020819052604090205460ff165b92915050565b61032b610a21565b61033481610a72565b50565b6040517fbb141cf40000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff841660048201525f90819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000ed403d48e2bc946438b5686aa1ad65056ccf9512169063bb141cf4906024016040805180830381865afa1580156103d0573d5f5f3e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103f491906124b2565b90505f610405825f01518887610ae8565b90506104198160600151600c5f1b86610c4f565b602001519250825f03610458576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050949350505050565b61046a610a21565b610472610d3d565b61047b5f610a72565b6104845f610d8e565b565b73ffffffffffffffffffffffffffffffffffffffff84165f908152600360205260409020547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff16801561052d57806bffffffffffffffffffffffff16846bffffffffffffffffffffffff16101561052d576040517f011d308100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8086165f90815260036020526040902054168061058b576040517f17e740e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f61059882878787610337565b6040517f330a73550000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff881660048201526024810182905290915073ffffffffffffffffffffffffffffffffffffffff88169063330a7355906044015f604051808303815f87803b158015610614575f5ffd5b505af1158015610626573d5f5f3e3d5ffd5b5050505050505050505050565b61063b610a21565b5f5b818110156107ab575f838383818110610658576106586124f3565b90506040020180360381019061066e9190612520565b60208082015173ffffffffffffffffffffffffffffffffffffffff9081165f90815260039092526040909120549192501615610714576020818101805173ffffffffffffffffffffffffffffffffffffffff9081165f908152600390935260409283902054915183517f729d6d9c000000000000000000000000000000000000000000000000000000008152928216600484015216602482015290519081900360440190fd5b80516020808301805173ffffffffffffffffffffffffffffffffffffffff9081165f9081526003909352604080842080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169583169590951790945590518451935190821693909116917fc662d74d8469d456352095edb1ed6a69f64c66ace9fa3598de77edfccfad12a291a35060010161063d565b505050565b73ffffffffffffffffffffffffffffffffffffffff83165f908152600360205260408120547401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1690811561085857816bffffffffffffffffffffffff16846bffffffffffffffffffffffff161015610858576040517f011d308100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5073ffffffffffffffffffffffffffffffffffffffff8085165f9081526003602052604090205416806108b7576040517f17e740e800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f5f5f5f6108c6858989610e1b565b604080517fc473071e0000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff8e166004820152602481018690526044810185905260648101849052825164ffffffffff908116608483015260208401511660a4820152908201517affffffffffffffffffffffffffffffffffffffffffffffffffffff1660c48201529397509195509350915073ffffffffffffffffffffffffffffffffffffffff8a169063c473071e9060e4015f604051808303815f87803b158015610999575f5ffd5b505af11580156109ab573d5f5f3e3d5ffd5b50505073ffffffffffffffffffffffffffffffffffffffff998a165f90815260036020526040902080546bffffffffffffffffffffffff909a16740100000000000000000000000000000000000000000299909a16989098179098555050505050505050565b610a19610d3d565b610484611145565b60025473ffffffffffffffffffffffffffffffffffffffff163314610484576040517f1c0be90a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff838116918217909255600254604051919216907f162998b90abc2507f3953aa797827b03a14c42dbd9a35f09feaf02e0d592773a905f90a350565b610b176040518060a001604052805f151581526020015f81526020015f81526020015f81526020015f81525090565b5f825167ffffffffffffffff811115610b3257610b3261206d565b604051908082528060200260200182016040528015610b7657816020015b604080518082019091525f8082526020820152815260200190600190039081610b505790505b5090505f5b8351811015610bf257610bcd848281518110610b9957610b996124f3565b60200260200101516040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b828281518110610bdf57610bdf6124f3565b6020908102919091010152600101610b7b565b506040517fffffffffffffffffffffffffffffffffffffffff000000000000000000000000606086901b166020820152610c4690603401604051602081830303815290604052805190602001208683611176565b95945050505050565b604080518082019091525f80825260208201525f825167ffffffffffffffff811115610c7d57610c7d61206d565b604051908082528060200260200182016040528015610cc157816020015b604080518082019091525f8082526020820152815260200190600190039081610c9b5790505b5090505f5b8351811015610d0957610ce4848281518110610b9957610b996124f3565b828281518110610cf657610cf66124f3565b6020908102919091010152600101610cc6565b50610c4684604051602001610d2091815260200190565b6040516020818303038152906040528051906020012086836112ee565b60015473ffffffffffffffffffffffffffffffffffffffff163314610484576040517ff5c49e6400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60025460405173ffffffffffffffffffffffffffffffffffffffff8084169216907f31b6c5a04b069b6ec1b3cef44c4e7c1eadd721349cda9823d0b1877b3551cdc6905f90a3600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055565b604080516060810182525f808252602082018190529181018290528190819050604080516060810182525f8082526020820181905281830181905291517fbb141cf40000000000000000000000000000000000000000000000000000000081526bffffffffffffffffffffffff881660048201529091907f000000000000000000000000ed403d48e2bc946438b5686aa1ad65056ccf951273ffffffffffffffffffffffffffffffffffffffff169063bb141cf4906024016040805180830381865afa158015610eed573d5f5f3e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610f1191906124b2565b90505f610f25825f01518a895f0151610ae8565b9050610f3d816060015160025f1b8960200151610c4f565b602001519550610f59816060015160095f1b8960400151610c4f565b602001519450610f75816060015160085f1b8960600151610c4f565b6020015193505f610f92826060015160065f1b8a60800151610c4f565b6020015190505f610faf836060015160075f1b8b60a00151610c4f565b60209081015164ffffffffff602885901c81169288019290925292168552507affffffffffffffffffffffffffffffffffffffffffffffffffffff1660408401525f86900361102a576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826020015164ffffffffff165f0361106e576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b845f036110a7576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b835f036110e0576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b82604001517affffffffffffffffffffffffffffffffffffffffffffffffffffff165f0361113a576040517fac34915700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505093509350935093565b600180547fffffffffffffffffffffffff000000000000000000000000000000000000000016905561048433610d8e565b6111a56040518060a001604052805f151581526020015f81526020015f81526020015f81526020015f81525090565b5f6111d284866040516020016111bd91815260200190565b60405160208183030381529060405285611377565b90506112036040518060a001604052805f151581526020015f81526020015f81526020015f81526020015f81525090565b81515f036112145791506112e79050565b5f61124d611248846040805180820182525f8082526020918201528151808301909252825182529182019181019190915290565b6117ac565b9050805160041461125c575f5ffd5b6001825280516112839082905f90611276576112766124f3565b60200260200101516118cc565b602083015280516112a19082906001908110611276576112766124f3565b604083015280516112bf9082906002908110611276576112766124f3565b606083015280516112dd9082906003908110611276576112766124f3565b6080830152509150505b9392505050565b604080518082019091525f80825260208201525f61131984866040516020016111bd91815260200190565b604080518082019091525f8082526020820152909150815115610c4657600181526040805180820182525f80825260209182015281518083019092528351825280840190820152611369906118cc565b602082015295945050505050565b60605f611384845f611917565b90505f5f90505f60606113a860405180604001604052805f81526020015f81525090565b86515f036113f6577f56e81f171bcc55a6ff8345e692c0f86e5b48e01b996cadc001622fb5e363b42189146113db575f5ffd5b5050604080515f81526020810190915293506112e792505050565b5f5b875181101561179f5780158015611437575061143388828151811061141f5761141f6124f3565b602002602001015160208101519051902090565b8a14155b15611440575f5ffd5b8015801590611470575061146c88828151811061145f5761145f6124f3565b6020026020010151611ae4565b8414155b15611479575f5ffd5b61149b88828151811061148e5761148e6124f3565b60200260200101516117ac565b9250825160020361163f575f60606114d36114ce865f815181106114c1576114c16124f3565b6020026020010151611b3c565b611bb7565b90925090505f6114e4888a84611c4a565b90506114f08189612582565b975081518110156115515760018b516115099190612595565b841015611514575f5ffd5b5f5b6040519080825280601f01601f191660200182016040528015611540576020820181803683370190505b5099505050505050505050506112e7565b82156115b55760018b516115659190612595565b841015611570575f5ffd5b885188101561157f575f611516565b85600181518110611592576115926124f3565b602002602001015194506115a585611b3c565b99505050505050505050506112e7565b60018b516115c39190612595565b84036115cd575f5ffd5b6115f0866001815181106115e3576115e36124f3565b6020026020010151611d04565b61161e576116178660018151811061160a5761160a6124f3565b6020026020010151611d3b565b9650611637565b6116348660018151811061141f5761141f6124f3565b96505b505050611797565b8251601103611797578551851461175c575f868681518110611663576116636124f3565b016020015160f81c9050611678600187612582565b955060108160ff1610611689575f5ffd5b6116ae848260ff16815181106116a1576116a16124f3565b6020026020010151611d51565b156116e857600189516116c19190612595565b82146116cb575f5ffd5b5050604080515f81526020810190915295506112e7945050505050565b611700848260ff16815181106115e3576115e36124f3565b6117235761171c848260ff168151811061160a5761160a6124f3565b945061173e565b61173b848260ff168151811061141f5761141f6124f3565b94505b6001895161174c9190612595565b8203611756575f5ffd5b50611797565b6001885161176a9190612595565b8114611774575f5ffd5b61178a836010815181106114c1576114c16124f3565b96505050505050506112e7565b6001016113f8565b5050505050509392505050565b60606117b782611d04565b6117bf575f5ffd5b5f6117c983611d71565b90505f8167ffffffffffffffff8111156117e5576117e561206d565b60405190808252806020026020018201604052801561182957816020015b604080518082019091525f80825260208201528152602001906001900390816118035790505b5090505f61183a8560200151611df4565b85602001516118499190612582565b90505f805b848110156118a75761185f83611e6d565b9150604051806040016040528083815260200184815250848281518110611888576118886124f3565b602090810291909101015261189d8284612582565b925060010161184e565b50855160208701516118b99084612595565b146118c2575f5ffd5b5090949350505050565b80515f90158015906118e057508151602110155b6118e8575f5ffd5b5f5f6118f384611f15565b81519193509150602082101561190f5760208290036101000a90045b949350505050565b60605f835111611925575f5ffd5b5f8351600261193491906125a8565b905080831115611942575f5ffd5b61194c8382612595565b90508067ffffffffffffffff8111156119675761196761206d565b6040519080825280601f01601f191660200182016040528015611991576020820181803683370190505b5091505f835b6119a18386612582565b811015611acb576119b36002826125ec565b5f03611a35576004866119c76002846125ff565b815181106119d7576119d76124f3565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611a0257611a026124f3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a905350611aac565b5f86611a426002846125ff565b81518110611a5257611a526124f3565b602001015160f81c60f81b60f81c60ff16901c600f1660f81b848381518110611a7d57611a7d6124f3565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690815f1a9053505b611ab7600183612582565b9150611ac4600182612582565b9050611997565b5082518114611adc57611adc612612565b505092915050565b5f6020825f01511015611aff5760208201518251902061031d565b602082015182519020604051602001611b1a91815260200190565b604051602081830303815290604052805190602001209050919050565b919050565b8051606090611b49575f5ffd5b5f5f611b5484611f15565b915091505f8167ffffffffffffffff811115611b7257611b7261206d565b6040519080825280601f01601f191660200182016040528015611b9c576020820181803683370190505b50905060208101611bae848285611f57565b50949350505050565b5f60605f835111611bc6575f5ffd5b5f6004845f81518110611bdb57611bdb6124f3565b60209101015160f81c901c600f1690505f818103611bfe57505f92506002611c34565b81600103611c1157505f92506001611c34565b81600203611c255750600192506002611c34565b816003036100cf575060019250825b83611c3f8683611917565b935093505050915091565b5f805b8351611c598683612582565b108015611c665750825181105b1561190f57828181518110611c7d57611c7d6124f3565b01602001517fff000000000000000000000000000000000000000000000000000000000000001684611caf8784612582565b81518110611cbf57611cbf6124f3565b01602001517fff000000000000000000000000000000000000000000000000000000000000001614611cf25790506112e7565b80611cfc8161263f565b915050611c4d565b80515f908103611d1557505f919050565b602082015180515f1a9060c0821015611d3157505f9392505050565b5060019392505050565b5f5f5f611d4784611f15565b9020949350505050565b80515f90600114611d6357505f919050565b5060200151515f1a60801490565b80515f908103611d8257505f919050565b5f5f90505f611d948460200151611df4565b8460200151611da39190612582565b90505f845f01518560200151611db99190612582565b90505b80821015611deb57611dcd82611e6d565b611dd79083612582565b915082611de38161263f565b935050611dbc565b50909392505050565b80515f90811a6080811015611e0b57505f92915050565b60b8811080611e26575060c08110801590611e26575060f881105b15611e345750600192915050565b60c0811015611e6157611e49600160b8612676565b611e569060ff1682612595565b6112e7906001612582565b611e49600160f8612676565b80515f908190811a6080811015611e875760019150611f0e565b60b8811015611ead57611e9b608082612595565b611ea6906001612582565b9150611f0e565b60c0811015611eda5760b78103600185019450806020036101000a85510460018201810193505050611f0e565b60f8811015611eee57611e9b60c082612595565b60f78103600185019450806020036101000a855104600182018101935050505b5092915050565b5f5f5f611f258460200151611df4565b90505f818560200151611f389190612582565b90505f82865f0151611f4a9190612595565b9196919550909350505050565b805f03611f6357505050565b60208110611f9b5782518252611f7a602084612582565b9250611f87602083612582565b9150611f94602082612595565b9050611f63565b80156107ab575f6001611faf836020612595565b611fbb906101006127b0565b611fc59190612595565b84518451821691191617835250505050565b5f60208284031215611fe7575f5ffd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146112e7575f5ffd5b73ffffffffffffffffffffffffffffffffffffffff81168114610334575f5ffd5b5f60208284031215612047575f5ffd5b81356112e781612016565b80356bffffffffffffffffffffffff81168114611b37575f5ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b60405160c0810167ffffffffffffffff811182821017156120bd576120bd61206d565b60405290565b6040805190810167ffffffffffffffff811182821017156120bd576120bd61206d565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff8111828210171561212d5761212d61206d565b604052919050565b5f82601f830112612144575f5ffd5b813567ffffffffffffffff81111561215e5761215e61206d565b8060051b61216e602082016120e6565b91825260208185018101929081019086841115612189575f5ffd5b6020860192505b8383101561224957823567ffffffffffffffff8111156121ae575f5ffd5b8601603f810188136121be575f5ffd5b602081013567ffffffffffffffff8111156121db576121db61206d565b61220c60207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116016120e6565b8181526040838301018a1015612220575f5ffd5b816040840160208301375f60208383010152808552505050602082019150602083019250612190565b9695505050505050565b5f5f5f5f60808587031215612266575f5ffd5b843561227181612016565b935061227f60208601612052565b9250604085013567ffffffffffffffff81111561229a575f5ffd5b6122a687828801612135565b925050606085013567ffffffffffffffff8111156122c2575f5ffd5b6122ce87828801612135565b91505092959194509250565b5f5f602083850312156122eb575f5ffd5b823567ffffffffffffffff811115612301575f5ffd5b8301601f81018513612311575f5ffd5b803567ffffffffffffffff811115612327575f5ffd5b8560208260061b840101111561233b575f5ffd5b6020919091019590945092505050565b5f5f5f6060848603121561235d575f5ffd5b833561236881612016565b925061237660208501612052565b9150604084013567ffffffffffffffff811115612391575f5ffd5b840160c081870312156123a2575f5ffd5b6123aa61209a565b813567ffffffffffffffff8111156123c0575f5ffd5b6123cc88828501612135565b825250602082013567ffffffffffffffff8111156123e8575f5ffd5b6123f488828501612135565b602083015250604082013567ffffffffffffffff811115612413575f5ffd5b61241f88828501612135565b604083015250606082013567ffffffffffffffff81111561243e575f5ffd5b61244a88828501612135565b606083015250608082013567ffffffffffffffff811115612469575f5ffd5b61247588828501612135565b60808301525060a082013567ffffffffffffffff811115612494575f5ffd5b6124a088828501612135565b60a08301525080925050509250925092565b5f60408284031280156124c3575f5ffd5b506124cc6120c3565b82518152602083015164ffffffffff811681146124e7575f5ffd5b60208201529392505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f6040828403128015612531575f5ffd5b5061253a6120c3565b823561254581612016565b815260208301356124e781612016565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b8082018082111561031d5761031d612555565b8181038181111561031d5761031d612555565b808202811582820484141761031d5761031d612555565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f826125fa576125fa6125bf565b500690565b5f8261260d5761260d6125bf565b500490565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52600160045260245ffd5b5f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361266f5761266f612555565b5060010190565b60ff828116828216039081111561031d5761031d612555565b6001815b60018411156126ca578085048111156126ae576126ae612555565b60018416156126bc57908102905b60019390931c928002612693565b935093915050565b5f826126e05750600161031d565b816126ec57505f61031d565b8160018114612702576002811461270c57612728565b600191505061031d565b60ff84111561271d5761271d612555565b50506001821b61031d565b5060208310610133831016604e8410600b841016171561274b575081810a61031d565b6127767fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848461268f565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048211156127a8576127a8612555565b029392505050565b5f6112e783836126d256fea164736f6c634300081c000a
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000ed403d48e2bc946438b5686aa1ad65056ccf9512000000000000000000000000b26b24e6aaa874a428d7eef6002b291d24ccf271
-----Decoded View---------------
Arg [0] : _stateRootOracle (address): 0xeD403d48e2bC946438B5686AA1AD65056Ccf9512
Arg [1] : _timelockAddress (address): 0xb26B24e6aAA874a428D7eeF6002b291d24ccF271
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000ed403d48e2bc946438b5686aa1ad65056ccf9512
Arg [1] : 000000000000000000000000b26b24e6aaa874a428d7eef6002b291d24ccf271
Deployed Bytecode Sourcemap
1648:10283:6:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;653:188:12;;;;;;:::i;:::-;;:::i;:::-;;;516:14:13;;509:22;491:41;;479:2;464:18;653:188:12;;;;;;;;1362:37:3;;;;;;;;;;;;719:42:13;707:55;;;689:74;;677:2;662:18;1362:37:3;543:226:13;4768:141:3;;;;;;:::i;:::-;;:::i;:::-;;1451:30;;;;;;;;;5387:1024:6;;;;;;:::i;:::-;;:::i;:::-;;;4833:25:13;;;4821:2;4806:18;5387:1024:6;4687:177:13;5433:188:3;;;:::i;9609:904:6:-;;;;;;:::i;:::-;;:::i;1787:51::-;;;;;4350:845;;;;;;:::i;:::-;;:::i;2711:82::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;6814:42:13;6802:55;;;6784:74;;6906:26;6894:39;;;6889:2;6874:18;;6867:67;6757:18;2711:82:6;6612:328:13;10519:1077:6;;;;;;:::i;:::-;;:::i;5057:128:3:-;;;:::i;653:188:12:-;738:4;877:25:0;862:40;;;;761:73:12;;;-1:-1:-1;801:33:12;;;:20;:33;;;;;;;;;;;;;761:73;754:80;653:188;-1:-1:-1;;653:188:12:o;4768:141:3:-;4843:18;:16;:18::i;:::-;4871:31;4889:12;4871:17;:31::i;:::-;4768:141;:::o;5387:1024:6:-;5700:44;;;;;8991:26:13;8979:39;;5700:44:6;;;8961:58:13;5609:32:6;;;;5700:30;:17;:30;;;;8934:18:13;;5700:44:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;5653:91;;5754:43;5800:189;5863:10;:24;;;5915:15;5958:20;5800:33;:189::i;:::-;5754:235;;6047:258;6142:19;:31;;;6217:2;6201:20;;6257:29;6047:55;:258::i;:::-;:281;;;5999:339;;6352:24;6380:1;6352:29;6348:56;;6390:14;;;;;;;;;;;;;;6348:56;5643:768;;5387:1024;;;;;;:::o;5433:188:3:-;5488:18;:16;:18::i;:::-;5516:25;:23;:25::i;:::-;5551:29;5577:1;5551:17;:29::i;:::-;5590:24;5611:1;5590:12;:24::i;:::-;5433:188::o;9609:904:6:-;9866:37;;;9840:23;9866:37;;;:12;:37;;;;;:54;;;;;;9934:21;;9930:107;;9990:16;9975:31;;:12;:31;;;9971:55;;;10015:11;;;;;;;;;;;;;;9971:55;10106:37;;;;10082:21;10106:37;;;:12;:37;;;;;:50;;;10166:60;;10206:20;;;;;;;;;;;;;;10166:60;10236:20;10259:164;10297:13;10324:12;10350:20;10384:29;10259:24;:164::i;:::-;10433:73;;;;;9723:26:13;9711:39;;10433:73:6;;;9693:58:13;9767:18;;;9760:34;;;10236:187:6;;-1:-1:-1;10433:45:6;;;;;;9666:18:13;;10433:73:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9830:683;;;9609:904;;;;:::o;4350:845::-;4429:18;:16;:18::i;:::-;4463:9;4458:731;4478:23;;;4458:731;;;4522:29;4554:12;;4567:1;4554:15;;;;;;;:::i;:::-;;;;;;4522:47;;;;;;;;;;:::i;:::-;4600:28;;;;;4587:69;:42;;;4654:1;4587:42;;;:12;:42;;;;;;;:55;4522:47;;-1:-1:-1;4587:55:6;:69;4583:318;;4757:28;;;;;;4744:42;;;;;;;;:12;:42;;;;;;;;:55;4839:28;;4683:203;;;;;4744:55;;;4683:203;;;10702:74:13;10812:55;10792:18;;;10785:83;4683:203:6;;;;;;10675:18:13;4683:203:6;;;4583:318;4972:28;;4927;;;;;;4914:42;;;;4972:28;4914:42;;;:12;:42;;;;;;;:86;;;;;;;;;;;;;;5135:28;;5071;;5019:159;;;;;;;;;;;;;-1:-1:-1;4503:3:6;;4458:731;;;;4350:845;;:::o;10519:1077::-;10710:37;;;10684:23;10710:37;;;:12;:37;;;;;:54;;;;;;;10823:21;;10819:115;;10883:16;10868:31;;:12;:31;;;10864:55;;;10908:11;;;;;;;;;;;;;;10864:55;-1:-1:-1;11003:37:6;;;;;;;;:12;:37;;;;;:50;;;11067:60;;11107:20;;;;;;;;;;;;;;11067:60;11161:19;11194:25;11233:31;11278:45;11336:57;11358:13;11373:12;11387:5;11336:21;:57::i;:::-;11403:107;;;;;;11234:26:13;11222:39;;11403:107:6;;;11204:58:13;11278:18;;;11271:34;;;11321:18;;;11314:34;;;11364:18;;;11357:34;;;11432:13;;11447:12;11428:32;;;11407:19;;;11400:61;11293:2;11508:15;;11502:22;11498:41;11477:19;;;11470:70;11587:15;;;11581:22;11605:56;11577:85;11556:19;;;11549:114;11147:246:6;;-1:-1:-1;11147:246:6;;-1:-1:-1;11147:246:6;-1:-1:-1;11147:246:6;-1:-1:-1;11403:30:6;;;;;;11176:19:13;;11403:107:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;11520:37:6;;;;;;;;:12;:37;;;;;:69;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;10519:1077:6:o;5057:128:3:-;5118:25;:23;:25::i;:::-;5153;:23;:25::i;2783:115::-;2853:15;;;;2839:10;:29;2835:56;;2877:14;;;;;;;;;;;;;;3699:181;3767:22;:37;;;;;;;;;;;;;;3843:15;;3819:54;;3767:37;;3843:15;;3819:54;;-1:-1:-1;;3819:54:3;3699:181;:::o;1782:645:9:-;1935:35;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1935:35:9;1982:42;2051:12;:19;2027:44;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;2027:44:9;;;;;;;;;;;;;;;-1:-1:-1;1982:89:9;-1:-1:-1;2086:9:9;2081:123;2105:12;:19;2101:1;:23;2081:123;;;2166:27;:12;2179:1;2166:15;;;;;;;;:::i;:::-;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;1699:28:5;;;;;;;;1707:11;;1699:28;;1657:15;;;1699:28;;;;;;;;1513:221;2166:27:9;2145:15;2161:1;2145:18;;;;;;;;:::i;:::-;;;;;;;;;;:48;2126:3;;2081:123;;;-1:-1:-1;2298:30:9;;11836:66:13;11823:2;11819:15;;;11815:88;2298:30:9;;;11803:101:13;2227:193:9;;11920:12:13;;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;;;;;;;;;;;;;;;-1:-1:-1;2963:89:9;-1:-1:-1;3067:9: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;;3062:123;;;;3206:188;3293:4;3276:22;;;;;;12072:19:13;;12116:2;12107:12;;11943:182;3276:22:9;;;;;;;;;;;;;3266:33;;;;;;3331:15;3368;3206:34;:188::i;3327:136:3:-;3404:22;;;;3390:10;:36;3386:70;;3435:21;;;;;;;;;;;;;;4385:165;4473:15;;4453:50;;;;;;;4473:15;;4453:50;;4473:15;;4453:50;4513:15;:30;;;;;;;;;;;;;;;4385:165::o;6417:3186:6:-;-1:-1:-1;;;;;;;;6626:19:6;-1:-1:-1;;;;;;;;;;;;;;;6626:19:6;;;;-1:-1:-1;6814:42:6;;;;;;;;-1:-1:-1;6814:42:6;;;;;;;;;;;;;;;6913:44;;;;;8991:26:13;8979:39;;6913:44:6;;;8961:58:13;6814:42:6;;-1:-1:-1;6913:17:6;:30;;;;;8934:18:13;;6913:44:6;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6866:91;;6967:44;7014:204;7077:10;:24;;;7129:18;7175:11;:32;;;7014:33;:204::i;:::-;6967:251;;7263:265;7358:20;:32;;;7434:1;7418:19;;7473:11;:36;;;7263:55;:265::i;:::-;:288;;;7228:333;;7606:265;7701:20;:32;;;7777:1;7761:19;;7816:11;:36;;;7606:55;:265::i;:::-;:288;;;7571:333;;7961:262;8056:20;:32;;;8132:1;8116:19;;8171:11;:33;;;7961:55;:262::i;:::-;:285;;;7914:342;;8280:21;8329:287;8432:20;:32;;;8512:1;8496:19;;8555:11;:38;;;8329:59;:287::i;:::-;:314;;;8280:377;;8671:25;8724:292;8827:20;:32;;;8907:1;8891:19;;8950:11;:43;;;8724:59;:292::i;:::-;:319;;;;;9087:45;;;;;;;9071:13;;;:61;;;;9162:45;;9146:61;;-1:-1:-1;9246:50:6;;9221:22;;;:75;9101:22;9320:16;;;9316:43;;9345:14;;;;;;;;;;;;;;9316:43;9373:4;:13;;;:18;;9390:1;9373:18;9369:45;;9400:14;;;;;;;;;;;;;;9369:45;9428:11;9443:1;9428:16;9424:43;;9453:14;;;;;;;;;;;;;;9424:43;9481:23;9508:1;9481:28;9477:55;;9518:14;;;;;;;;;;;;;;9477:55;9546:4;:22;;;:27;;9572:1;9546:27;9542:54;;9582:14;;;;;;;;;;;;;;9542:54;6797:2806;;6417:3186;;;;;;;:::o;4046:130:3:-;4100:22;:35;;;;;;4145:24;4158:10;4145:12;:24::i;2565:930:10:-;2772:14;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2772:14:10;2798:25;2826:147;2885:14;2930:12;2913:30;;;;;;12072:19:13;;12116:2;12107:12;;11943:182;2913:30:10;;;;;;;;;;;;;2957:6;2826:45;:147::i;:::-;2798:175;;2984:22;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2984:22:10;3021:12;: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:5;;;;;;;;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;;;;;;12072:19:13;;12116:2;12107:12;;11943: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:5;;;;;;;;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:5638:8:-;1418:18;1448:19;1470:23;1485:4;1491:1;1470:14;:23::i;:::-;1448:45;;1503:20;1526:1;1503:24;;1538:20;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:4959;1964:5;:12;1960:1;:16;1940:4959;;;2238:6;;:50;;;;;2260:28;:5;2266:1;2260:8;;;;;;;;:::i;:::-;;;;;;;4208:11:5;;;;4243:8;;4318:19;;;4104: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:4195;;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:4195;;;5279:4;:11;5294:2;5279:17;5275:1614;;5368:6;:13;5352:12;:29;5348:1527;;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;6368:1;6353:5;:12;:16;;;;:::i;:::-;6348:1;:21;6344:141;;6454:8;;;6344:141;5383:1120;5348:1527;;;6698:1;6683:5;:12;:16;;;;:::i;:::-;6678:1;:21;6674:135;;6778:8;;;6674:135;6838:18;:4;6843:2;6838:8;;;;;;;;:::i;:18::-;6831:25;;;;;;;;;;5348:1527;1978:3;;1940:4959;;;;1438:5467;;;;;1267:5638;;;;;:::o;2946:571:5:-;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:5;;;;;;;;;;;;;;;;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:5;;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:5;;3256:179;;;-1:-1:-1;3477:8:5;;3462:11;;;;3453:20;;:6;:20;:::i;:::-;:32;3445:41;;;;;;-1:-1:-1;3504:6:5;;2946:571;-1:-1:-1;;;;2946:571:5:o;6101:467::-;6188:8;;6161:7;;6188:12;;;;:30;;-1:-1:-1;6204:8:5;;6216:2;-1:-1:-1;6204:14:5;6188:30;6180:39;;;;;;6231:14;6247:11;6262:21;6278:4;6262:15;:21::i;:::-;6351:13;;6230:53;;-1:-1:-1;6230:53:5;-1:-1:-1;6447:2:5;6439:11;;6436:92;;;6504:2;6500:12;;;6495:3;6491:22;6479:35;;6436:92;6555:6;6101:467;-1:-1:-1;;;;6101:467:5:o;8886:747:8:-;8975:20;9032:1;9015:7;:14;:18;9007:27;;;;;;9045:14;9062:7;:14;9079:1;9062:18;;;;:::i;:::-;9045:35;;9113:6;9098:11;:21;;9090:30;;;;;;9130:21;9140:11;9130:21;;:::i;:::-;;;9182:6;9172:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;9172:17:8;-1:-1:-1;9162:27:8;-1:-1:-1;9199:21:8;9252:11;9235:342;9269:20;9283:6;9269:11;:20;:::i;:::-;9265:1;:24;9235:342;;;9317:5;9321:1;9317;:5;:::i;:::-;9326:1;9317:10;9313:222;;9405:1;9386:7;9394:5;9398:1;9394;:5;:::i;:::-;9386:14;;;;;;;;:::i;:::-;;;;;;;;;9380:21;;:26;;;;9410:3;9379:34;9372:42;;9347:7;9355:13;9347:22;;;;;;;;:::i;:::-;;;;:67;;;;;;;;;;;9313:222;;;9511:1;9492:7;9500:5;9504:1;9500;:5;:::i;:::-;9492:14;;;;;;;;:::i;:::-;;;;;;;;;9486:21;;:26;;;;9516:3;9485:34;9478:42;;9453:7;9461:13;9453:22;;;;;;;;:::i;:::-;;;;:67;;;;;;;;;;;9313:222;9548:18;9565:1;9548:18;;:::i;:::-;;-1:-1:-1;9291:6:8;9296:1;9291:6;;:::i;:::-;;;9235:342;;;;9611:7;:14;9594:13;:31;9587:39;;;;:::i;:::-;8997:636;;8886:747;;;;:::o;7470:266::-;7545:7;7579:2;7568:4;:8;;;:13;7564:166;;;4208:11:5;;;;4243:8;;4318:19;;7604:24:8;4104:272:5;7564:166:8;4208:11:5;;;;4243:8;;4318:19;;7676:42:8;;;;;;12072:19:13;;12116:2;12107:12;;11943:182;7676:42:8;;;;;;;;;;;;;7666:53;;;;;;7659:60;;7470:266;;;:::o;7564:166::-;7470:266;;;:::o;6909:379:5:-;7002:8;;6970:12;;6994:21;;;;;;7027:14;7043:11;7058:21;7074:4;7058:15;:21::i;:::-;7026:53;;;;7089:19;7121:3;7111:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;7111:14:5;-1:-1:-1;7089:36:5;-1:-1:-1;7199:4:5;7195:17;;7232:26;7237:6;7195:17;7254:3;7232:4;:26::i;:::-;-1:-1:-1;7275:6:5;6909:379;-1:-1:-1;;;;6909:379:5:o;8083:797:8:-;8179:11;8192:20;8249:1;8232:7;:14;:18;8224:27;;;;;;8261:20;8306:1;8291:7;8299:1;8291:10;;;;;;;;:::i;:::-;;;;;;;;8285:22;;8311:3;8284:30;;-1:-1:-1;8324:19:8;8357:17;;;8353:458;;-1:-1:-1;8428:5:8;;-1:-1:-1;8404:1:8;8353:458;;;8454:12;8470:1;8454:17;8450:361;;-1:-1:-1;8525:5:8;;-1:-1:-1;8501:1:8;8450:361;;;8551:12;8567:1;8551:17;8547:264;;-1:-1:-1;8622:4:8;;-1:-1:-1;8598:1:8;8547:264;;;8647:12;8663:1;8647:17;8643:168;;-1:-1:-1;8694:1:8;;-1:-1:-1;8694:1:8;8643:168;8828:6;8836:36;8851:7;8860:11;8836:14;:36::i;:::-;8820:53;;;;;;8083:797;;;:::o;9639:321::-;9742:7;;9780:156;9807:9;;9792:12;9796:8;9792:1;:12;:::i;:::-;:24;:41;;;;;9824:2;:9;9820:1;:13;9792:41;9780:156;;;9878:2;9881:1;9878:5;;;;;;;;:::i;:::-;;;;;;;9858:2;9861:12;9865:8;9861:1;:12;:::i;:::-;9858:16;;;;;;;;:::i;:::-;;;;;;;:25;9854:72;;9910:1;-1:-1:-1;9903:8:8;;9854:72;9835:3;;;;:::i;:::-;;;;9780:156;;3621:321:5;3701:8;;3681:4;;3701:13;;3697:31;;-1:-1:-1;3723:5:5;;3621:321;-1:-1:-1;3621:321:5:o;3697:31::-;3777:11;;;;3838:13;;3739:11;3830:22;;328:4;3876:24;;3872:42;;;-1:-1:-1;3909:5:5;;3621:321;-1:-1:-1;;;3621:321:5:o;3872:42::-;-1:-1:-1;3931:4:5;;3621:321;-1:-1:-1;;;3621:321:5:o;4534:270::-;4604:7;4624:14;4640:11;4655:21;4671:4;4655:15;:21::i;:::-;4743:22;;;4534:270;-1:-1:-1;;;;4534:270:5:o;7742:335:8:-;7845:8;;7825:4;;7857:1;7845:13;7841:56;;-1:-1:-1;7881:5:8;;7742:335;-1:-1:-1;7742:335:8:o;7841:56::-;-1:-1:-1;7940:11:8;;;7997:13;7906:7;7989:22;8042:4;8037:9;;7742:335::o;7396:424:5:-;7480:8;;7457:7;;7480:13;;7476:27;;-1:-1:-1;7502:1:5;;7396:424;-1:-1:-1;7396:424:5:o;7476:27::-;7514:13;7530:1;7514:17;;7541:15;7573:27;7588:4;:11;;;7573:14;:27::i;:::-;7559:4;:11;;;:41;;;;:::i;:::-;7541:59;;7610:14;7641:4;:8;;;7627:4;:11;;;:22;;;;:::i;:::-;7610:39;;7659:132;7676:6;7666:7;:16;7659:132;;;7718:20;7730:7;7718:11;:20::i;:::-;7708:30;;:7;:30;:::i;:::-;7698:40;-1:-1:-1;7773:7:5;;;;:::i;:::-;;;;7659:132;;;-1:-1:-1;7808:5:5;;7396:424;-1:-1:-1;;;7396:424:5:o;9184:581::-;9328:13;;9246:7;;9320:22;;239:4;9366:26;;9362:397;;;-1:-1:-1;9415:1:5;;9184:581;-1:-1:-1;;9184:581:5:o;9362:397::-;284:4;9437:25;;;:83;;-1:-1:-1;328:4:5;9467:25;;;;;:52;;-1:-1:-1;371:4:5;9496:23;;9467:52;9433:326;;;-1:-1:-1;9543:1:5;;9184:581;-1:-1:-1;;9184:581:5:o;9433:326::-;328:4;9565:24;;9561:198;;;9651:21;9671:1;284:4;9651:21;:::i;:::-;9642:31;;;;:5;:31;:::i;:::-;:35;;9676:1;9642:35;:::i;9561:198::-;9724:19;9742:1;371:4;9724:19;:::i;7869:1263::-;8035:13;;7928:7;;;;8027:22;;239:4;8073:26;;8069:1032;;;8125:1;8115:11;;8069:1032;;;284:4;8147:25;;8143:958;;;8198:26;239:4;8198:5;:26;:::i;:::-;:30;;8227:1;8198:30;:::i;:::-;8188:40;;8143:958;;;328:4;8249:24;;8245:856;;;8342:4;8335:5;8331:16;8421:1;8413:6;8409:14;8399:24;;8560:7;8556:2;8552:16;8547:3;8543:26;8534:6;8528:13;8524:46;8657:1;8648:7;8644:15;8635:7;8631:29;8620:40;;;;8245:856;;;371:4;8694:23;;8690:411;;;8743:24;328:4;8743:5;:24;:::i;8690:411::-;8855:4;8848:5;8844:16;8899:1;8891:6;8887:14;8877:24;;8970:7;8966:2;8962:16;8957:3;8953:26;8944:6;8938:13;8934:46;9074:1;9065:7;9061:15;9052:7;9048:29;9037:40;;;;8690:411;-1:-1:-1;9118:7:5;7869:1263;-1:-1:-1;;7869:1263:5: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:5;;-1:-1:-1;;;;2390:281:5:o;9923:768::-;10004:3;10011:1;10004:8;10000:21;;9923:768;;;:::o;10000:21::-;408:2;10085:16;;10078:194;;10175:10;;10162:24;;10214:16;408:2;10181:3;10214:16;:::i;:::-;;-1:-1:-1;10244:17:5;408:2;10244:17;;:::i;:::-;;-1:-1:-1;10103:16:5;408:2;10103:16;;:::i;:::-;;;10078:194;;;10286:7;;10282:403;;10393:12;10433:1;10414:15;10426:3;408:2;10414:15;:::i;:::-;10408:22;;:3;:22;:::i;:::-;:26;;;;:::i;:::-;10494:10;;10569:11;;10565:22;;10506:9;;10490:26;10639:21;10626:35;;-1:-1:-1;9923:768:5;;;:::o;14:332:13:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;180:9;167:23;230:66;223:5;219:78;212:5;209:89;199:117;;312:1;309;302:12;774:154;860:42;853:5;849:54;842:5;839:65;829:93;;918:1;915;908:12;933:247;992:6;1045:2;1033:9;1024:7;1020:23;1016:32;1013:52;;;1061:1;1058;1051:12;1013:52;1100:9;1087:23;1119:31;1144:5;1119:31;:::i;1185:179::-;1252:20;;1312:26;1301:38;;1291:49;;1281:77;;1354:1;1351;1344:12;1369:184;1421:77;1418:1;1411:88;1518:4;1515:1;1508:15;1542:4;1539:1;1532:15;1558:253;1630:2;1624:9;1672:4;1660:17;;1707:18;1692:34;;1728:22;;;1689:62;1686:88;;;1754:18;;:::i;:::-;1790:2;1783:22;1558:253;:::o;1816:251::-;1888:2;1882:9;;;1918:15;;1963:18;1948:34;;1984:22;;;1945:62;1942:88;;;2010:18;;:::i;2072:334::-;2143:2;2137:9;2199:2;2189:13;;2204:66;2185:86;2173:99;;2302:18;2287:34;;2323:22;;;2284:62;2281:88;;;2349:18;;:::i;:::-;2385:2;2378:22;2072:334;;-1:-1:-1;2072:334:13:o;2411:1454::-;2463:5;2516:3;2509:4;2501:6;2497:17;2493:27;2483:55;;2534:1;2531;2524:12;2483:55;2574:6;2561:20;2604:18;2596:6;2593:30;2590:56;;;2626:18;;:::i;:::-;2672:6;2669:1;2665:14;2699:30;2723:4;2719:2;2715:13;2699:30;:::i;:::-;2765:19;;;2809:4;2841:15;;;2837:26;;;2800:14;;;;2875:15;;;2872:35;;;2903:1;2900;2893:12;2872:35;2939:4;2931:6;2927:17;2916:28;;2953:881;2969:6;2964:3;2961:15;2953:881;;;3057:3;3044:17;3093:18;3080:11;3077:35;3074:55;;;3125:1;3122;3115:12;3074:55;3152:24;;3211:2;3203:11;;3199:21;-1:-1:-1;3189:49:13;;3234:1;3231;3224:12;3189:49;3288:4;3284:2;3280:13;3267:27;3323:18;3313:8;3310:32;3307:58;;;3345:18;;:::i;:::-;3393:120;3507:4;3438:66;3431:4;3421:8;3417:19;3413:92;3409:103;3393:120;:::i;:::-;3526:25;;;3570:39;3578:17;;;3570:39;3567:48;-1:-1:-1;3564:68:13;;;3628:1;3625;3618:12;3564:68;3691:8;3686:2;3682;3678:11;3671:4;3662:7;3658:18;3645:55;3755:1;3748:4;3737:8;3728:7;3724:22;3720:33;3713:44;3782:7;3777:3;3770:20;;;;3819:4;3814:3;3810:14;3803:21;;2995:4;2990:3;2986:14;2979:21;;2953:881;;;3852:7;2411:1454;-1:-1:-1;;;;;;2411:1454:13:o;3870:812::-;4023:6;4031;4039;4047;4100:3;4088:9;4079:7;4075:23;4071:33;4068:53;;;4117:1;4114;4107:12;4068:53;4156:9;4143:23;4175:31;4200:5;4175:31;:::i;:::-;4225:5;-1:-1:-1;4249:37:13;4282:2;4267:18;;4249:37;:::i;:::-;4239:47;;4337:2;4326:9;4322:18;4309:32;4364:18;4356:6;4353:30;4350:50;;;4396:1;4393;4386:12;4350:50;4419:59;4470:7;4461:6;4450:9;4446:22;4419:59;:::i;:::-;4409:69;;;4531:2;4520:9;4516:18;4503:32;4560:18;4550:8;4547:32;4544:52;;;4592:1;4589;4582:12;4544:52;4615:61;4668:7;4657:8;4646:9;4642:24;4615:61;:::i;:::-;4605:71;;;3870:812;;;;;;;:::o;5967:640::-;6083:6;6091;6144:2;6132:9;6123:7;6119:23;6115:32;6112:52;;;6160:1;6157;6150:12;6112:52;6200:9;6187:23;6233:18;6225:6;6222:30;6219:50;;;6265:1;6262;6255:12;6219:50;6288:22;;6341:4;6333:13;;6329:27;-1:-1:-1;6319:55:13;;6370:1;6367;6360:12;6319:55;6410:2;6397:16;6436:18;6428:6;6425:30;6422:50;;;6468:1;6465;6458:12;6422:50;6521:7;6516:2;6506:6;6503:1;6499:14;6495:2;6491:23;6487:32;6484:45;6481:65;;;6542:1;6539;6532:12;6481:65;6573:2;6565:11;;;;;6595:6;;-1:-1:-1;5967:640:13;-1:-1:-1;;;5967:640:13:o;6945:1866::-;7082:6;7090;7098;7151:2;7139:9;7130:7;7126:23;7122:32;7119:52;;;7167:1;7164;7157:12;7119:52;7206:9;7193:23;7225:31;7250:5;7225:31;:::i;:::-;7275:5;-1:-1:-1;7299:37:13;7332:2;7317:18;;7299:37;:::i;:::-;7289:47;;7387:2;7376:9;7372:18;7359:32;7414:18;7406:6;7403:30;7400:50;;;7446:1;7443;7436:12;7400:50;7469:22;;7525:4;7507:16;;;7503:27;7500:47;;;7543:1;7540;7533:12;7500:47;7571:22;;:::i;:::-;7631:2;7618:16;7659:18;7649:8;7646:32;7643:52;;;7691:1;7688;7681:12;7643:52;7720:54;7766:7;7755:8;7751:2;7747:17;7720:54;:::i;:::-;7711:7;7704:71;;7821:2;7817;7813:11;7800:25;7850:18;7840:8;7837:32;7834:52;;;7882:1;7879;7872:12;7834:52;7920:54;7966:7;7955:8;7951:2;7947:17;7920:54;:::i;:::-;7915:2;7906:7;7902:16;7895:80;;8021:2;8017;8013:11;8000:25;8050:18;8040:8;8037:32;8034:52;;;8082:1;8079;8072:12;8034:52;8120:54;8166:7;8155:8;8151:2;8147:17;8120:54;:::i;:::-;8115:2;8106:7;8102:16;8095:80;;8221:2;8217;8213:11;8200:25;8250:18;8240:8;8237:32;8234:52;;;8282:1;8279;8272:12;8234:52;8320:54;8366:7;8355:8;8351:2;8347:17;8320:54;:::i;:::-;8315:2;8306:7;8302:16;8295:80;;8421:3;8417:2;8413:12;8400:26;8451:18;8441:8;8438:32;8435:52;;;8483:1;8480;8473:12;8435:52;8522:54;8568:7;8557:8;8553:2;8549:17;8522:54;:::i;:::-;8516:3;8507:7;8503:17;8496:81;;8623:3;8619:2;8615:12;8602:26;8653:18;8643:8;8640:32;8637:52;;;8685:1;8682;8675:12;8637:52;8724:54;8770:7;8759:8;8755:2;8751:17;8724:54;:::i;:::-;8718:3;8709:7;8705:17;8698:81;;8798:7;8788:17;;;;6945:1866;;;;;:::o;9030:486::-;9127:6;9187:2;9175:9;9166:7;9162:23;9158:32;9202:2;9199:22;;;9217:1;9214;9207:12;9199:22;-1:-1:-1;9259:22:13;;:::i;:::-;9310:9;9304:16;9297:5;9290:31;9366:2;9355:9;9351:18;9345:25;9414:12;9405:7;9401:26;9392:7;9389:39;9379:67;;9442:1;9439;9432:12;9379:67;9473:2;9462:14;;9455:31;9466:5;9030:486;-1:-1:-1;;;9030:486:13:o;9805:184::-;9857:77;9854:1;9847:88;9954:4;9951:1;9944:15;9978:4;9975:1;9968:15;9994:529;10081:6;10141:2;10129:9;10120:7;10116:23;10112:32;10156:2;10153:22;;;10171:1;10168;10161:12;10153:22;-1:-1:-1;10213:22:13;;:::i;:::-;10272:9;10259:23;10291:33;10316:7;10291:33;:::i;:::-;10333:22;;10407:2;10392:18;;10379:32;10420:33;10379:32;10420:33;:::i;12130:184::-;12182:77;12179:1;12172:88;12279:4;12276:1;12269:15;12303:4;12300:1;12293:15;12319:125;12384:9;;;12405:10;;;12402:36;;;12418:18;;:::i;12449:128::-;12516:9;;;12537:11;;;12534:37;;;12551:18;;:::i;12582:168::-;12655:9;;;12686;;12703:15;;;12697:22;;12683:37;12673:71;;12724:18;;:::i;12755:184::-;12807:77;12804:1;12797:88;12904:4;12901:1;12894:15;12928:4;12925:1;12918:15;12944:112;12976:1;13002;12992:35;;13007:18;;:::i;:::-;-1:-1:-1;13041:9:13;;12944:112::o;13061:120::-;13101:1;13127;13117:35;;13132:18;;:::i;:::-;-1:-1:-1;13166:9:13;;13061:120::o;13186:184::-;13238:77;13235:1;13228:88;13335:4;13332:1;13325:15;13359:4;13356:1;13349:15;13375:195;13414:3;13445:66;13438:5;13435:77;13432:103;;13515:18;;:::i;:::-;-1:-1:-1;13562:1:13;13551:13;;13375:195::o;13575:151::-;13665:4;13658:12;;;13644;;;13640:31;;13683:14;;13680:40;;;13700:18;;:::i;13731:375::-;13819:1;13837:5;13851:249;13872:1;13862:8;13859:15;13851:249;;;13922:4;13917:3;13913:14;13907:4;13904:24;13901:50;;;13931:18;;:::i;:::-;13981:1;13971:8;13967:16;13964:49;;;13995:16;;;;13964:49;14078:1;14074:16;;;;;14034:15;;13851:249;;;13731:375;;;;;;:::o;14111:1022::-;14160:5;14190:8;14180:80;;-1:-1:-1;14231:1:13;14245:5;;14180:80;14279:4;14269:76;;-1:-1:-1;14316:1:13;14330:5;;14269:76;14361:4;14379:1;14374:59;;;;14447:1;14442:174;;;;14354:262;;14374:59;14404:1;14395:10;;14418:5;;;14442:174;14479:3;14469:8;14466:17;14463:43;;;14486:18;;:::i;:::-;-1:-1:-1;;14542:1:13;14528:16;;14601:5;;14354:262;;14700:2;14690:8;14687:16;14681:3;14675:4;14672:13;14668:36;14662:2;14652:8;14649:16;14644:2;14638:4;14635:12;14631:35;14628:77;14625:203;;;-1:-1:-1;14737:19:13;;;14813:5;;14625:203;14860:102;14895:66;14885:8;14879:4;14860:102;:::i;:::-;15058:6;14990:66;14986:79;14977:7;14974:92;14971:118;;;15069:18;;:::i;:::-;15107:20;;14111:1022;-1:-1:-1;;;14111:1022:13:o;15138:131::-;15198:5;15227:36;15254:8;15248:4;15227:36;:::i
Swarm Source
none
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in FRAX
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.