Source Code
EVM
Overview
ETH Balance
0 ETH
ETH Value
$0.00Latest 16 from a total of 16 transactions
| Transaction Hash |
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Execute Cross Ch... | 30374198 | 43 days ago | IN | 0 ETH | 0.00001888 | ||||
| Execute Batch Tr... | 17391474 | 157 days ago | IN | 0 ETH | 0.00026165 | ||||
| Execute Transact... | 10327748 | 242 days ago | IN | 0 ETH | 0.00002012 | ||||
| Execute Transact... | 10327652 | 242 days ago | IN | 0 ETH | 0.0000245 | ||||
| Execute Cross Ch... | 9200345 | 255 days ago | IN | 0 ETH | 0.00004558 | ||||
| Execute Cross Ch... | 9200041 | 255 days ago | IN | 0 ETH | 0.0000458 | ||||
| Execute Cross Ch... | 9053454 | 257 days ago | IN | 0 ETH | 0.00008442 | ||||
| Execute Cross Ch... | 9053443 | 257 days ago | IN | 0 ETH | 0.00002151 | ||||
| Execute Cross Ch... | 9053434 | 257 days ago | IN | 0 ETH | 0.00002162 | ||||
| Execute Cross Ch... | 9053426 | 257 days ago | IN | 0 ETH | 0.00003257 | ||||
| Execute Cross Ch... | 9053349 | 257 days ago | IN | 0 ETH | 0.00002768 | ||||
| Execute Cross Ch... | 9053323 | 257 days ago | IN | 0 ETH | 0.00002737 | ||||
| Execute Cross Ch... | 9053258 | 257 days ago | IN | 0 ETH | 0.00003879 | ||||
| Execute Cross Ch... | 9053250 | 257 days ago | IN | 0 ETH | 0.00011203 | ||||
| Execute Cross Ch... | 9053150 | 257 days ago | IN | 0 ETH | 0.00057617 | ||||
| Execute Cross Ch... | 9052784 | 257 days ago | IN | 0 ETH | 0.00000443 |
Latest 2 internal transactions
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 9052807 | 257 days ago | Contract Creation | 0 ETH | |||
| 9052807 | 257 days ago | Contract Creation | 0 ETH |
Cross-Chain Transactions
Loading...
Loading
Contract Name:
MultisigWallet
Compiler Version
v0.8.24+commit.e11b9ed9
Contract Source Code (Solidity Standard Json-Input format)
//SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import "./EIP712.sol";
import "./Constants.sol";
import "./DataTypes.sol";
import "./Errors.sol";
import "@limitbreak/tm-core-lib/src/utils/security/TstorishReentrancyGuard.sol";
/**
* @title MultisigWallet
* @author Limit Break, Inc.
* @notice The MultisigWallet contract is designed to allow authorized signers to
* execute transactions when the number of signatures meets or exceeds the
* wallet's threshold for execution.
*
* @dev A MultisigWallet's signer set has three components:
* - Signers - List of addresses that may sign a transaction or signer set replacement
* - Guardians - List of addresses, one of which *MUST* sign a signer set replacement
* - Threshold - The minimum number of signers required to execute a transaction
*
* @dev Signer set replacement is implemented through EIP-712 signatures that
* *DO NOT* use the `chainId` in the domain separator. This is to allow a
* signer set chain on one chain to be applied across all chains that the
* wallet is deployed to and for a "new chain" to "catch up" to the current
* signer set without having to re-sign the changes with the initial signers.
*/
contract MultisigWallet is EIP712, TstorishReentrancyGuard {
using EnumerableSet for EnumerableSet.AddressSet;
/// @dev Current signer set data
SignerSet private signerSet;
/// @dev Current wallet nonce, transactions must be signed with the current nonce to execute
uint256 public currentNonce;
/// @dev Mapping of cross chain nonce buckets to their current nonce
mapping (uint256 => uint256) public crossChainNonceBuckets;
/// @dev Mapping of selectors to return values for adding support of token protocols that use basic transfer checks on addresses with code
mapping (bytes4 => FallbackReturn) public fallbackReturns;
/// @dev Emitted when a batch transaction is executed
event BatchTransactionExecuted(bytes32 indexed batchTxHash, bytes[] results);
/// @dev Emitted when a fallback return is updated
event FallbackReturnUpdated(bytes4 indexed selector, bool enabled, bytes returnData);
/// @dev Emitted when the signer set is replaced
event SignerSetReplaced(uint32 newSignerSetId, uint32 newThreshold, address[] newSignerAddresses, address[] newGuardianAddresses);
/// @dev Emitted when a transaction is executed
event TransactionExecuted(bytes32 indexed txHash, bytes result);
/**
* @dev Construct the multisig wallet with the supplied list of initial signers and signature threshold.
*
* @dev Throws when the number of signers is less than the threshold.
* @dev Throws when the signers are not supplied in ascending order.
*
* @param threshold Number of signatures required to execute a transaction.
* @param signers List of initial signers.
* @param guardians List of initial guardians.
* @param fallbackReturnSelectors Array of function selectors to return a value for in the fallback.
* @param fallbackReturnData Array of data to return for each function signature in the fallback.
*/
constructor(
uint256 threshold,
address[] memory signers,
address[] memory guardians,
bytes4[] memory fallbackReturnSelectors,
bytes[] memory fallbackReturnData
) TstorishReentrancyGuard() EIP712("MultisigWallet", "1") {
_setSignerSet(signers, threshold);
_setGuardianSet(guardians);
uint256 fallbackReturnSelectorsLength = fallbackReturnSelectors.length;
if (fallbackReturnSelectorsLength != fallbackReturnData.length) {
revert MultisigWallet__InvalidArrayLengths();
}
for (uint256 i; i < fallbackReturnSelectorsLength; ++i) {
bytes4 fallbackReturnSelector = fallbackReturnSelectors[i];
bytes memory fallbackReturn = fallbackReturnData[i];
fallbackReturns[fallbackReturnSelector] = FallbackReturn({
enabled: true,
returnData: fallbackReturn
});
emit FallbackReturnUpdated(fallbackReturnSelector, true, fallbackReturn);
}
fallbackReturns[SELECTOR_ON_ERC1155_RECEIVED] = FallbackReturn({
enabled: true,
returnData: RETURN_DATA_ON_ERC1155_RECEIVED
});
emit FallbackReturnUpdated(SELECTOR_ON_ERC1155_RECEIVED, true, RETURN_DATA_ON_ERC1155_RECEIVED);
fallbackReturns[SELECTOR_ON_ERC1155_BATCH_RECEIVED] = FallbackReturn({
enabled: true,
returnData: RETURN_DATA_ON_ERC1155_BATCH_RECEIVED
});
emit FallbackReturnUpdated(SELECTOR_ON_ERC1155_BATCH_RECEIVED, true, RETURN_DATA_ON_ERC1155_BATCH_RECEIVED);
fallbackReturns[SELECTOR_ON_ERC721_RECEIVED] = FallbackReturn({
enabled: true,
returnData: RETURN_DATA_ON_ERC721_RECEIVED
});
emit FallbackReturnUpdated(SELECTOR_ON_ERC721_RECEIVED, true, RETURN_DATA_ON_ERC721_RECEIVED);
}
/**
* @notice Executes a transaction from the multisig wallet when properly signed.
*
* @dev Throws when there are not enough signatures supplied for the current threshold.
* @dev Throws when the recovered address for a signature is not in the current signer set.
* @dev Throws when signatures are supplied where the signer order is not ascending.
* @dev Throws when the call from the multisig to the `to` address reverts.
*
* @dev <h4>Postconditions:</h4>
* @dev 1. This contract's native token balance has increased by `msg.value`.
* @dev 2. `currentNonce` is incremented by one.
* @dev 3. This contract's native token balance is decreased by `value`.
* @dev 4. A call is made to `to` with a message value of `value` and calldata of `data`.
* @dev 5. A `TransactionExecuted` event has been emitted. The EIP712 transaction hash and call return data is logged in the event.
*
* @param to Address to call.
* @param value Value to send to the `to` address.
* @param data Calldata to send to the `to` address.
* @param signatures Array of signature values from the multisig signers.
*/
function executeTransaction(
address to,
uint256 value,
bytes calldata data,
SignatureECDSA[] calldata signatures
) external payable nonReentrant {
unchecked {
bytes32 txHash = _getTransactionHash(
currentNonce++,
to,
value,
data
);
_checkSignatures(txHash, signatures);
(bool success, bytes memory result) = to.call{value: value}(data);
if (success) {
emit TransactionExecuted(txHash, result);
} else {
revert MultisigWallet__CallReverted(result);
}
}
}
/**
* @notice Executes a batch of transactions from the multisig wallet when properly signed.
*
* @dev Throws when the batch array lengths are zero or do not match.
* @dev Throws when there are not enough signatures supplied for the current threshold.
* @dev Throws when the recovered address for a signature is not in the current signer set.
* @dev Throws when signatures are supplied where the signer order is not ascending.
* @dev Throws when the call from the multisig to the `to` address reverts.
*
* @dev <h4>Postconditions:</h4>
* @dev 1. This contract's native token balance has increased by `msg.value`.
* @dev 2. `currentNonce` is incremented by the number of transactions in the batch.
* @dev 3. This contract's native token balance is decreased by the sum of values in `transactions`.
* @dev 4. Calls are made to each address in `transactions` with the corresponding `data` and `value`.
* @dev 5. A `BatchTransactionExecuted` event has been emitted. The EIP712 transaction hash and call return data is logged in the event.
*
* @param transactions Array of transactions to execute.
* @param signatures Array of signature values from the multisig signers.
*/
function executeBatchTransaction(
BatchedTransaction[] calldata transactions,
SignatureECDSA[] calldata signatures
) external payable nonReentrant {
if (transactions.length == 0) {
revert MultisigWallet__InvalidArrayLengths();
}
unchecked {
uint256 cachedNonce = currentNonce;
bytes32[] memory txHashes = new bytes32[](transactions.length);
bytes[] memory txResults = new bytes[](transactions.length);
address to;
uint256 value;
bytes calldata data;
BatchedTransaction calldata transaction;
for (uint256 i; i < transactions.length; ++i) {
transaction = transactions[i];
to = transaction.to;
value = transaction.value;
data = transaction.data;
bytes32 txHash = _getTransactionHashForBatch(
cachedNonce++,
to,
value,
data
);
txHashes[i] = txHash;
(bool success, bytes memory result) = to.call{value: value}(data);
if (success) {
txResults[i] = result;
} else {
revert MultisigWallet__CallReverted(result);
}
}
currentNonce = cachedNonce;
bytes32 batchTxHash = _getBatchTransactionHashFromTxHashes(txHashes);
_checkSignatures(batchTxHash, signatures);
emit BatchTransactionExecuted(batchTxHash, txResults);
}
}
/**
* @notice Executes a transaction from the multisig wallet when properly signed.
*
* @dev Cross chain transactions are signed with a domain separator that does not include
* the chainId so that they may be replayed across all chains the multisig wallet is
* deployed to.
*
* @dev Throws when the cross chain nonce has already been consumed.
* @dev Throws when there are not enough signatures supplied for the current threshold.
* @dev Throws when the recovered address for a signature is not in the current signer set.
* @dev Throws when signatures are supplied where the signer order is not ascending.
* @dev Throws when a call from the multisig reverts.
*
* @dev <h4>Postconditions:</h4>
* @dev 1. This contract's native token balance has increased by `msg.value`.
* @dev 2. Each nonce in `transactions` is consumed in the `consumedCrossChainNonces` mapping.
* @dev 3. This contract's native token balance is decreased by the sum of values in `transactions`.
* @dev 4. Calls are made to each address in `transactions` with the corresponding `data` and `value`.
* @dev 5. A `TransactionExecuted` event has been emitted for each transaction.
* The EIP712 transaction hash and call return data is logged in the event.
*
* @param transactions Array of cross chain transactions to execute.
* @param signatures Array of signature values from the multisig signers.
*/
function executeCrossChainTransactions(
CrossChainTransaction[] calldata transactions,
SignatureECDSA[][] calldata signatures
) external payable nonReentrant {
if (transactions.length == 0 || transactions.length != signatures.length) {
revert MultisigWallet__InvalidArrayLengths();
}
unchecked {
CrossChainTransaction calldata transaction;
SignatureECDSA[] calldata txSignatures;
uint256 bucket;
address to;
uint256 value;
bytes calldata data;
for (uint256 i; i < transactions.length; ++i) {
transaction = transactions[i];
txSignatures = signatures[i];
bucket = transaction.bucket;
to = transaction.to;
value = transaction.value;
data = transaction.data;
if (to.code.length == 0) {
revert MultisigWallet__ToHasNoCode();
}
bytes32 txHash = _getCrossChainTransactionHash(
bucket,
crossChainNonceBuckets[bucket]++,
to,
value,
data
);
_checkSignatures(txHash, txSignatures);
(bool success, bytes memory result) = to.call{value: value}(data);
if (success) {
emit TransactionExecuted(txHash, result);
} else {
revert MultisigWallet__CallReverted(result);
}
}
}
}
/**
* @notice Updates the signer set with a new list of signers.
*
* @dev Throws when there are not enough signatures supplied for the current threshold.
* @dev Throws when the recovered address for a signature is not in the current signer set.
* @dev Throws when signatures are supplied where the signer order is not ascending.
* @dev Throws when the number of new signers is less than the new threshold.
* @dev Throws when the new signers are not supplied in ascending order.
* @dev Throws when the recovered address for the guardian signature is not in the current guardian set.
*
* @dev <h4>Postconditions:</h4>
* @dev 1. The new signers, guardians and threshold are stored.
* @dev 2. A `SignerSetReplaced` event has been emitted.
*
* @param threshold Number of signers required to execute a transaction.
* @param signers Array of signer addresses allowed to sign a transaction.
* @param guardians Array of guardian addresses allowed to sign the next signer set update.
* @param signatures Array of signature values from the multisig signers.
* @param guardianSignature Signature from a guardian authorizing this signer set change.
*/
function setSignerSet(
uint256 threshold,
address[] calldata signers,
address[] calldata guardians,
SignatureECDSA[] calldata signatures,
SignatureECDSA calldata guardianSignature
) external {
uint32 currentSignerSetId = signerSet.id;
bytes32 signerSetHash = _getSignerSetHash(currentSignerSetId, threshold, signers, guardians);
_checkSignatures(signerSetHash, signatures);
_checkGuardianSignature(signerSetHash, guardianSignature);
_setSignerSet(signers, threshold);
_setGuardianSet(guardians);
unchecked {
signerSet.id = ++currentSignerSetId;
}
emit SignerSetReplaced(currentSignerSetId, uint32(threshold), signers, guardians);
}
/**
* @notice Executes a batch of signer set updates.
*
* @dev Primary use case for this function is to bring a multisig wallet up to the current
* @dev signing set from a primary chain when the wallet is deployed on a new chain.
*
* @dev Throws when the batch array lengths are zero or do not match.
* @dev Throws when there are not enough signatures supplied for the current threshold.
* @dev Throws when the recovered address for a signature is not in the current signer set.
* @dev Throws when signatures are supplied where the signer order is not ascending.
* @dev Throws when the number of new signers is less than the new threshold.
* @dev Throws when the new signers are not supplied in ascending order.
* @dev Throws when the recovered address for the guardian signature is not in the current guardian set.
*
* @dev <h4>Postconditions:</h4>
* @dev 1. The new signers, guardians and threshold are stored.
* @dev 2. A `SignerSetReplaced` event has been emitted.
*
* @param batchThreshold Array of number of signers required to execute a transaction.
* @param batchSigners Array of signer addresses allowed to sign a transaction.
* @param batchGuardians Array of guardian addresses allowed to sign the next signer set update.
* @param batchSignatures Array of signature values from the multisig signers.
* @param batchGuardianSignature Array of signatures from a guardian authorizing this signer set change.
*/
function batchSetSignerSet(
uint256[] calldata batchThreshold,
address[][] calldata batchSigners,
address[][] calldata batchGuardians,
SignatureECDSA[][] calldata batchSignatures,
SignatureECDSA[] calldata batchGuardianSignature
) external {
if (
batchThreshold.length == 0 ||
batchThreshold.length != batchSigners.length ||
batchSigners.length != batchGuardians.length ||
batchGuardians.length != batchSignatures.length ||
batchSignatures.length != batchGuardianSignature.length
) {
revert MultisigWallet__InvalidArrayLengths();
}
unchecked {
uint32 currentSignerSetId = signerSet.id;
for (uint256 i; i < batchThreshold.length; ++i) {
bytes32 signerSetHash = _getSignerSetHash(currentSignerSetId, batchThreshold[i], batchSigners[i], batchGuardians[i]);
_checkSignatures(signerSetHash, batchSignatures[i]);
_checkGuardianSignature(signerSetHash, batchGuardianSignature[i]);
_setSignerSet(batchSigners[i], batchThreshold[i]);
_setGuardianSet(batchGuardians[i]);
++currentSignerSetId;
}
signerSet.id = currentSignerSetId;
uint256 lastIndex = batchThreshold.length - 1;
emit SignerSetReplaced(
currentSignerSetId,
uint32(batchThreshold[lastIndex]),
batchSigners[lastIndex],
batchGuardians[lastIndex]
);
}
}
/**
* @notice Sets a generic return value in bytes for a given function selector that is handled by the fallback.
*
* @dev This function must be called through `executeTransaction` or `executeBatchTransaction`.
*
* @param selector Function selector to supply return data for.
* @param enabled True if the fallback should handle the function, false otherwise.
* @param returnData Bytes of return data to return when the fallback handles a call for the selector.
*/
function setFallbackReturnData(bytes4 selector, bool enabled, bytes calldata returnData) external {
if (msg.sender != address(this)) {
revert MultisigWallet__CallerMustBeWallet();
}
fallbackReturns[selector] = FallbackReturn({
enabled: enabled,
returnData: returnData
});
emit FallbackReturnUpdated(selector, enabled, returnData);
}
/**
* @notice Computes the EIP712 hash value that must be signed for a transaction by the multisig signers to execute.
*
* @dev Uses a supplied nonce value so that transactions may be queued for signing and execution.
*
* @param nonce The value the nonce should be when the transaction is executed.
* @param to Address to call.
* @param value Value to send to the `to` address.
* @param data Calldata to send to the `to` address.
*
* @return hash The computed EIP712 hash to be signed.
*/
function getTransactionHash(
uint256 nonce,
address to,
uint256 value,
bytes calldata data
) external view returns (bytes32 hash) {
hash = _getTransactionHash(nonce, to, value, data);
}
/**
* @notice Computes the EIP712 hash value that must be signed for a transaction by the multisig signers to execute.
*
* @dev Uses the current nonce value for determining the transaction hash.
*
* @param to Address to call.
* @param value Value to send to the `to` address.
* @param data Calldata to send to the `to` address.
*
* @return hash The computed EIP712 hash to be signed.
*/
function getTransactionHashWithCurrentNonce(
address to,
uint256 value,
bytes calldata data
) external view returns (bytes32 hash) {
hash = _getTransactionHash(currentNonce, to, value, data);
}
/**
* @notice Computes the EIP712 hash value that must be signed for a transaction by the multisig signers to execute.
*
* @dev Uses a supplied nonce value so that transactions may be queued for signing and execution.
*
* @param nonce The value the nonce should be when the transaction is executed.
* @param transactions Array of transactions to execute.
*
* @return hash The computed EIP712 hash to be signed.
*/
function getBatchTransactionHash(
uint256 nonce,
BatchedTransaction[] calldata transactions
) external view returns (bytes32 hash) {
hash = _getBatchTransactionHash(nonce, transactions);
}
/**
* @notice Computes the EIP712 hash value that must be signed for a transaction by the multisig signers to execute.
*
* @dev Uses the current nonce value for determining the transaction hash.
*
* @param transactions Array of transactions to execute.
*
* @return hash The computed EIP712 hash to be signed.
*/
function getBatchTransactionHashWithCurrentNonce(
BatchedTransaction[] calldata transactions
) external view returns (bytes32 hash) {
hash = _getBatchTransactionHash(currentNonce, transactions);
}
/**
* @notice Computes the EIP712 hash value that must be signed for a cross chain transaction by the multisig signers to execute.
*
* @param nonce The value the nonce should be when the transaction is executed.
* @param transaction The cross chain transaction to get the EIP712 hash for.
*
* @return hash The computed EIP712 hash to be signed.
*/
function getCrossChainTransactionHash(
uint256 nonce,
CrossChainTransaction calldata transaction
) external view returns (bytes32 hash) {
hash = _getCrossChainTransactionHash(
transaction.bucket,
nonce,
transaction.to,
transaction.value,
transaction.data
);
}
/**
* @notice Computes the EIP712 hash value that must be signed for a cross chain transaction by the multisig signers to execute.
*
* @param transaction The cross chain transaction to get the EIP712 hash for.
*
* @return hash The computed EIP712 hash to be signed.
*/
function getCrossChainTransactionHashWithCurrentNonce(
CrossChainTransaction calldata transaction
) external view returns (bytes32 hash) {
hash = _getCrossChainTransactionHash(
transaction.bucket,
crossChainNonceBuckets[transaction.bucket],
transaction.to,
transaction.value,
transaction.data
);
}
/**
* @notice Computes the EIP712 hash value that must be signed to update the signer set.
*
* @param threshold Number of signers required to execute a transaction.
* @param signers Array of signer addresses allowed to sign a transaction.
* @param guardians Array of guardian addresses allowed to sign the next signer set update.
*
* @return hash The computed EIP712 hash to be signed.
*/
function getSignerSetHash(
uint256 threshold,
address[] calldata signers,
address[] calldata guardians
) external view returns (bytes32 hash) {
hash = _getSignerSetHash(signerSet.id, threshold, signers, guardians);
}
/**
* @notice Checks the signatures for a EIP712 hash to ensure signatures are valid to execute a transaction.
*
* @dev Throws when there are not enough signatures supplied for the current threshold.
* @dev Throws when the recovered address for a signature is not in the current signer set.
* @dev Throws when signatures are supplied where the signer order is not ascending.
*
* @param hash Hash value of the message that was signed by the signers.
* @param signatures Array of signature values from the multisig signers.
*
* @return True if signatures are valid for the current signer set and threshold, throws otherwise.
*/
function checkSignaturesForExecuteTransaction(
bytes32 hash,
SignatureECDSA[] calldata signatures
) external view returns (bool) {
_checkSignatures(hash, signatures);
return true;
}
/**
* @notice Checks the signatures for a EIP712 hash to ensure signatures are valid to update the signer set.
*
* @dev Throws when there are not enough signatures supplied for the current threshold.
* @dev Throws when the recovered address for a signature is not in the current signer set.
* @dev Throws when signatures are supplied where the signer order is not ascending.
* @dev Throws when the recovered guardian address for the guardian signature is not in the current guardian set.
*
* @param hash Hash value of the message that was signed by the signers.
* @param signatures Array of signature values from the multisig signers.
*
* @return True if signatures are valid for the current signer set, threshold and guardians, throws otherwise.
*/
function checkSignaturesForSetSignerSet(
bytes32 hash,
SignatureECDSA[] calldata signatures,
SignatureECDSA calldata guardianSignature
) external view returns (bool) {
_checkSignatures(hash, signatures);
_checkGuardianSignature(hash, guardianSignature);
return true;
}
/**
* @notice Returns the current signer set id.
*
* @return currentSignerSetId The id of the current signer set.
*/
function getCurrentSignerSetId() external view returns (uint32 currentSignerSetId) {
currentSignerSetId = signerSet.id;
}
/**
* @notice Returns the threshold for the current signer set.
*
* @return threshold The number of valid signatures required to execute a transaction.
*/
function getThreshold() external view returns (uint256 threshold) {
threshold = signerSet.threshold;
}
/**
* @notice Returns if an address is a valid signer in the current signer set.
*
* @return addressIsSigner True if the signer is in the current signer set, false otherwise.
*/
function isSigner(address signer) external view returns (bool addressIsSigner) {
addressIsSigner = signerSet.signers.contains(signer);
}
/**
* @notice Returns an address array of all addresses in the current signer set.
*
* @return signers Array of signers in the current signer set.
*/
function getSigners() external view returns (address[] memory signers) {
signers = signerSet.signers.values();
}
/**
* @notice Returns an address array of all addresses in the current guardian set.
*
* @return guardians Array of guardians in the current signer set.
*/
function getGuardians() external view returns (address[] memory guardians) {
guardians = signerSet.guardians.values();
}
/**
* @notice Returns the chain specific domain separator hash for signing transactions to execute.
*
* @return chainDomainSeparatorHash The hash of the chain specific domain separator.
*/
function chainDomainSeparator() external view returns (bytes32 chainDomainSeparatorHash) {
chainDomainSeparatorHash = _chainDomainSeparator();
}
/**
* @notice Returns the domain separator without chainId hash for signing transactions to update signer sets.
*
* @return chainlessDomainSeparatorHash The hash of the domain separator without chainId.
*/
function chainlessDomainSeparator() external view returns (bytes32 chainlessDomainSeparatorHash) {
chainlessDomainSeparatorHash = _chainlessDomainSeparator();
}
/**
* @dev Internal function to store a new set of signers and threshold. Called during contract construction
* @dev and when `setSignerSet` is executed by the current signers.
*
* @param signers Array of signer addresses allowed to sign a transaction.
* @param threshold Number of signers required to execute a transaction.
*/
function _setSignerSet(address[] memory signers, uint256 threshold) internal {
if (threshold == 0 || signers.length < threshold || threshold > type(uint32).max) {
revert MultisigWallet__InvalidSignerSet();
}
EnumerableSet.AddressSet storage signerSetSigners = signerSet.signers;
uint256 currentSignerSetLength = signerSetSigners.length();
if (currentSignerSetLength > 0) {
unchecked {
uint256 index = currentSignerSetLength - 1;
while (true) {
signerSetSigners.remove(signerSetSigners.at(index));
if (index == 0) break;
--index;
}
}
}
address previousSigner;
for (uint256 i; i < signers.length; i++) {
address signer = signers[i];
if (signer <= previousSigner) {
revert MultisigWallet__InvalidSignerSet();
}
signerSetSigners.add(signer);
previousSigner = signer;
}
signerSet.threshold = uint32(threshold);
}
/**
* @dev Internal function to store a new set of guardians. Called during contract construction
* @dev and when `setSignerSet` is executed by the current signers.
*
* @param guardians Array of guardian addresses allowed to authorize a signer set change.
*/
function _setGuardianSet(address[] memory guardians) internal {
if (guardians.length < MINIMUM_GUARDIANS) {
revert MultisigWallet__InvalidGuardianSet();
}
EnumerableSet.AddressSet storage signerSetGuardians = signerSet.guardians;
uint256 currentGuardianSetLength = signerSetGuardians.length();
if (currentGuardianSetLength > 0) {
unchecked {
uint256 index = currentGuardianSetLength - 1;
while (true) {
signerSetGuardians.remove(signerSetGuardians.at(index));
if (index == 0) break;
--index;
}
}
}
address previousGuardian;
for (uint256 i; i < guardians.length; i++) {
address guardian = guardians[i];
if (guardian <= previousGuardian) {
revert MultisigWallet__InvalidGuardianSet();
}
signerSetGuardians.add(guardian);
previousGuardian = guardian;
}
}
/**
* @dev Internal function to compute the EIP712 signature hash to be signed for a transaction.
*
* @param nonce The value the nonce should be when the transaction is executed.
* @param to Address to call.
* @param value Value to send to the `to` address.
* @param data Calldata to send to the `to` address.
*
* @return hash The computed EIP712 hash to be signed.
*/
function _getTransactionHash(
uint256 nonce,
address to,
uint256 value,
bytes calldata data
) internal view returns (bytes32 hash) {
hash = _hashChainTypedData(
keccak256(
abi.encode(
TRANSACTION_TYPEHASH,
nonce,
to,
value,
keccak256(data)
)
)
);
}
/**
* @dev Internal function to compute the EIP712 signature hash to be signed for a cross chain transaction.
*
* @param bucket The bucket the nonce is in.
* @param nonce The nonce value of the cross chain transaction.
* @param to Address to call.
* @param value Value to send to the `to` address.
* @param data Calldata to send to the `to` address.
*
* @return hash The computed EIP712 hash to be signed.
*/
function _getCrossChainTransactionHash(
uint256 bucket,
uint256 nonce,
address to,
uint256 value,
bytes calldata data
) internal view returns (bytes32 hash) {
hash = _hashChainlessTypedData(
keccak256(
abi.encode(
CROSS_CHAIN_TRANSACTION_TYPEHASH,
bucket,
nonce,
to,
value,
keccak256(data)
)
)
);
}
/**
* @dev Internal function to compute the hash of a transaction that is included in a batch.
*
* @param nonce The value the nonce should be when the transaction is executed.
* @param to Address to call.
* @param value Value to send to the `to` address.
* @param data Calldata to send to the `to` address.
*
* @return hash The computed EIP712 hash to be signed.
*/
function _getTransactionHashForBatch(
uint256 nonce,
address to,
uint256 value,
bytes calldata data
) internal pure returns (bytes32 hash) {
hash = keccak256(
abi.encode(
TRANSACTION_TYPEHASH,
nonce,
to,
value,
keccak256(data)
)
);
}
/**
* @dev Internal function to compute the EIP712 signature hash to be signed for a batch transaction.
*
* @param txHashes Array of transaction hashes for each transaction in the batch.
*
* @return hash The computed EIP712 hash to be signed.
*/
function _getBatchTransactionHashFromTxHashes(
bytes32[] memory txHashes
) internal view returns (bytes32 hash) {
hash = _hashChainTypedData(
keccak256(
abi.encode(
BATCH_TRANSACTION_TYPEHASH,
_getBytes32ArrayHashed(txHashes)
)
)
);
}
/**
* @dev Internal function to compute the EIP712 signature hash to be signed for a batch transaction.
*
* @param nonce The value the nonce should be when the transaction is executed.
* @param transactions Array of transactions to execute.
*
* @return hash The computed EIP712 hash to be signed.
*/
function _getBatchTransactionHash(
uint256 nonce,
BatchedTransaction[] calldata transactions
) internal view returns (bytes32 hash) {
unchecked {
uint256 cachedNonce = nonce;
bytes32[] memory txHashes = new bytes32[](transactions.length);
BatchedTransaction calldata transaction;
for (uint256 i; i < transactions.length; ++i) {
transaction = transactions[i];
bytes32 txHash = _getTransactionHashForBatch(
cachedNonce++,
transaction.to,
transaction.value,
transaction.data
);
txHashes[i] = txHash;
}
hash = _getBatchTransactionHashFromTxHashes(txHashes);
}
}
/**
* @dev Internal function to compute the EIP712 signature hash to be signed for a signer set update.
*
* @param signerSetId The current signer set id
* @param threshold Number of signers required to execute a transaction.
* @param signers Array of signer addresses allowed to sign a transaction.
* @param guardians Array of guardian addresses allowed to authorize a signer set change.
*
* @return hash The computed EIP712 hash to be signed.
*/
function _getSignerSetHash(
uint32 signerSetId,
uint256 threshold,
address[] calldata signers,
address[] calldata guardians
) internal view returns (bytes32 hash) {
hash = _hashChainlessTypedData(
keccak256(
abi.encode(
SIGNER_SET_TYPEHASH,
signerSetId,
threshold,
_getAddressBytesHashed(signers),
_getAddressBytesHashed(guardians)
)
)
);
}
/**
* @dev Internal function to hash an array of addresses for EIP712 signatures.
*
* @param addresses Array of addresses to hash.
*
* @return addressesHash Hash of the address values.
*/
function _getAddressBytesHashed(address[] calldata addresses) internal pure returns (bytes32 addressesHash) {
assembly ("memory-safe") {
let ptr := mload(0x40)
let len := mul(addresses.length, 0x20)
mstore(0x40, add(ptr, len))
calldatacopy(ptr, addresses.offset, add(addresses.offset, len))
addressesHash := keccak256(ptr, len)
}
}
/**
* @dev Internal function to hash an array of bytes32 values for EIP712 signatures.
*
* @param hashes Array of bytes32 hashes to hash.
*
* @return hashesHash Hash of the bytes32 values.
*/
function _getBytes32ArrayHashed(bytes32[] memory hashes) internal pure returns (bytes32 hashesHash) {
assembly ("memory-safe") {
let ptr := add(hashes, 0x20)
let len := mul(mload(hashes), 0x20)
hashesHash := keccak256(ptr, len)
}
}
/**
* @dev Internal function to check that the provided signatures are signed by the signers in
* @dev the signer set and meet the signer set threshold for executing a transaction.
*
* @dev Throws when the number of signatures is less than the signer set threshold.
* @dev Throws when a signatures v value is greater than type(uint8).max.
* @dev Throws when a signer is not in the signer set.
*
* @param hash Hash value of the message that was signed by the signers.
* @param signatures Array of signature values from the multisig signers.
*/
function _checkSignatures(bytes32 hash, SignatureECDSA[] calldata signatures) internal view {
uint256 requiredSignatures = signerSet.threshold;
if (requiredSignatures > signatures.length) {
revert MultisigWallet__NotEnoughSignatures();
}
EnumerableSet.AddressSet storage signers = signerSet.signers;
SignatureECDSA calldata signature;
address previousSigner;
for (uint256 i; i < requiredSignatures; ++i) {
signature = signatures[i];
if (signature.v > type(uint8).max) {
revert MultisigWallet__InvalidV();
}
address signer = ecrecover(hash, uint8(signature.v), signature.r, signature.s);
if (signer <= previousSigner || !signers.contains(signer)) {
revert MultisigWallet__InvalidSignatures();
}
previousSigner = signer;
}
}
/**
* @dev Internal function to check that the provided signature is signed by a guardian in
* @dev the current signer set.
*
* @dev Throws when the signature v value is greater than type(uint8).max.
* @dev Throws when the signer is not in the guardian set.
*
* @param hash Hash value of the message that was signed by the signers.
* @param signature Signature value from a guardian.
*/
function _checkGuardianSignature(bytes32 hash, SignatureECDSA calldata signature) internal view {
if (signature.v > type(uint8).max) {
revert MultisigWallet__InvalidV();
}
address signer = ecrecover(hash, uint8(signature.v), signature.r, signature.s);
if (!signerSet.guardians.contains(signer)) {
revert MultisigWallet__InvalidSignatures();
}
}
/// @dev Receive function allows native funds to be deposited
receive() external payable { }
/// @dev Fallback function allows native funds to be deposited with calldata
fallback() external payable {
if (msg.data.length > 3) {
FallbackReturn storage fallbackReturn = fallbackReturns[msg.sig];
if (fallbackReturn.enabled) {
bytes memory returnData = fallbackReturn.returnData;
assembly ("memory-safe") {
return(add(returnData, 0x20), mload(returnData))
}
}
}
if (msg.value == 0) {
revert MultisigWallet__FallbackNotHandled();
}
}
}//SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
/// @dev Constant variable for zero.
uint256 constant ZERO = 0;
/// @dev Constant variable for one.
uint256 constant ONE = 1;
/// @dev Requires a minimum number of guardians when creating a multisig wallet or updating the signer set.
uint8 constant MINIMUM_GUARDIANS = 2;
/// @dev EIP712 typehash for a transaction to execute by the wallet
bytes32 constant TRANSACTION_TYPEHASH = keccak256("Transaction(uint256 nonce,address to,uint256 value,bytes data)");
/// @dev EIP712 typehash for a batch transaction to execute by the wallet
bytes32 constant BATCH_TRANSACTION_TYPEHASH = keccak256("BatchTransaction(Transaction[] transactions)Transaction(uint256 nonce,address to,uint256 value,bytes data)");
/// @dev EIP712 typehash for a cross chain transaction to execute by the wallet
bytes32 constant CROSS_CHAIN_TRANSACTION_TYPEHASH = keccak256("CrossChainTransaction(uint256 bucket,uint256 nonce,address to,uint256 value,bytes data)");
/// @dev EIP712 typehash for updating to a new signer set
bytes32 constant SIGNER_SET_TYPEHASH = keccak256("SignerSet(uint32 currentSignerSetId,uint256 threshold,address[] signers,address[] guardians)");
/// @dev Function selector to handle onERC1155Received calls in fallback
bytes4 constant SELECTOR_ON_ERC1155_RECEIVED = 0xf23a6e61;
/// @dev Return value when handling onERC1155Received calls in fallback
bytes constant RETURN_DATA_ON_ERC1155_RECEIVED = hex"f23a6e6100000000000000000000000000000000000000000000000000000000";
/// @dev Function selector to handle onERC1155BatchReceived calls in fallback
bytes4 constant SELECTOR_ON_ERC1155_BATCH_RECEIVED = 0xbc197c81;
/// @dev Return value when handling onERC1155BatchReceived calls in fallback
bytes constant RETURN_DATA_ON_ERC1155_BATCH_RECEIVED = hex"bc197c8100000000000000000000000000000000000000000000000000000000";
/// @dev Function selector to handle onERC721Received calls in fallback
bytes4 constant SELECTOR_ON_ERC721_RECEIVED = 0x150b7a02;
/// @dev Return value when handling onERC721Received calls in fallback
bytes constant RETURN_DATA_ON_ERC721_RECEIVED = hex"150b7a0200000000000000000000000000000000000000000000000000000000";//SPDX-License-Identifier: MIT
pragma solidity 0.8.24;
import "@limitbreak/tm-core-lib/src/utils/structs/EnumerableSet.sol";
/// @dev Storage for a set of signers with threshold
struct SignerSet {
uint32 id;
uint32 threshold;
EnumerableSet.AddressSet signers;
EnumerableSet.AddressSet guardians;
}
/// @dev Struct for signer's signatures when executing transactions
struct SignatureECDSA {
uint256 v;
bytes32 r;
bytes32 s;
}
/// @dev Struct for batched transaction data
struct BatchedTransaction {
address to;
uint256 value;
bytes data;
}
/// @dev Struct for batched transaction data
struct CrossChainTransaction {
uint256 bucket;
address to;
uint256 value;
bytes data;
}
/// @dev Struct to store state and return value for fallback returns
struct FallbackReturn {
bool enabled;
bytes returnData;
}// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/cryptography/EIP712.sol)
pragma solidity 0.8.24;
/**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
*
* The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
* thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
* they need in their contracts using a combination of `abi.encode` and `keccak256`.
*
* This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
* scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
* ({_hashTypedDataV4}).
*
* The implementation of the domain separator was designed to be as efficient as possible while still properly updating
* the chain id to protect against replay attacks on an eventual fork of the chain.
*
* NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
* https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
*
* NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain
* separator of the implementation contract. This will cause the `_domainSeparatorV4` function to always rebuild the
* separator from the immutable values, which is cheaper than accessing a cached version in cold storage.
*
* _Available since v3.4._
*
* @custom:oz-upgrades-unsafe-allow state-variable-immutable state-variable-assignment
*/
abstract contract EIP712 {
bytes32 private constant _CHAIN_TYPE_HASH =
keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
bytes32 private constant _CHAINLESS_TYPE_HASH =
keccak256("EIP712Domain(string name,string version,address verifyingContract)");
// Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
// invalidate the cached domain separator if the chain id changes.
bytes32 private immutable _cachedChainDomainSeparator;
bytes32 private immutable _cachedChainlessDomainSeparator;
uint256 private immutable _cachedChainId;
bytes32 private immutable _hashedName;
bytes32 private immutable _hashedVersion;
/**
* @dev Initializes the domain separator and parameter caches.
*
* The meaning of `name` and `version` is specified in
* https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
*
* - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
* - `version`: the current major version of the signing domain.
*
* NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
* contract upgrade].
*/
constructor(string memory name, string memory version) {
_hashedName = keccak256(bytes(name));
_hashedVersion = keccak256(bytes(version));
_cachedChainId = block.chainid;
_cachedChainDomainSeparator = _buildChainDomainSeparator();
_cachedChainlessDomainSeparator = _buildChainlessDomainSeparator();
}
/**
* @dev Returns the domain separator for the current chain.
*/
function _chainDomainSeparator() internal view returns (bytes32 domainSeparator) {
if (block.chainid == _cachedChainId) {
domainSeparator = _cachedChainDomainSeparator;
} else {
domainSeparator = _buildChainDomainSeparator();
}
}
/**
* @dev Returns the domain separator for the current chain.
*/
function _chainlessDomainSeparator() internal view returns (bytes32 domainSeparator) {
domainSeparator = _cachedChainlessDomainSeparator;
}
function _buildChainDomainSeparator() private view returns (bytes32) {
return keccak256(abi.encode(_CHAIN_TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this)));
}
function _buildChainlessDomainSeparator() private view returns (bytes32) {
return keccak256(abi.encode(_CHAINLESS_TYPE_HASH, _hashedName, _hashedVersion, address(this)));
}
function _hashChainTypedData(bytes32 structHash) internal view virtual returns (bytes32 hash) {
hash = _toTypedDataHash(_chainDomainSeparator(), structHash);
}
function _hashChainlessTypedData(bytes32 structHash) internal view virtual returns (bytes32 hash) {
hash = _toTypedDataHash(_chainlessDomainSeparator(), structHash);
}
function _toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 data) {
assembly {
let ptr := mload(0x40)
mstore(ptr, "\x19\x01")
mstore(add(ptr, 0x02), domainSeparator)
mstore(add(ptr, 0x22), structHash)
data := keccak256(ptr, 0x42)
}
}
}//SPDX-License-Identifier: MIT pragma solidity 0.8.24; /// @dev Thrown when setting a fallback return data and the caller is not the wallet error MultisigWallet__CallerMustBeWallet(); /// @dev Thrown when executing a transaction and the call reverts error MultisigWallet__CallReverted(bytes result); /// @dev Thrown when a call with no value is not handled by the fallback function error MultisigWallet__FallbackNotHandled(); /// @dev Thrown when executing a batch transaction or signer set update and array lengths do not match or are zero length error MultisigWallet__InvalidArrayLengths(); /// @dev Thrown when validating signatures and a signer is not in the current signer set or signatures are not ordered by signer ascending error MultisigWallet__InvalidSignatures(); /// @dev Thrown when updating a signer set and the number of guardians is less than `MINIMUM_GUARDIANS` or guardians are not ordered by their address ascending error MultisigWallet__InvalidGuardianSet(); /// @dev Thrown when updating a signer set and the number of signers is less than threshold or signers are not ordered by signer ascending error MultisigWallet__InvalidSignerSet(); /// @dev Thrown when a signature V value exceeds type(uint8).max error MultisigWallet__InvalidV(); /// @dev Thrown when validating signatures and the number of signatures submitted is less than the threshold error MultisigWallet__NotEnoughSignatures(); /// @dev Thrown when execute a cross chain transaction and the to address does not have deployed code error MultisigWallet__ToHasNoCode();
pragma solidity ^0.8.24;
library StorageTstorish {
// keccak256(abi.encode(uint256(keccak256("storage.Tstorish")) - 1)) & ~bytes32(uint256(0xff))
bytes32 private constant DATA_STORAGE_SLOT =
0xdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b00;
struct Data {
// Indicates if TSTORE support has been activated during or post-deployment.
bool tstoreSupport;
}
function data() internal pure returns (Data storage ptr) {
bytes32 slot = DATA_STORAGE_SLOT;
assembly {
ptr.slot := slot
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import "./StorageTstorish.sol";
/**
* @title Tstorish
* @notice Based on https://github.com/ProjectOpenSea/tstorish/commit/a81ed74453ed7b9fe7e96a9906bc4def19b73e33
*/
abstract contract Tstorish {
/*
* ------------------------------------------------------------------------+
* Opcode | Mnemonic | Stack | Memory |
* ------------------------------------------------------------------------|
* 60 0x02 | PUSH1 0x02 | 0x02 | |
* 60 0x1e | PUSH1 0x1e | 0x1e 0x02 | |
* 61 0x3d5c | PUSH2 0x3d5c | 0x3d5c 0x1e 0x02 | |
* 3d | RETURNDATASIZE | 0 0x3d5c 0x1e 0x02 | |
* |
* :: store deployed bytecode in memory: (3d) RETURNDATASIZE (5c) TLOAD :: |
* 52 | MSTORE | 0x1e 0x02 | [0..0x20): 0x3d5c |
* f3 | RETURN | | [0..0x20): 0x3d5c |
* ------------------------------------------------------------------------+
*/
uint256 constant _TLOAD_TEST_PAYLOAD = 0x6002_601e_613d5c_3d_52_f3;
uint256 constant _TLOAD_TEST_PAYLOAD_LENGTH = 0x0a;
uint256 constant _TLOAD_TEST_PAYLOAD_OFFSET = 0x16;
// Declare an immutable variable to store the tstore test contract address.
address private immutable _tloadTestContract;
// Declare an immutable variable to store the initial TSTORE support status.
bool internal immutable _tstoreInitialSupport;
// Declare an immutable function type variable for the _setTstorish function
// based on chain support for tstore at time of deployment.
function(uint256,uint256) internal immutable _setTstorish;
// Declare an immutable function type variable for the _getTstorish function
// based on chain support for tstore at time of deployment.
function(uint256) view returns (uint256) internal immutable _getTstorish;
// Declare an immutable function type variable for the _clearTstorish function
// based on chain support for tstore at time of deployment.
function(uint256) internal immutable _clearTstorish;
// Declare a few custom revert error types.
error TStoreAlreadyActivated();
error TStoreNotSupported();
error TloadTestContractDeploymentFailed();
error OnlyDirectCalls();
/**
* @dev Determine TSTORE availability during deployment. This involves
* attempting to deploy a contract that utilizes TLOAD as part of the
* contract construction bytecode, and configuring initial support for
* using TSTORE in place of SSTORE based on the result.
*/
constructor() {
// Deploy the contract testing TLOAD support and store the address.
address tloadTestContract = _prepareTloadTest();
// Ensure the deployment was successful.
if (tloadTestContract == address(0)) {
revert TloadTestContractDeploymentFailed();
}
// Determine if TSTORE is supported.
_tstoreInitialSupport = StorageTstorish.data().tstoreSupport = _testTload(tloadTestContract);
if (_tstoreInitialSupport) {
// If TSTORE is supported, set functions to their versions that use
// tstore/tload directly without support checks.
_setTstorish = _setTstore;
_getTstorish = _getTstore;
_clearTstorish = _clearTstore;
} else {
// If TSTORE is not supported, set functions to their versions that
// fallback to sstore/sload until tstoreSupport is true.
_setTstorish = _setTstorishWithSstoreFallback;
_getTstorish = _getTstorishWithSloadFallback;
_clearTstorish = _clearTstorishWithSstoreFallback;
}
// Set the address of the deployed TLOAD test contract as an immutable.
_tloadTestContract = tloadTestContract;
}
/**
* @dev Called internally when tstore is activated by an external call to
* `__activateTstore`. Developers must override this function and handle
* relevant transfers of data from regular storage to transient storage *OR*
* revert the transaction if it is in a state that should not support the activation
* of tstore.
*/
function _onTstoreSupportActivated() internal virtual;
/**
* @dev External function to activate TSTORE usage. Does not need to be
* called if TSTORE is supported from deployment, and only needs to be
* called once. Reverts if TSTORE has already been activated or if the
* opcode is not available. Note that this must be called directly from
* an externally-owned account to avoid potential reentrancy issues.
*/
function __activateTstore() external {
// Determine if TSTORE can potentially be activated.
if (_tstoreInitialSupport || StorageTstorish.data().tstoreSupport) {
revert TStoreAlreadyActivated();
}
// Determine if TSTORE can be activated and revert if not.
if (!_testTload(_tloadTestContract)) {
revert TStoreNotSupported();
}
// Mark TSTORE as activated.
StorageTstorish.data().tstoreSupport = true;
_onTstoreSupportActivated();
}
/**
* @dev Private function to set a TSTORISH value. Assigned to _setTstorish
* internal function variable at construction if chain has tstore support.
*
* @param storageSlot The slot to write the TSTORISH value to.
* @param value The value to write to the given storage slot.
*/
function _setTstore(uint256 storageSlot, uint256 value) internal {
assembly {
tstore(storageSlot, value)
}
}
/**
* @dev Private function to set a TSTORISH value with sstore fallback.
* Assigned to _setTstorish internal function variable at construction
* if chain does not have tstore support.
*
* @param storageSlot The slot to write the TSTORISH value to.
* @param value The value to write to the given storage slot.
*/
function _setTstorishWithSstoreFallback(uint256 storageSlot, uint256 value) internal {
if (StorageTstorish.data().tstoreSupport) {
assembly {
tstore(storageSlot, value)
}
} else {
assembly {
sstore(storageSlot, value)
}
}
}
/**
* @dev Private function to read a TSTORISH value. Assigned to _getTstorish
* internal function variable at construction if chain has tstore support.
*
* @param storageSlot The slot to read the TSTORISH value from.
*
* @return value The TSTORISH value at the given storage slot.
*/
function _getTstore(
uint256 storageSlot
) internal view returns (uint256 value) {
assembly {
value := tload(storageSlot)
}
}
/**
* @dev Private function to read a TSTORISH value with sload fallback.
* Assigned to _getTstorish internal function variable at construction
* if chain does not have tstore support.
*
* @param storageSlot The slot to read the TSTORISH value from.
*
* @return value The TSTORISH value at the given storage slot.
*/
function _getTstorishWithSloadFallback(
uint256 storageSlot
) internal view returns (uint256 value) {
if (StorageTstorish.data().tstoreSupport) {
assembly {
value := tload(storageSlot)
}
} else {
assembly {
value := sload(storageSlot)
}
}
}
/**
* @dev Private function to clear a TSTORISH value. Assigned to _clearTstorish internal
* function variable at construction if chain has tstore support.
*
* @param storageSlot The slot to clear the TSTORISH value for.
*/
function _clearTstore(uint256 storageSlot) internal {
assembly {
tstore(storageSlot, 0)
}
}
/**
* @dev Private function to clear a TSTORISH value with sstore fallback.
* Assigned to _clearTstorish internal function variable at construction
* if chain does not have tstore support.
*
* @param storageSlot The slot to clear the TSTORISH value for.
*/
function _clearTstorishWithSstoreFallback(uint256 storageSlot) internal {
if (StorageTstorish.data().tstoreSupport) {
assembly {
tstore(storageSlot, 0)
}
} else {
assembly {
sstore(storageSlot, 0)
}
}
}
/**
* @dev Private function to copy a value from storage to transient storage at the same slot.
* Useful when tstore is activated on a chain that didn't initially support it.
*/
function _copyFromStorageToTransient(uint256 storageSlot) internal {
if (StorageTstorish.data().tstoreSupport) {
assembly {
tstore(storageSlot, sload(storageSlot))
}
} else {
revert TStoreNotSupported();
}
}
/**
* @dev Private function to deploy a test contract that utilizes TLOAD as
* part of its fallback logic.
*/
function _prepareTloadTest() private returns (address contractAddress) {
// Utilize assembly to deploy a contract testing TLOAD support.
assembly {
// Write the contract deployment code payload to scratch space.
mstore(0, _TLOAD_TEST_PAYLOAD)
// Deploy the contract.
contractAddress := create(
0,
_TLOAD_TEST_PAYLOAD_OFFSET,
_TLOAD_TEST_PAYLOAD_LENGTH
)
}
}
/**
* @dev Private view function to determine if TSTORE/TLOAD are supported by
* the current EVM implementation by attempting to call the test
* contract, which utilizes TLOAD as part of its fallback logic.
*/
function _testTload(
address tloadTestContract
) private view returns (bool ok) {
// Call the test contract, which will perform a TLOAD test. If the call
// does not revert, then TLOAD/TSTORE is supported. Do not forward all
// available gas, as all forwarded gas will be consumed on revert.
(ok, ) = tloadTestContract.staticcall{ gas: gasleft() / 10 }("");
}
}pragma solidity ^0.8.24;
import "../misc/Tstorish.sol";
/**
* @dev Variant of {ReentrancyGuard} that uses transient storage.
*
* NOTE: This variant only works on networks where EIP-1153 is available.
*/
abstract contract TstorishReentrancyGuard is Tstorish {
// keccak256(abi.encode(uint256(keccak256("storage.TstorishReentrancyGuard")) - 1)) & ~bytes32(uint256(0xff))
uint256 private constant REENTRANCY_GUARD_STORAGE =
0xeff9701f8ef712cda0f707f0a4f48720f142bf7e1bce9d4747c32b4eeb890500;
uint256 private constant NOT_ENTERED = 1;
uint256 private constant ENTERED = 2;
/**
* @dev Unauthorized reentrant call.
*/
error ReentrancyGuardReentrantCall();
constructor() Tstorish() {
if (!_tstoreInitialSupport) {
_setTstorish(REENTRANCY_GUARD_STORAGE, NOT_ENTERED);
}
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be NOT_ENTERED
if (_getTstorish(REENTRANCY_GUARD_STORAGE) == ENTERED) {
revert ReentrancyGuardReentrantCall();
}
// Any calls to nonReentrant after this point will fail
_setTstorish(REENTRANCY_GUARD_STORAGE, ENTERED);
}
function _nonReentrantAfter() private {
_setTstorish(REENTRANCY_GUARD_STORAGE, NOT_ENTERED);
}
function _onTstoreSupportActivated() internal virtual override {
_copyFromStorageToTransient(REENTRANCY_GUARD_STORAGE);
}
}pragma solidity ^0.8.4;
/**
* @dev Library for managing
* https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
* types.
*
* Sets have the following properties:
*
* - Elements are added, removed, and checked for existence in constant time
* (O(1)).
* - Elements are enumerated in O(n). No guarantees are made on the ordering.
*
* ```solidity
* contract Example {
* // Add the library methods
* using EnumerableSet for EnumerableSet.AddressSet;
*
* // Declare a set state variable
* EnumerableSet.AddressSet private mySet;
* }
* ```
*
* As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
* and `uint256` (`UintSet`) are supported.
*
* [WARNING]
* ====
* Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
* unusable.
* See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
*
* In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
* array of EnumerableSet.
* ====
*/
library EnumerableSet {
// To implement this library for multiple types with as little code
// repetition as possible, we write it in terms of a generic Set type with
// bytes32 values.
// The Set implementation uses private functions, and user-facing
// implementations (such as AddressSet) are just wrappers around the
// underlying Set.
// This means that we can only create new EnumerableSets for types that fit
// in bytes32.
struct Set {
// Storage of set values
bytes32[] _values;
// Position is the index of the value in the `values` array plus 1.
// Position 0 is used to mean a value is not in the set.
mapping(bytes32 value => uint256) _positions;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function _add(Set storage set, bytes32 value) private returns (bool) {
if (!_contains(set, value)) {
set._values.push(value);
// The value is stored at length-1, but we add 1 to all indexes
// and use 0 as a sentinel value
set._positions[value] = set._values.length;
return true;
} else {
return false;
}
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function _remove(Set storage set, bytes32 value) private returns (bool) {
// We cache the value's position to prevent multiple reads from the same storage slot
uint256 position = set._positions[value];
if (position != 0) {
// Equivalent to contains(set, value)
// To delete an element from the _values array in O(1), we swap the element to delete with the last one in
// the array, and then remove the last element (sometimes called as 'swap and pop').
// This modifies the order of the array, as noted in {at}.
uint256 valueIndex = position - 1;
uint256 lastIndex = set._values.length - 1;
if (valueIndex != lastIndex) {
bytes32 lastValue = set._values[lastIndex];
// Move the lastValue to the index where the value to delete is
set._values[valueIndex] = lastValue;
// Update the tracked position of the lastValue (that was just moved)
set._positions[lastValue] = position;
}
// Delete the slot where the moved value was stored
set._values.pop();
// Delete the tracked position for the deleted slot
delete set._positions[value];
return true;
} else {
return false;
}
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function _contains(Set storage set, bytes32 value) private view returns (bool) {
return set._positions[value] != 0;
}
/**
* @dev Returns the number of values on the set. O(1).
*/
function _length(Set storage set) private view returns (uint256) {
return set._values.length;
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function _at(Set storage set, uint256 index) private view returns (bytes32) {
return set._values[index];
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function _values(Set storage set) private view returns (bytes32[] memory) {
return set._values;
}
// Bytes32Set
struct Bytes32Set {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _add(set._inner, value);
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
return _remove(set._inner, value);
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
return _contains(set._inner, value);
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(Bytes32Set storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
return _at(set._inner, index);
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
bytes32[] memory store = _values(set._inner);
bytes32[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// AddressSet
struct AddressSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(AddressSet storage set, address value) internal returns (bool) {
return _add(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(AddressSet storage set, address value) internal returns (bool) {
return _remove(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(AddressSet storage set, address value) internal view returns (bool) {
return _contains(set._inner, bytes32(uint256(uint160(value))));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(AddressSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(AddressSet storage set, uint256 index) internal view returns (address) {
return address(uint160(uint256(_at(set._inner, index))));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(AddressSet storage set) internal view returns (address[] memory) {
bytes32[] memory store = _values(set._inner);
address[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
// UintSet
struct UintSet {
Set _inner;
}
/**
* @dev Add a value to a set. O(1).
*
* Returns true if the value was added to the set, that is if it was not
* already present.
*/
function add(UintSet storage set, uint256 value) internal returns (bool) {
return _add(set._inner, bytes32(value));
}
/**
* @dev Removes a value from a set. O(1).
*
* Returns true if the value was removed from the set, that is if it was
* present.
*/
function remove(UintSet storage set, uint256 value) internal returns (bool) {
return _remove(set._inner, bytes32(value));
}
/**
* @dev Returns true if the value is in the set. O(1).
*/
function contains(UintSet storage set, uint256 value) internal view returns (bool) {
return _contains(set._inner, bytes32(value));
}
/**
* @dev Returns the number of values in the set. O(1).
*/
function length(UintSet storage set) internal view returns (uint256) {
return _length(set._inner);
}
/**
* @dev Returns the value stored at position `index` in the set. O(1).
*
* Note that there are no guarantees on the ordering of values inside the
* array, and it may change when more values are added or removed.
*
* Requirements:
*
* - `index` must be strictly less than {length}.
*/
function at(UintSet storage set, uint256 index) internal view returns (uint256) {
return uint256(_at(set._inner, index));
}
/**
* @dev Return the entire set in an array
*
* WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
* to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
* this function has an unbounded cost, and using it as part of a state-changing function may render the function
* uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
*/
function values(UintSet storage set) internal view returns (uint256[] memory) {
bytes32[] memory store = _values(set._inner);
uint256[] memory result;
/// @solidity memory-safe-assembly
assembly {
result := store
}
return result;
}
}{
"remappings": [
"ds-test/=lib/forge-std/lib/ds-test/src/",
"forge-std/=lib/forge-std/src/",
"@limitbreak/creator-token-transfer-validator/=lib/creator-token-transfer-validator/",
"@limitbreak/tm-cloner/=lib/tm-cloner/",
"@limitbreak/tm-core-lib/=lib/tm-core-lib/",
"@limitbreak/tm-extension-registry/=lib/tm-extension-registry/",
"@limitbreak/tm-role-server/=lib/tm-role-server/",
"@limitbreak/tm-template-factory/=lib/tm-template-factory/",
"@limitbreak/tm-web2-gateway/=lib/tm-web2-gateway/",
"@limitbreak/wrapped-native/=lib/wrapped-native/",
"@limitbreak/permit-c/=lib/payment-processor-v2/lib/PermitC/src/",
"@limitbreak/trusted-forwarder/=lib/payment-processor-v2/lib/TrustedForwarder/src/",
"@opensea/tstorish/=lib/creator-token-standards/lib/tstorish/src/",
"@openzeppelin/=lib/payment-processor-v2/lib/openzeppelin-contracts/",
"@rari-capital/solmate/=lib/payment-processor-v2/lib/solmate/",
"ERC721A/=lib/creator-token-standards/lib/ERC721A/contracts/",
"PermitC/=lib/payment-processor-v2/lib/PermitC/",
"TrustedForwarder/=lib/TrustedForwarder/",
"creator-token-standards/=lib/creator-token-standards/",
"creator-token-transfer-validator/=lib/creator-token-transfer-validator/src/",
"erc4626-tests/=lib/payment-processor-v2/lib/openzeppelin-contracts/lib/erc4626-tests/",
"erc721a/=lib/creator-token-standards/lib/ERC721A/",
"fake-contracts/=lib/fake-contracts/src/",
"forge-gas-metering/=lib/payment-processor-v2/lib/PermitC/lib/forge-gas-metering/",
"multisig/=lib/multisig/",
"murky/=lib/payment-processor-v2/lib/murky/",
"openzeppelin-contracts/=lib/payment-processor-v2/lib/openzeppelin-contracts/",
"openzeppelin/=lib/payment-processor-v2/lib/openzeppelin-contracts/contracts/",
"payment-processor-v2/=lib/payment-processor-v2/",
"solady/=lib/payment-processor-v2/lib/PermitC/lib/forge-gas-metering/lib/solady/",
"solmate/=lib/payment-processor-v2/lib/solmate/src/",
"tm-cloner/=lib/tm-cloner/src/",
"tm-core-lib/=lib/tm-core-lib/src/",
"tm-extension-registry/=lib/tm-extension-registry/src/",
"tm-role-server/=lib/tm-role-server/src/",
"tm-template-factory/=lib/tm-template-factory/src/",
"tm-web2-gateway/=lib/tm-web2-gateway/src/",
"tstorish/=lib/creator-token-standards/lib/tstorish/src/",
"wrapped-native/=lib/wrapped-native/"
],
"optimizer": {
"enabled": true,
"runs": 9999999
},
"metadata": {
"useLiteralContent": false,
"bytecodeHash": "ipfs",
"appendCBOR": true
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"abi"
]
}
},
"evmVersion": "cancun",
"viaIR": false
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"guardians","type":"address[]"},{"internalType":"bytes4[]","name":"fallbackReturnSelectors","type":"bytes4[]"},{"internalType":"bytes[]","name":"fallbackReturnData","type":"bytes[]"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"bytes","name":"result","type":"bytes"}],"name":"MultisigWallet__CallReverted","type":"error"},{"inputs":[],"name":"MultisigWallet__CallerMustBeWallet","type":"error"},{"inputs":[],"name":"MultisigWallet__FallbackNotHandled","type":"error"},{"inputs":[],"name":"MultisigWallet__InvalidArrayLengths","type":"error"},{"inputs":[],"name":"MultisigWallet__InvalidGuardianSet","type":"error"},{"inputs":[],"name":"MultisigWallet__InvalidSignatures","type":"error"},{"inputs":[],"name":"MultisigWallet__InvalidSignerSet","type":"error"},{"inputs":[],"name":"MultisigWallet__InvalidV","type":"error"},{"inputs":[],"name":"MultisigWallet__NotEnoughSignatures","type":"error"},{"inputs":[],"name":"MultisigWallet__ToHasNoCode","type":"error"},{"inputs":[],"name":"OnlyDirectCalls","type":"error"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","type":"error"},{"inputs":[],"name":"TStoreAlreadyActivated","type":"error"},{"inputs":[],"name":"TStoreNotSupported","type":"error"},{"inputs":[],"name":"TloadTestContractDeploymentFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"batchTxHash","type":"bytes32"},{"indexed":false,"internalType":"bytes[]","name":"results","type":"bytes[]"}],"name":"BatchTransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes4","name":"selector","type":"bytes4"},{"indexed":false,"internalType":"bool","name":"enabled","type":"bool"},{"indexed":false,"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"FallbackReturnUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"newSignerSetId","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"newThreshold","type":"uint32"},{"indexed":false,"internalType":"address[]","name":"newSignerAddresses","type":"address[]"},{"indexed":false,"internalType":"address[]","name":"newGuardianAddresses","type":"address[]"}],"name":"SignerSetReplaced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"txHash","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"result","type":"bytes"}],"name":"TransactionExecuted","type":"event"},{"stateMutability":"payable","type":"fallback"},{"inputs":[],"name":"__activateTstore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"batchThreshold","type":"uint256[]"},{"internalType":"address[][]","name":"batchSigners","type":"address[][]"},{"internalType":"address[][]","name":"batchGuardians","type":"address[][]"},{"components":[{"internalType":"uint256","name":"v","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureECDSA[][]","name":"batchSignatures","type":"tuple[][]"},{"components":[{"internalType":"uint256","name":"v","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureECDSA[]","name":"batchGuardianSignature","type":"tuple[]"}],"name":"batchSetSignerSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"chainDomainSeparator","outputs":[{"internalType":"bytes32","name":"chainDomainSeparatorHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"chainlessDomainSeparator","outputs":[{"internalType":"bytes32","name":"chainlessDomainSeparatorHash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"components":[{"internalType":"uint256","name":"v","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureECDSA[]","name":"signatures","type":"tuple[]"}],"name":"checkSignaturesForExecuteTransaction","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"},{"components":[{"internalType":"uint256","name":"v","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureECDSA[]","name":"signatures","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"v","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureECDSA","name":"guardianSignature","type":"tuple"}],"name":"checkSignaturesForSetSignerSet","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"crossChainNonceBuckets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentNonce","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct BatchedTransaction[]","name":"transactions","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"v","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureECDSA[]","name":"signatures","type":"tuple[]"}],"name":"executeBatchTransaction","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"bucket","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct CrossChainTransaction[]","name":"transactions","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"v","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureECDSA[][]","name":"signatures","type":"tuple[][]"}],"name":"executeCrossChainTransactions","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"},{"components":[{"internalType":"uint256","name":"v","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureECDSA[]","name":"signatures","type":"tuple[]"}],"name":"executeTransaction","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"name":"fallbackReturns","outputs":[{"internalType":"bool","name":"enabled","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct BatchedTransaction[]","name":"transactions","type":"tuple[]"}],"name":"getBatchTransactionHash","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct BatchedTransaction[]","name":"transactions","type":"tuple[]"}],"name":"getBatchTransactionHashWithCurrentNonce","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"components":[{"internalType":"uint256","name":"bucket","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct CrossChainTransaction","name":"transaction","type":"tuple"}],"name":"getCrossChainTransactionHash","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"bucket","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"internalType":"struct CrossChainTransaction","name":"transaction","type":"tuple"}],"name":"getCrossChainTransactionHashWithCurrentNonce","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentSignerSetId","outputs":[{"internalType":"uint32","name":"currentSignerSetId","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getGuardians","outputs":[{"internalType":"address[]","name":"guardians","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"guardians","type":"address[]"}],"name":"getSignerSetHash","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSigners","outputs":[{"internalType":"address[]","name":"signers","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getThreshold","outputs":[{"internalType":"uint256","name":"threshold","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getTransactionHash","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"getTransactionHashWithCurrentNonce","outputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"signer","type":"address"}],"name":"isSigner","outputs":[{"internalType":"bool","name":"addressIsSigner","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"selector","type":"bytes4"},{"internalType":"bool","name":"enabled","type":"bool"},{"internalType":"bytes","name":"returnData","type":"bytes"}],"name":"setFallbackReturnData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"threshold","type":"uint256"},{"internalType":"address[]","name":"signers","type":"address[]"},{"internalType":"address[]","name":"guardians","type":"address[]"},{"components":[{"internalType":"uint256","name":"v","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureECDSA[]","name":"signatures","type":"tuple[]"},{"components":[{"internalType":"uint256","name":"v","type":"uint256"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"internalType":"struct SignatureECDSA","name":"guardianSignature","type":"tuple"}],"name":"setSignerSet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
6101c060405234801562000011575f80fd5b506040516200435438038062004354833981016040819052620000349162000d25565b604080518082018252600e81526d135d5b1d1a5cda59d5d85b1b195d60921b6020808301918252835180850190945260018452603160f81b908401908152825190912060e05282519020610100524660c0529062000091620005ab565b6080526200009e62000615565b60a052505f9050620000af62000663565b90506001600160a01b038116620000d957604051632aea588760e01b815260040160405180910390fd5b620000e4816200067c565b5f8051602062004314833981519152805460ff191691158015928317909155610140919091526200015457620006de602090811b62001480176001600160401b0390811661016052620006e5821b6200148717811661018052620006e990911b6200148b17166101a05262000194565b620006ef602090811b62001491176001600160401b039081166101605262000713821b620014c6178116610180526200073790911b620014ff17166101a0525b6001600160a01b03166101205261014051620001da57620001da7feff9701f8ef712cda0f707f0a4f48720f142bf7e1bce9d4747c32b4eeb89050060016101605160201c565b620001e684866200075b565b620001f18362000882565b815181518114620002155760405163e574a93160e01b815260040160405180910390fd5b5f5b81811015620002f8575f84828151811062000236576200023662000e53565b602002602001015190505f84838151811062000256576200025662000e53565b60209081029190910181015160408051808201825260018082528185018481526001600160e01b031988165f9081526007909652929094208151815460ff1916901515178155915192945092909190820190620002b4908262000eee565b50905050816001600160e01b0319165f8051602062004334833981519152600183604051620002e592919062000fba565b60405180910390a2505060010162000217565b50604080518082018252600181528151808301909252602080835263f23a6e6160e01b8184018190528183019384525f526007905280517f4aadaddd00dfee5402f506fd1b65f159277cf485f067f82f22e5b25d7192c617805460ff191691151591909117815591519091907f4aadaddd00dfee5402f506fd1b65f159277cf485f067f82f22e5b25d7192c6189062000392908262000eee565b5050604080518082018252602080825263f23a6e6160e01b90820181905291519192505f805160206200433483398151915291620003d39160019162000fba565b60405180910390a2604080518082018252600181528151808301909252602080835263bc197c8160e01b8184018190528183019384525f526007905280517f07ae7d8c51662391b0fc8fce43b9e49b606d4d6b4945dbe5b5a8ca5d2c2e9cd8805460ff191691151591909117815591519091907f07ae7d8c51662391b0fc8fce43b9e49b606d4d6b4945dbe5b5a8ca5d2c2e9cd99062000474908262000eee565b5050604080518082018252602080825263bc197c8160e01b90820181905291519192505f805160206200433483398151915291620004b59160019162000fba565b60405180910390a26040805180820182526001815281518083019092526020808352630a85bd0160e11b8184018190528183019384525f526007905280517f22be377b75abc9ec2a65d6ab63724336435d0146f0a717cb0ce87ca505045e79805460ff191691151591909117815591519091907f22be377b75abc9ec2a65d6ab63724336435d0146f0a717cb0ce87ca505045e7a9062000556908262000eee565b50506040805180820182526020808252630a85bd0160e11b90820181905291519192505f805160206200433483398151915291620005979160019162000fba565b60405180910390a25050505050506200104b565b60e05161010051604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201529081019290925260608201524660808201523060a08201525f9060c0015b60405160208183030381529060405280519060200120905090565b60e05161010051604080517f91ab3d17e3a50a9d89e63fd30b92be7f5336b03b287bb946787a83a9d62a276660208201529081019290925260608201523060808201525f9060a001620005fa565b5f696002601e613d5c3d52f35f52600a60165ff0905090565b5f816001600160a01b0316600a5a62000696919062000ff7565b6040515f8181818686fa925050503d805f8114620006d0576040519150601f19603f3d011682016040523d82523d5f602084013e620006d5565b606091505b50909392505050565b80825d5050565b5c90565b5f815d50565b5f80516020620043148339815191525460ff16156200070f5780825d5050565b9055565b5f5f80516020620043148339815191525460ff16156200073257505c90565b505490565b5f80516020620043148339815191525460ff161562000756575f815d50565b5f9055565b801580620007695750808251105b8062000778575063ffffffff81115b15620007975760405163246ebd8f60e21b815260040160405180910390fd5b60015f620007a58262000964565b90508015620007de575f1981015b620007cb620007c3848362000974565b849062000988565b508015620007dc575f1901620007b3565b505b5f805b855181101562000856575f86828151811062000801576200080162000e53565b60200260200101519050826001600160a01b0316816001600160a01b0316116200083e5760405163246ebd8f60e21b815260040160405180910390fd5b6200084a85826200099e565b509150600101620007e1565b50505f805463ffffffff9094166401000000000263ffffffff60201b1990941693909317909255505050565b805160021115620008a65760405163a778c8ef60e01b815260040160405180910390fd5b60035f620008b48262000964565b90508015620008e5575f1981015b620008d2620007c3848362000974565b508015620008e3575f1901620008c2565b505b5f805b84518110156200095d575f85828151811062000908576200090862000e53565b60200260200101519050826001600160a01b0316816001600160a01b031611620009455760405163a778c8ef60e01b815260040160405180910390fd5b6200095185826200099e565b509150600101620008e8565b5050505050565b5f6200096e825490565b92915050565b5f620009818383620009b4565b9392505050565b5f62000981836001600160a01b038416620009dd565b5f62000981836001600160a01b03841662000ad1565b5f825f018281548110620009cc57620009cc62000e53565b905f5260205f200154905092915050565b5f818152600183016020526040812054801562000ac7575f62000a0260018362001017565b85549091505f9062000a179060019062001017565b905080821462000a7d575f865f01828154811062000a395762000a3962000e53565b905f5260205f200154905080875f01848154811062000a5c5762000a5c62000e53565b5f918252602080832090910192909255918252600188019052604090208390555b855486908062000a915762000a9162001037565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f9055600193505050506200096e565b5f9150506200096e565b5f81815260018301602052604081205462000b1857508154600181810184555f8481526020808220909301849055845484825282860190935260409020919091556200096e565b505f6200096e565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171562000b5f5762000b5f62000b20565b604052919050565b5f6001600160401b0382111562000b825762000b8262000b20565b5060051b60200190565b5f82601f83011262000b9c575f80fd5b8151602062000bb562000baf8362000b67565b62000b34565b8083825260208201915060208460051b87010193508684111562000bd7575f80fd5b602086015b8481101562000c0a5780516001600160a01b038116811462000bfc575f80fd5b835291830191830162000bdc565b509695505050505050565b5f5b8381101562000c3157818101518382015260200162000c17565b50505f910152565b5f601f83601f84011262000c4b575f80fd5b8251602062000c5e62000baf8362000b67565b82815260059290921b8501810191818101908784111562000c7d575f80fd5b8287015b8481101562000d195780516001600160401b038082111562000ca1575f80fd5b818a0191508a603f83011262000cb5575f80fd5b8582015160408282111562000cce5762000cce62000b20565b62000ce1828b01601f1916890162000b34565b92508183528c8183860101111562000cf7575f80fd5b62000d088289850183870162000c15565b505084525091830191830162000c81565b50979650505050505050565b5f805f805f60a0868803121562000d3a575f80fd5b8551602080880151919650906001600160401b038082111562000d5b575f80fd5b62000d698a838b0162000b8c565b9650604089015191508082111562000d7f575f80fd5b62000d8d8a838b0162000b8c565b9550606089015191508082111562000da3575f80fd5b818901915089601f83011262000db7575f80fd5b815162000dc862000baf8262000b67565b81815260059190911b8301840190848101908c83111562000de7575f80fd5b938501935b8285101562000e1d5784516001600160e01b03198116811462000e0d575f80fd5b8252938501939085019062000dec565b60808c0151909750945050508083111562000e36575f80fd5b505062000e468882890162000c39565b9150509295509295909350565b634e487b7160e01b5f52603260045260245ffd5b600181811c9082168062000e7c57607f821691505b60208210810362000e9b57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000ee957805f5260205f20601f840160051c8101602085101562000ec85750805b601f840160051c820191505b818110156200095d575f815560010162000ed4565b505050565b81516001600160401b0381111562000f0a5762000f0a62000b20565b62000f228162000f1b845462000e67565b8462000ea1565b602080601f83116001811462000f58575f841562000f405750858301515b5f19600386901b1c1916600185901b17855562000fb2565b5f85815260208120601f198616915b8281101562000f885788860151825594840194600190910190840162000f67565b508582101562000fa657878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b8215158152604060208201525f825180604084015262000fe281606085016020870162000c15565b601f01601f1916919091016060019392505050565b5f826200101257634e487b7160e01b5f52601260045260245ffd5b500490565b818103818111156200096e57634e487b7160e01b5f52601160045260245ffd5b634e487b7160e01b5f52603160045260245ffd5b60805160a05160c05160e05161010051610120516101405161016051610180516101a05161324e620010c65f395f50505f6116ef01525f81816117750152611a5f01525f610e4401525f610ecb01525f6120ef01525f6120c701525f61204e01525f8181610424015261219e01525f612076015261324e5ff3fe6080604052600436106101a4575f3560e01c8063828a0660116100e0578063aedb17b311610089578063e75235b811610063578063e75235b814610582578063ee576b69146105a3578063f4c53f91146105c2578063fc535a5d146105d5576101ab565b8063aedb17b314610525578063b8371e0014610544578063bbfeef2514610563576101ab565b8063978c3f16116100ba578063978c3f16146104d2578063a8d8129b146104fd578063adb610a314610510576101ab565b8063828a06601461048b57806391269b731461049f57806394cf795e146104be576101ab565b8063545a4a3c1161014d5780636bc76d06116101275780636bc76d06146103f75780637259943d146104165780637423eb3c146104485780637df73e271461045c576101ab565b8063545a4a3c146103965780635a371508146103b557806366c03638146103d4576101ab565b80634ea209341161017e5780634ea20934146103375780634f3e9f1e1461034a57806351e3af8b14610377576101ab565b80630665f04b146102c15780634018f274146102eb5780634d398b5614610318576101ab565b366101ab57005b6003361115610286575f80357fffffffff00000000000000000000000000000000000000000000000000000000168152600760205260409020805460ff1615610284575f8160010180546101fe90612430565b80601f016020809104026020016040519081016040528092919081815260200182805461022a90612430565b80156102755780601f1061024c57610100808354040283529160200191610275565b820191905f5260205f20905b81548152906001019060200180831161025857829003601f168201915b50505050509050805160208201f35b505b345f036102bf576040517f45329c7e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b005b3480156102cc575f80fd5b506102d56105f4565b6040516102e29190612481565b60405180910390f35b3480156102f6575f80fd5b5061030a6103053660046124ea565b610605565b6040519081526020016102e2565b348015610323575f80fd5b5061030a610332366004612564565b61064e565b6102bf6103453660046125ed565b610662565b348015610355575f80fd5b50610369610364366004612683565b61091b565b6040516102e29291906126fd565b348015610382575f80fd5b506102bf610391366004612727565b6109c1565b3480156103a1575f80fd5b5061030a6103b0366004612835565b610aed565b3480156103c0575f80fd5b506102bf6103cf366004612898565b610b05565b3480156103df575f80fd5b505f5460405163ffffffff90911681526020016102e2565b348015610402575f80fd5b5061030a61041136600461297e565b610e24565b348015610421575f80fd5b507f000000000000000000000000000000000000000000000000000000000000000061030a565b348015610453575f80fd5b506102bf610e42565b348015610467575f80fd5b5061047b6104763660046129c2565b610f79565b60405190151581526020016102e2565b348015610496575f80fd5b5061030a610f85565b3480156104aa575f80fd5b5061030a6104b93660046129db565b610f8e565b3480156104c9575f80fd5b506102d5610fa5565b3480156104dd575f80fd5b5061030a6104ec366004612a3e565b60066020525f908152604090205481565b6102bf61050b366004612a55565b610fb1565b34801561051b575f80fd5b5061030a60055481565b348015610530575f80fd5b5061030a61053f366004612ad9565b61109f565b34801561054f575f80fd5b5061030a61055e366004612b18565b6110ad565b34801561056e575f80fd5b5061047b61057d366004612b62565b6110c6565b34801561058d575f80fd5b505f54640100000000900463ffffffff1661030a565b3480156105ae575f80fd5b5061047b6105bd366004612bbd565b6110e7565b6102bf6105d0366004612bf8565b6110fd565b3480156105e0575f80fd5b506102bf6105ef366004612c53565b611325565b60606106006003611534565b905090565b80355f8181526006602090815260408083205492936106489390929091610631919087019087016129c2565b60408601356106436060880188612c9e565b611540565b92915050565b5f61065a8484846115eb565b949350505050565b61066a6116c7565b5f8390036106a4576040517fe574a93100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005545f8467ffffffffffffffff8111156106c1576106c1612cff565b6040519080825280602002602001820160405280156106ea578160200160208202803683370190505b5090505f8567ffffffffffffffff81111561070757610707612cff565b60405190808252806020026020018201604052801561073a57816020015b60608152602001906001900390816107255790505b5090505f80365f365f5b8b8110156108af578c8c8281811061075e5761075e612d2c565b90506020028101906107709190612d59565b915061077f60208301836129c2565b9550602082013594506107956040830183612c9e565b935093505f6107ad8a806001019b508888888861179c565b9050808983815181106107c2576107c2612d2c565b6020026020010181815250505f808873ffffffffffffffffffffffffffffffffffffffff168888886040516107f8929190612d95565b5f6040518083038185875af1925050503d805f8114610832576040519150601f19603f3d011682016040523d82523d5f602084013e610837565b606091505b5091509150811561086557808a858151811061085557610855612d2c565b60200260200101819052506108a1565b806040517e9701970000000000000000000000000000000000000000000000000000000081526004016108989190612da4565b60405180910390fd5b505050806001019050610744565b5060058890555f6108bf88611837565b90506108cc818c8c61189b565b807f54576a17773085513ac2d8ee45ac7ead47dc7e05a25d5b43d014cc243e590522886040516108fc9190612db6565b60405180910390a2505050505050505050610915611a37565b50505050565b60076020525f90815260409020805460018201805460ff909216929161094090612430565b80601f016020809104026020016040519081016040528092919081815260200182805461096c90612430565b80156109b75780601f1061098e576101008083540402835291602001916109b7565b820191905f5260205f20905b81548152906001019060200180831161099a57829003601f168201915b5050505050905082565b5f805463ffffffff16906109d9828b8b8b8b8b611a86565b90506109e681868661189b565b6109f08184611af6565b610a2d8989808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152508e9250611bf7915050565b610a688787808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250611dac92505050565b5f805463ffffffff60019094019384167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009091161790556040517f833e20fce4b48d20600eee8f34ecec26beb95dc588acfeb8aacd02dfb9ae7b1390610ad99084908d908d908d908d908d90612e88565b60405180910390a150505050505050505050565b5f610afb8686868686611f07565b9695505050505050565b881580610b125750888714155b80610b1d5750868514155b80610b285750848314155b80610b335750828114155b15610b6a576040517fe574a93100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805463ffffffff16905b8a811015610d26575f610be8838e8e85818110610b9457610b94612d2c565b905060200201358d8d86818110610bad57610bad612d2c565b9050602002810190610bbf9190612ed1565b8d8d88818110610bd157610bd1612d2c565b9050602002810190610be39190612ed1565b611a86565b9050610c1781888885818110610c0057610c00612d2c565b9050602002810190610c129190612f35565b61189b565b610c3881868685818110610c2d57610c2d612d2c565b905060600201611af6565b610cbc8b8b84818110610c4d57610c4d612d2c565b9050602002810190610c5f9190612ed1565b808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f820116905080830192505050505050508e8e85818110610cb057610cb0612d2c565b90506020020135611bf7565b610d19898984818110610cd157610cd1612d2c565b9050602002810190610ce39190612ed1565b808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250611dac92505050565b5060019182019101610b75565b505f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff83161790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a017f833e20fce4b48d20600eee8f34ecec26beb95dc588acfeb8aacd02dfb9ae7b13828d8d84818110610dad57610dad612d2c565b905060200201358c8c85818110610dc657610dc6612d2c565b9050602002810190610dd89190612ed1565b8c8c87818110610dea57610dea612d2c565b9050602002810190610dfc9190612ed1565b604051610e0e96959493929190612e88565b60405180910390a1505050505050505050505050565b5f610e3b82358461063160408601602087016129c2565b9392505050565b7f000000000000000000000000000000000000000000000000000000000000000080610e8f57507fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b005460ff165b15610ec6576040517ff45b98b000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610eef7f0000000000000000000000000000000000000000000000000000000000000000611f89565b610f25576040517f70a4078f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b0080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610f77611ff4565b565b5f61064860018361201d565b5f61060061204b565b5f8054610afb9063ffffffff168787878787611a86565b60606106006001611534565b610fb96116c7565b60058054600181019091555f90610fd39088888888611f07565b9050610fe081848461189b565b5f808873ffffffffffffffffffffffffffffffffffffffff1688888860405161100a929190612d95565b5f6040518083038185875af1925050503d805f8114611044576040519150601f19603f3d011682016040523d82523d5f602084013e611049565b606091505b5091509150811561086557827ffd2dd1404be8946179e2efaadd5b7b78920403c755422016c708b3c84d5fd8e3826040516110849190612da4565b60405180910390a2505050611097611a37565b505050505050565b5f610e3b60055484846115eb565b5f6110bd60055486868686611f07565b95945050505050565b5f6110d285858561189b565b6110dc8583611af6565b506001949350505050565b5f6110f384848461189b565b5060019392505050565b6111056116c7565b8215806111125750828114155b15611149576040517fe574a93100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b36365f805f80365f805b8b811015611314578c8c8281811061116d5761116d612d2c565b905060200281019061117f9190612f98565b98508a8a8281811061119357611193612d2c565b90506020028101906111a59190612f35565b9098509650883595506111be60408a0160208b016129c2565b9450604089013593506111d460608a018a612c9e565b925092508473ffffffffffffffffffffffffffffffffffffffff163b5f03611228576040517f9c612a4f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f86815260066020526040812080546001810190915561124d90889088888888611540565b905061125a818a8a61189b565b5f808773ffffffffffffffffffffffffffffffffffffffff16878787604051611284929190612d95565b5f6040518083038185875af1925050503d805f81146112be576040519150601f19603f3d011682016040523d82523d5f602084013e6112c3565b606091505b5091509150811561086557827ffd2dd1404be8946179e2efaadd5b7b78920403c755422016c708b3c84d5fd8e3826040516112fe9190612da4565b60405180910390a2505050806001019050611153565b505050505050505050610915611a37565b33301461135e576040517f58983cbe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060400160405280841515815260200183838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201829052509390945250507fffffffff0000000000000000000000000000000000000000000000000000000087168152600760209081526040909120835181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690151517815590830151909150600182019061141b908261300e565b50905050837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167fa46a7bc91facec060b0513f84098b4466c9d24b2c91f0e6caea6e9226abd538c84848460405161147293929190613126565b60405180910390a250505050565b80825d5050565b5c90565b5f815d50565b7fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b005460ff16156114c25780825d5050565b9055565b5f7fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b005460ff16156114f657505c90565b5080545b919050565b7fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b005460ff161561152f575f815d50565b5f9055565b60605f610e3b8361213f565b5f6115e07f084f557b515e7c50b02487f369d91e957677bf70e81cdd20989f3a7caa0cf738888888888888604051611579929190612d95565b604080519182900382206020830197909752810194909452606084019290925273ffffffffffffffffffffffffffffffffffffffff16608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120612198565b979650505050505050565b5f83818367ffffffffffffffff81111561160757611607612cff565b604051908082528060200260200182016040528015611630578160200160208202803683370190505b509050365f5b858110156116bd5786868281811061165057611650612d2c565b90506020028101906116629190612d59565b60018501949092505f906116949061167d60208601866129c2565b602086013561168f6040880188612c9e565b61179c565b9050808483815181106116a9576116a9612d2c565b602090810291909101015250600101611636565b506115e082611837565b60026117167feff9701f8ef712cda0f707f0a4f48720f142bf7e1bce9d4747c32b4eeb8905007f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b0361174d576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f777feff9701f8ef712cda0f707f0a4f48720f142bf7e1bce9d4747c32b4eeb89050060027f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b5f7f1b36c156a37f0f0d76ca5274b8c0f557f0ed6b0e0435f04085d7d3f29731e03986868686866040516117d1929190612d95565b60408051918290038220602083019690965281019390935273ffffffffffffffffffffffffffffffffffffffff9091166060830152608082015260a081019190915260c00160405160208183030381529060405280519060200120905095945050505050565b5f6106487f28feeb9d4bd7516024ebb2d6e635bdc2b2c697620e28dd95692e33f2baf446cd61186d848051602090810291012090565b6040805160208101939093528201526060015b604051602081830303815290604052805190602001206121f9565b5f54640100000000900463ffffffff16818111156118e5576040517fb77b95a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001365f805b84811015611a2d5786868281811061190557611905612d2c565b6060029190910193505060ff8335111561194b576040517fa578efdc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080515f80825260208281018085528c905260ff87351683850152860135606083015291850135608082015260019060a0016020604051602081039080840390855afa15801561199e573d5f803e3d5ffd5b5050506020604051035190508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161115806119ec57506119ea858261201d565b155b15611a23576040517fa62c5ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b91506001016118eb565b5050505050505050565b610f777feff9701f8ef712cda0f707f0a4f48720f142bf7e1bce9d4747c32b4eeb89050060017f000000000000000000000000000000000000000000000000000000000000000063ffffffff16565b5f6115e07fd040ebbdf9607604b0546e96283b0a18f0c2fd5d8d830a9fbdae9eaaecbef40f8888611ab78989612205565b611ac18888612205565b60408051602081019690965263ffffffff909416938501939093526060840191909152608083015260a082015260c0016115c5565b60ff81351115611b32576040517fa578efdc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080515f808252602082810180855286905260ff85351683850152840135606083015291830135608082015260019060a0016020604051602081039080840390855afa158015611b85573d5f803e3d5ffd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001519150611bbc905060038261201d565b611bf2576040517fa62c5ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b801580611c045750808251105b80611c12575063ffffffff81115b15611c49576040517f91baf63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015f611c5582612222565b90508015611cc5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81015b611c95611c8e848361222b565b8490612236565b508015611cc3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611c81565b505b5f805b8551811015611d68575f868281518110611ce457611ce4612d2c565b602002602001015190508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1611611d53576040517f91baf63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d5d8582612257565b509150600101611cc8565b50505f805463ffffffff909416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff90941693909317909255505050565b805160021115611de8576040517fa778c8ef00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035f611df482612222565b90508015611e5d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81015b611e2d611c8e848361222b565b508015611e5b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611e20565b505b5f805b8451811015611f00575f858281518110611e7c57611e7c612d2c565b602002602001015190508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1611611eeb576040517fa778c8ef00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ef58582612257565b509150600101611e60565b5050505050565b5f610afb7f1b36c156a37f0f0d76ca5274b8c0f557f0ed6b0e0435f04085d7d3f29731e0398787878787604051611f3f929190612d95565b60408051918290038220602083019690965281019390935273ffffffffffffffffffffffffffffffffffffffff9091166060830152608082015260a081019190915260c001611880565b5f8173ffffffffffffffffffffffffffffffffffffffff16600a5a611fae919061317b565b6040515f8181818686fa925050503d805f8114611fe6576040519150601f19603f3d011682016040523d82523d5f602084013e611feb565b606091505b50909392505050565b610f777feff9701f8ef712cda0f707f0a4f48720f142bf7e1bce9d4747c32b4eeb890500612278565b73ffffffffffffffffffffffffffffffffffffffff81165f9081526001830160205260408120541515610e3b565b5f7f0000000000000000000000000000000000000000000000000000000000000000460361209857507f000000000000000000000000000000000000000000000000000000000000000090565b610600604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527f0000000000000000000000000000000000000000000000000000000000000000918101919091527f000000000000000000000000000000000000000000000000000000000000000060608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561218c57602002820191905f5260205f20905b815481526020019060010190808311612178575b50505050509050919050565b5f6106487f00000000000000000000000000000000000000000000000000000000000000005b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b5f6106486121be61204b565b5f6040516020830280820160405280850185833790209392505050565b5f610648825490565b5f610e3b83836122db565b5f610e3b8373ffffffffffffffffffffffffffffffffffffffff8416612301565b5f610e3b8373ffffffffffffffffffffffffffffffffffffffff84166123e4565b7fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b005460ff16156122a9578054815d50565b6040517f70a4078f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f825f0182815481106122f0576122f0612d2c565b905f5260205f200154905092915050565b5f81815260018301602052604081205480156123db575f6123236001836131b3565b85549091505f90612336906001906131b3565b9050808214612395575f865f01828154811061235457612354612d2c565b905f5260205f200154905080875f01848154811061237457612374612d2c565b5f918252602080832090910192909255918252600188019052604090208390555b85548690806123a6576123a66131eb565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610648565b5f915050610648565b5f81815260018301602052604081205461242957508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610648565b505f610648565b600181811c9082168061244457607f821691505b60208210810361247b577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b602080825282518282018190525f9190848201906040850190845b818110156124ce57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161249c565b50909695505050505050565b5f6080828403121561247b575f80fd5b5f602082840312156124fa575f80fd5b813567ffffffffffffffff811115612510575f80fd5b61065a848285016124da565b5f8083601f84011261252c575f80fd5b50813567ffffffffffffffff811115612543575f80fd5b6020830191508360208260051b850101111561255d575f80fd5b9250929050565b5f805f60408486031215612576575f80fd5b83359250602084013567ffffffffffffffff811115612593575f80fd5b61259f8682870161251c565b9497909650939450505050565b5f8083601f8401126125bc575f80fd5b50813567ffffffffffffffff8111156125d3575f80fd5b60208301915083602060608302850101111561255d575f80fd5b5f805f8060408587031215612600575f80fd5b843567ffffffffffffffff80821115612617575f80fd5b6126238883890161251c565b9096509450602087013591508082111561263b575f80fd5b50612648878288016125ac565b95989497509550505050565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146114fa575f80fd5b5f60208284031215612693575f80fd5b610e3b82612654565b5f81518084525f5b818110156126c0576020818501810151868301820152016126a4565b505f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b8215158152604060208201525f61065a604083018461269c565b5f6060828403121561247b575f80fd5b5f805f805f805f8060e0898b03121561273e575f80fd5b88359750602089013567ffffffffffffffff8082111561275c575f80fd5b6127688c838d0161251c565b909950975060408b0135915080821115612780575f80fd5b61278c8c838d0161251c565b909750955060608b01359150808211156127a4575f80fd5b506127b18b828c016125ac565b90945092506127c590508a60808b01612717565b90509295985092959890939650565b803573ffffffffffffffffffffffffffffffffffffffff811681146114fa575f80fd5b5f8083601f840112612807575f80fd5b50813567ffffffffffffffff81111561281e575f80fd5b60208301915083602082850101111561255d575f80fd5b5f805f805f60808688031215612849575f80fd5b85359450612859602087016127d4565b935060408601359250606086013567ffffffffffffffff81111561287b575f80fd5b612887888289016127f7565b969995985093965092949392505050565b5f805f805f805f805f8060a08b8d0312156128b1575f80fd5b8a3567ffffffffffffffff808211156128c8575f80fd5b6128d48e838f0161251c565b909c509a5060208d01359150808211156128ec575f80fd5b6128f88e838f0161251c565b909a50985060408d0135915080821115612910575f80fd5b61291c8e838f0161251c565b909850965060608d0135915080821115612934575f80fd5b6129408e838f0161251c565b909650945060808d0135915080821115612958575f80fd5b506129658d828e016125ac565b915080935050809150509295989b9194979a5092959850565b5f806040838503121561298f575f80fd5b82359150602083013567ffffffffffffffff8111156129ac575f80fd5b6129b8858286016124da565b9150509250929050565b5f602082840312156129d2575f80fd5b610e3b826127d4565b5f805f805f606086880312156129ef575f80fd5b85359450602086013567ffffffffffffffff80821115612a0d575f80fd5b612a1989838a0161251c565b90965094506040880135915080821115612a31575f80fd5b506128878882890161251c565b5f60208284031215612a4e575f80fd5b5035919050565b5f805f805f8060808789031215612a6a575f80fd5b612a73876127d4565b955060208701359450604087013567ffffffffffffffff80821115612a96575f80fd5b612aa28a838b016127f7565b90965094506060890135915080821115612aba575f80fd5b50612ac789828a016125ac565b979a9699509497509295939492505050565b5f8060208385031215612aea575f80fd5b823567ffffffffffffffff811115612b00575f80fd5b612b0c8582860161251c565b90969095509350505050565b5f805f8060608587031215612b2b575f80fd5b612b34856127d4565b935060208501359250604085013567ffffffffffffffff811115612b56575f80fd5b612648878288016127f7565b5f805f8060a08587031215612b75575f80fd5b84359350602085013567ffffffffffffffff811115612b92575f80fd5b612b9e878288016125ac565b9094509250612bb290508660408701612717565b905092959194509250565b5f805f60408486031215612bcf575f80fd5b83359250602084013567ffffffffffffffff811115612bec575f80fd5b61259f868287016125ac565b5f805f8060408587031215612c0b575f80fd5b843567ffffffffffffffff80821115612c22575f80fd5b612c2e8883890161251c565b90965094506020870135915080821115612c46575f80fd5b506126488782880161251c565b5f805f8060608587031215612c66575f80fd5b612c6f85612654565b935060208501358015158114612c83575f80fd5b9250604085013567ffffffffffffffff811115612b56575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612cd1575f80fd5b83018035915067ffffffffffffffff821115612ceb575f80fd5b60200191503681900382131561255d575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112612d8b575f80fd5b9190910192915050565b818382375f9101908152919050565b602081525f610e3b602083018461269c565b5f60208083016020845280855180835260408601915060408160051b8701019250602087015f5b82811015612e29577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452612e1785835161269c565b94509285019290850190600101612ddd565b5092979650505050505050565b8183525f60208085019450825f5b85811015612e7d5773ffffffffffffffffffffffffffffffffffffffff612e6a836127d4565b1687529582019590820190600101612e44565b509495945050505050565b5f63ffffffff808916835280881660208401525060806040830152612eb1608083018688612e36565b8281036060840152612ec4818587612e36565b9998505050505050505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612f04575f80fd5b83018035915067ffffffffffffffff821115612f1e575f80fd5b6020019150600581901b360382131561255d575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612f68575f80fd5b83018035915067ffffffffffffffff821115612f82575f80fd5b602001915060608102360382131561255d575f80fd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612d8b575f80fd5b601f821115611bf257805f5260205f20601f840160051c81016020851015612fef5750805b601f840160051c820191505b81811015611f00575f8155600101612ffb565b815167ffffffffffffffff81111561302857613028612cff565b61303c816130368454612430565b84612fca565b602080601f83116001811461308e575f84156130585750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611097565b5f858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156130da578886015182559484019460019091019084016130bb565b508582101561311657878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b831515815260406020820152816040820152818360608301375f818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b5f826131ae577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b81810381811115610648577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220434da885dc152cd4cb0609299995ad24e2c2f2552b77394f0a0b8fa3855bfd1264736f6c63430008180033dacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b00a46a7bc91facec060b0513f84098b4466c9d24b2c91f0e6caea6e9226abd538c000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000ead5ba549a6ca66150a2d1484d90c3f15f992fd0000000000000000000000007c6ff9371dd547c84f2def766007e5dce67f6a3f000000000000000000000000c58be29e4dd270967d5edca91c451e8aff7a8656000000000000000000000000e5b265fd6a08c98580c07f2537051775c943061f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000e1e3df6fe07927623c3fa3006c7d52733bc83808000000000000000000000000f6b8cd475599707d5e6748943de76d7d310cdb6200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106101a4575f3560e01c8063828a0660116100e0578063aedb17b311610089578063e75235b811610063578063e75235b814610582578063ee576b69146105a3578063f4c53f91146105c2578063fc535a5d146105d5576101ab565b8063aedb17b314610525578063b8371e0014610544578063bbfeef2514610563576101ab565b8063978c3f16116100ba578063978c3f16146104d2578063a8d8129b146104fd578063adb610a314610510576101ab565b8063828a06601461048b57806391269b731461049f57806394cf795e146104be576101ab565b8063545a4a3c1161014d5780636bc76d06116101275780636bc76d06146103f75780637259943d146104165780637423eb3c146104485780637df73e271461045c576101ab565b8063545a4a3c146103965780635a371508146103b557806366c03638146103d4576101ab565b80634ea209341161017e5780634ea20934146103375780634f3e9f1e1461034a57806351e3af8b14610377576101ab565b80630665f04b146102c15780634018f274146102eb5780634d398b5614610318576101ab565b366101ab57005b6003361115610286575f80357fffffffff00000000000000000000000000000000000000000000000000000000168152600760205260409020805460ff1615610284575f8160010180546101fe90612430565b80601f016020809104026020016040519081016040528092919081815260200182805461022a90612430565b80156102755780601f1061024c57610100808354040283529160200191610275565b820191905f5260205f20905b81548152906001019060200180831161025857829003601f168201915b50505050509050805160208201f35b505b345f036102bf576040517f45329c7e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b005b3480156102cc575f80fd5b506102d56105f4565b6040516102e29190612481565b60405180910390f35b3480156102f6575f80fd5b5061030a6103053660046124ea565b610605565b6040519081526020016102e2565b348015610323575f80fd5b5061030a610332366004612564565b61064e565b6102bf6103453660046125ed565b610662565b348015610355575f80fd5b50610369610364366004612683565b61091b565b6040516102e29291906126fd565b348015610382575f80fd5b506102bf610391366004612727565b6109c1565b3480156103a1575f80fd5b5061030a6103b0366004612835565b610aed565b3480156103c0575f80fd5b506102bf6103cf366004612898565b610b05565b3480156103df575f80fd5b505f5460405163ffffffff90911681526020016102e2565b348015610402575f80fd5b5061030a61041136600461297e565b610e24565b348015610421575f80fd5b507fdf8fea4d5103d9a1cbde95fe3f45712c17ec4037372cb96c3d8d2d09d07bf97861030a565b348015610453575f80fd5b506102bf610e42565b348015610467575f80fd5b5061047b6104763660046129c2565b610f79565b60405190151581526020016102e2565b348015610496575f80fd5b5061030a610f85565b3480156104aa575f80fd5b5061030a6104b93660046129db565b610f8e565b3480156104c9575f80fd5b506102d5610fa5565b3480156104dd575f80fd5b5061030a6104ec366004612a3e565b60066020525f908152604090205481565b6102bf61050b366004612a55565b610fb1565b34801561051b575f80fd5b5061030a60055481565b348015610530575f80fd5b5061030a61053f366004612ad9565b61109f565b34801561054f575f80fd5b5061030a61055e366004612b18565b6110ad565b34801561056e575f80fd5b5061047b61057d366004612b62565b6110c6565b34801561058d575f80fd5b505f54640100000000900463ffffffff1661030a565b3480156105ae575f80fd5b5061047b6105bd366004612bbd565b6110e7565b6102bf6105d0366004612bf8565b6110fd565b3480156105e0575f80fd5b506102bf6105ef366004612c53565b611325565b60606106006003611534565b905090565b80355f8181526006602090815260408083205492936106489390929091610631919087019087016129c2565b60408601356106436060880188612c9e565b611540565b92915050565b5f61065a8484846115eb565b949350505050565b61066a6116c7565b5f8390036106a4576040517fe574a93100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6005545f8467ffffffffffffffff8111156106c1576106c1612cff565b6040519080825280602002602001820160405280156106ea578160200160208202803683370190505b5090505f8567ffffffffffffffff81111561070757610707612cff565b60405190808252806020026020018201604052801561073a57816020015b60608152602001906001900390816107255790505b5090505f80365f365f5b8b8110156108af578c8c8281811061075e5761075e612d2c565b90506020028101906107709190612d59565b915061077f60208301836129c2565b9550602082013594506107956040830183612c9e565b935093505f6107ad8a806001019b508888888861179c565b9050808983815181106107c2576107c2612d2c565b6020026020010181815250505f808873ffffffffffffffffffffffffffffffffffffffff168888886040516107f8929190612d95565b5f6040518083038185875af1925050503d805f8114610832576040519150601f19603f3d011682016040523d82523d5f602084013e610837565b606091505b5091509150811561086557808a858151811061085557610855612d2c565b60200260200101819052506108a1565b806040517e9701970000000000000000000000000000000000000000000000000000000081526004016108989190612da4565b60405180910390fd5b505050806001019050610744565b5060058890555f6108bf88611837565b90506108cc818c8c61189b565b807f54576a17773085513ac2d8ee45ac7ead47dc7e05a25d5b43d014cc243e590522886040516108fc9190612db6565b60405180910390a2505050505050505050610915611a37565b50505050565b60076020525f90815260409020805460018201805460ff909216929161094090612430565b80601f016020809104026020016040519081016040528092919081815260200182805461096c90612430565b80156109b75780601f1061098e576101008083540402835291602001916109b7565b820191905f5260205f20905b81548152906001019060200180831161099a57829003601f168201915b5050505050905082565b5f805463ffffffff16906109d9828b8b8b8b8b611a86565b90506109e681868661189b565b6109f08184611af6565b610a2d8989808060200260200160405190810160405280939291908181526020018383602002808284375f920191909152508e9250611bf7915050565b610a688787808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250611dac92505050565b5f805463ffffffff60019094019384167fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000009091161790556040517f833e20fce4b48d20600eee8f34ecec26beb95dc588acfeb8aacd02dfb9ae7b1390610ad99084908d908d908d908d908d90612e88565b60405180910390a150505050505050505050565b5f610afb8686868686611f07565b9695505050505050565b881580610b125750888714155b80610b1d5750868514155b80610b285750848314155b80610b335750828114155b15610b6a576040517fe574a93100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f805463ffffffff16905b8a811015610d26575f610be8838e8e85818110610b9457610b94612d2c565b905060200201358d8d86818110610bad57610bad612d2c565b9050602002810190610bbf9190612ed1565b8d8d88818110610bd157610bd1612d2c565b9050602002810190610be39190612ed1565b611a86565b9050610c1781888885818110610c0057610c00612d2c565b9050602002810190610c129190612f35565b61189b565b610c3881868685818110610c2d57610c2d612d2c565b905060600201611af6565b610cbc8b8b84818110610c4d57610c4d612d2c565b9050602002810190610c5f9190612ed1565b808060200260200160405190810160405280939291908181526020018383602002808284375f81840152601f19601f820116905080830192505050505050508e8e85818110610cb057610cb0612d2c565b90506020020135611bf7565b610d19898984818110610cd157610cd1612d2c565b9050602002810190610ce39190612ed1565b808060200260200160405190810160405280939291908181526020018383602002808284375f92019190915250611dac92505050565b5060019182019101610b75565b505f80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000001663ffffffff83161790557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8a017f833e20fce4b48d20600eee8f34ecec26beb95dc588acfeb8aacd02dfb9ae7b13828d8d84818110610dad57610dad612d2c565b905060200201358c8c85818110610dc657610dc6612d2c565b9050602002810190610dd89190612ed1565b8c8c87818110610dea57610dea612d2c565b9050602002810190610dfc9190612ed1565b604051610e0e96959493929190612e88565b60405180910390a1505050505050505050505050565b5f610e3b82358461063160408601602087016129c2565b9392505050565b7f000000000000000000000000000000000000000000000000000000000000000180610e8f57507fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b005460ff165b15610ec6576040517ff45b98b000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610eef7f0000000000000000000000008064f4c67461893c1b63b17285998308f2e533d4611f89565b610f25576040517f70a4078f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b0080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055610f77611ff4565b565b5f61064860018361201d565b5f61060061204b565b5f8054610afb9063ffffffff168787878787611a86565b60606106006001611534565b610fb96116c7565b60058054600181019091555f90610fd39088888888611f07565b9050610fe081848461189b565b5f808873ffffffffffffffffffffffffffffffffffffffff1688888860405161100a929190612d95565b5f6040518083038185875af1925050503d805f8114611044576040519150601f19603f3d011682016040523d82523d5f602084013e611049565b606091505b5091509150811561086557827ffd2dd1404be8946179e2efaadd5b7b78920403c755422016c708b3c84d5fd8e3826040516110849190612da4565b60405180910390a2505050611097611a37565b505050505050565b5f610e3b60055484846115eb565b5f6110bd60055486868686611f07565b95945050505050565b5f6110d285858561189b565b6110dc8583611af6565b506001949350505050565b5f6110f384848461189b565b5060019392505050565b6111056116c7565b8215806111125750828114155b15611149576040517fe574a93100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b36365f805f80365f805b8b811015611314578c8c8281811061116d5761116d612d2c565b905060200281019061117f9190612f98565b98508a8a8281811061119357611193612d2c565b90506020028101906111a59190612f35565b9098509650883595506111be60408a0160208b016129c2565b9450604089013593506111d460608a018a612c9e565b925092508473ffffffffffffffffffffffffffffffffffffffff163b5f03611228576040517f9c612a4f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f86815260066020526040812080546001810190915561124d90889088888888611540565b905061125a818a8a61189b565b5f808773ffffffffffffffffffffffffffffffffffffffff16878787604051611284929190612d95565b5f6040518083038185875af1925050503d805f81146112be576040519150601f19603f3d011682016040523d82523d5f602084013e6112c3565b606091505b5091509150811561086557827ffd2dd1404be8946179e2efaadd5b7b78920403c755422016c708b3c84d5fd8e3826040516112fe9190612da4565b60405180910390a2505050806001019050611153565b505050505050505050610915611a37565b33301461135e576040517f58983cbe00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040518060400160405280841515815260200183838080601f0160208091040260200160405190810160405280939291908181526020018383808284375f9201829052509390945250507fffffffff0000000000000000000000000000000000000000000000000000000087168152600760209081526040909120835181547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690151517815590830151909150600182019061141b908261300e565b50905050837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167fa46a7bc91facec060b0513f84098b4466c9d24b2c91f0e6caea6e9226abd538c84848460405161147293929190613126565b60405180910390a250505050565b80825d5050565b5c90565b5f815d50565b7fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b005460ff16156114c25780825d5050565b9055565b5f7fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b005460ff16156114f657505c90565b5080545b919050565b7fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b005460ff161561152f575f815d50565b5f9055565b60605f610e3b8361213f565b5f6115e07f084f557b515e7c50b02487f369d91e957677bf70e81cdd20989f3a7caa0cf738888888888888604051611579929190612d95565b604080519182900382206020830197909752810194909452606084019290925273ffffffffffffffffffffffffffffffffffffffff16608083015260a082015260c081019190915260e0015b60405160208183030381529060405280519060200120612198565b979650505050505050565b5f83818367ffffffffffffffff81111561160757611607612cff565b604051908082528060200260200182016040528015611630578160200160208202803683370190505b509050365f5b858110156116bd5786868281811061165057611650612d2c565b90506020028101906116629190612d59565b60018501949092505f906116949061167d60208601866129c2565b602086013561168f6040880188612c9e565b61179c565b9050808483815181106116a9576116a9612d2c565b602090810291909101015250600101611636565b506115e082611837565b60026117167feff9701f8ef712cda0f707f0a4f48720f142bf7e1bce9d4747c32b4eeb8905007f000000000000000000000000000000000000000000000000000006e50000148763ffffffff16565b0361174d576040517f3ee5aeb500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f777feff9701f8ef712cda0f707f0a4f48720f142bf7e1bce9d4747c32b4eeb89050060027f000000000000000000000000000000000000000000000000000006de0000148063ffffffff16565b5f7f1b36c156a37f0f0d76ca5274b8c0f557f0ed6b0e0435f04085d7d3f29731e03986868686866040516117d1929190612d95565b60408051918290038220602083019690965281019390935273ffffffffffffffffffffffffffffffffffffffff9091166060830152608082015260a081019190915260c00160405160208183030381529060405280519060200120905095945050505050565b5f6106487f28feeb9d4bd7516024ebb2d6e635bdc2b2c697620e28dd95692e33f2baf446cd61186d848051602090810291012090565b6040805160208101939093528201526060015b604051602081830303815290604052805190602001206121f9565b5f54640100000000900463ffffffff16818111156118e5576040517fb77b95a900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001365f805b84811015611a2d5786868281811061190557611905612d2c565b6060029190910193505060ff8335111561194b576040517fa578efdc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080515f80825260208281018085528c905260ff87351683850152860135606083015291850135608082015260019060a0016020604051602081039080840390855afa15801561199e573d5f803e3d5ffd5b5050506020604051035190508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161115806119ec57506119ea858261201d565b155b15611a23576040517fa62c5ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b91506001016118eb565b5050505050505050565b610f777feff9701f8ef712cda0f707f0a4f48720f142bf7e1bce9d4747c32b4eeb89050060017f000000000000000000000000000000000000000000000000000006de0000148063ffffffff16565b5f6115e07fd040ebbdf9607604b0546e96283b0a18f0c2fd5d8d830a9fbdae9eaaecbef40f8888611ab78989612205565b611ac18888612205565b60408051602081019690965263ffffffff909416938501939093526060840191909152608083015260a082015260c0016115c5565b60ff81351115611b32576040517fa578efdc00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080515f808252602082810180855286905260ff85351683850152840135606083015291830135608082015260019060a0016020604051602081039080840390855afa158015611b85573d5f803e3d5ffd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001519150611bbc905060038261201d565b611bf2576040517fa62c5ac800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b801580611c045750808251105b80611c12575063ffffffff81115b15611c49576040517f91baf63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60015f611c5582612222565b90508015611cc5577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81015b611c95611c8e848361222b565b8490612236565b508015611cc3577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611c81565b505b5f805b8551811015611d68575f868281518110611ce457611ce4612d2c565b602002602001015190508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1611611d53576040517f91baf63c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611d5d8582612257565b509150600101611cc8565b50505f805463ffffffff909416640100000000027fffffffffffffffffffffffffffffffffffffffffffffffff00000000ffffffff90941693909317909255505050565b805160021115611de8576040517fa778c8ef00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60035f611df482612222565b90508015611e5d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81015b611e2d611c8e848361222b565b508015611e5b577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01611e20565b505b5f805b8451811015611f00575f858281518110611e7c57611e7c612d2c565b602002602001015190508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1611611eeb576040517fa778c8ef00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611ef58582612257565b509150600101611e60565b5050505050565b5f610afb7f1b36c156a37f0f0d76ca5274b8c0f557f0ed6b0e0435f04085d7d3f29731e0398787878787604051611f3f929190612d95565b60408051918290038220602083019690965281019390935273ffffffffffffffffffffffffffffffffffffffff9091166060830152608082015260a081019190915260c001611880565b5f8173ffffffffffffffffffffffffffffffffffffffff16600a5a611fae919061317b565b6040515f8181818686fa925050503d805f8114611fe6576040519150601f19603f3d011682016040523d82523d5f602084013e611feb565b606091505b50909392505050565b610f777feff9701f8ef712cda0f707f0a4f48720f142bf7e1bce9d4747c32b4eeb890500612278565b73ffffffffffffffffffffffffffffffffffffffff81165f9081526001830160205260408120541515610e3b565b5f7f0000000000000000000000000000000000000000000000000000000000000ab5460361209857507f15225620637a74ab0d472ec7c45150c402a00711f622fef7cad0b605e0d82b3990565b610600604080517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60208201527fa429596d7809271a52713ea6b572b82f42979e3b208382afaccbffbef811d131918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc660608201524660808201523060a08201525f9060c00160405160208183030381529060405280519060200120905090565b6060815f0180548060200260200160405190810160405280929190818152602001828054801561218c57602002820191905f5260205f20905b815481526020019060010190808311612178575b50505050509050919050565b5f6106487fdf8fea4d5103d9a1cbde95fe3f45712c17ec4037372cb96c3d8d2d09d07bf9785b836040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b5f6106486121be61204b565b5f6040516020830280820160405280850185833790209392505050565b5f610648825490565b5f610e3b83836122db565b5f610e3b8373ffffffffffffffffffffffffffffffffffffffff8416612301565b5f610e3b8373ffffffffffffffffffffffffffffffffffffffff84166123e4565b7fdacd49f6a6c42b45a5c3d195b83b324104542d9147bb8064a39c6a8d23ba9b005460ff16156122a9578054815d50565b6040517f70a4078f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5f825f0182815481106122f0576122f0612d2c565b905f5260205f200154905092915050565b5f81815260018301602052604081205480156123db575f6123236001836131b3565b85549091505f90612336906001906131b3565b9050808214612395575f865f01828154811061235457612354612d2c565b905f5260205f200154905080875f01848154811061237457612374612d2c565b5f918252602080832090910192909255918252600188019052604090208390555b85548690806123a6576123a66131eb565b600190038181905f5260205f20015f90559055856001015f8681526020019081526020015f205f905560019350505050610648565b5f915050610648565b5f81815260018301602052604081205461242957508154600181810184555f848152602080822090930184905584548482528286019093526040902091909155610648565b505f610648565b600181811c9082168061244457607f821691505b60208210810361247b577f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b50919050565b602080825282518282018190525f9190848201906040850190845b818110156124ce57835173ffffffffffffffffffffffffffffffffffffffff168352928401929184019160010161249c565b50909695505050505050565b5f6080828403121561247b575f80fd5b5f602082840312156124fa575f80fd5b813567ffffffffffffffff811115612510575f80fd5b61065a848285016124da565b5f8083601f84011261252c575f80fd5b50813567ffffffffffffffff811115612543575f80fd5b6020830191508360208260051b850101111561255d575f80fd5b9250929050565b5f805f60408486031215612576575f80fd5b83359250602084013567ffffffffffffffff811115612593575f80fd5b61259f8682870161251c565b9497909650939450505050565b5f8083601f8401126125bc575f80fd5b50813567ffffffffffffffff8111156125d3575f80fd5b60208301915083602060608302850101111561255d575f80fd5b5f805f8060408587031215612600575f80fd5b843567ffffffffffffffff80821115612617575f80fd5b6126238883890161251c565b9096509450602087013591508082111561263b575f80fd5b50612648878288016125ac565b95989497509550505050565b80357fffffffff00000000000000000000000000000000000000000000000000000000811681146114fa575f80fd5b5f60208284031215612693575f80fd5b610e3b82612654565b5f81518084525f5b818110156126c0576020818501810151868301820152016126a4565b505f6020828601015260207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010191505092915050565b8215158152604060208201525f61065a604083018461269c565b5f6060828403121561247b575f80fd5b5f805f805f805f8060e0898b03121561273e575f80fd5b88359750602089013567ffffffffffffffff8082111561275c575f80fd5b6127688c838d0161251c565b909950975060408b0135915080821115612780575f80fd5b61278c8c838d0161251c565b909750955060608b01359150808211156127a4575f80fd5b506127b18b828c016125ac565b90945092506127c590508a60808b01612717565b90509295985092959890939650565b803573ffffffffffffffffffffffffffffffffffffffff811681146114fa575f80fd5b5f8083601f840112612807575f80fd5b50813567ffffffffffffffff81111561281e575f80fd5b60208301915083602082850101111561255d575f80fd5b5f805f805f60808688031215612849575f80fd5b85359450612859602087016127d4565b935060408601359250606086013567ffffffffffffffff81111561287b575f80fd5b612887888289016127f7565b969995985093965092949392505050565b5f805f805f805f805f8060a08b8d0312156128b1575f80fd5b8a3567ffffffffffffffff808211156128c8575f80fd5b6128d48e838f0161251c565b909c509a5060208d01359150808211156128ec575f80fd5b6128f88e838f0161251c565b909a50985060408d0135915080821115612910575f80fd5b61291c8e838f0161251c565b909850965060608d0135915080821115612934575f80fd5b6129408e838f0161251c565b909650945060808d0135915080821115612958575f80fd5b506129658d828e016125ac565b915080935050809150509295989b9194979a5092959850565b5f806040838503121561298f575f80fd5b82359150602083013567ffffffffffffffff8111156129ac575f80fd5b6129b8858286016124da565b9150509250929050565b5f602082840312156129d2575f80fd5b610e3b826127d4565b5f805f805f606086880312156129ef575f80fd5b85359450602086013567ffffffffffffffff80821115612a0d575f80fd5b612a1989838a0161251c565b90965094506040880135915080821115612a31575f80fd5b506128878882890161251c565b5f60208284031215612a4e575f80fd5b5035919050565b5f805f805f8060808789031215612a6a575f80fd5b612a73876127d4565b955060208701359450604087013567ffffffffffffffff80821115612a96575f80fd5b612aa28a838b016127f7565b90965094506060890135915080821115612aba575f80fd5b50612ac789828a016125ac565b979a9699509497509295939492505050565b5f8060208385031215612aea575f80fd5b823567ffffffffffffffff811115612b00575f80fd5b612b0c8582860161251c565b90969095509350505050565b5f805f8060608587031215612b2b575f80fd5b612b34856127d4565b935060208501359250604085013567ffffffffffffffff811115612b56575f80fd5b612648878288016127f7565b5f805f8060a08587031215612b75575f80fd5b84359350602085013567ffffffffffffffff811115612b92575f80fd5b612b9e878288016125ac565b9094509250612bb290508660408701612717565b905092959194509250565b5f805f60408486031215612bcf575f80fd5b83359250602084013567ffffffffffffffff811115612bec575f80fd5b61259f868287016125ac565b5f805f8060408587031215612c0b575f80fd5b843567ffffffffffffffff80821115612c22575f80fd5b612c2e8883890161251c565b90965094506020870135915080821115612c46575f80fd5b506126488782880161251c565b5f805f8060608587031215612c66575f80fd5b612c6f85612654565b935060208501358015158114612c83575f80fd5b9250604085013567ffffffffffffffff811115612b56575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612cd1575f80fd5b83018035915067ffffffffffffffff821115612ceb575f80fd5b60200191503681900382131561255d575f80fd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffa1833603018112612d8b575f80fd5b9190910192915050565b818382375f9101908152919050565b602081525f610e3b602083018461269c565b5f60208083016020845280855180835260408601915060408160051b8701019250602087015f5b82811015612e29577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffc0888603018452612e1785835161269c565b94509285019290850190600101612ddd565b5092979650505050505050565b8183525f60208085019450825f5b85811015612e7d5773ffffffffffffffffffffffffffffffffffffffff612e6a836127d4565b1687529582019590820190600101612e44565b509495945050505050565b5f63ffffffff808916835280881660208401525060806040830152612eb1608083018688612e36565b8281036060840152612ec4818587612e36565b9998505050505050505050565b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612f04575f80fd5b83018035915067ffffffffffffffff821115612f1e575f80fd5b6020019150600581901b360382131561255d575f80fd5b5f8083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe1843603018112612f68575f80fd5b83018035915067ffffffffffffffff821115612f82575f80fd5b602001915060608102360382131561255d575f80fd5b5f82357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112612d8b575f80fd5b601f821115611bf257805f5260205f20601f840160051c81016020851015612fef5750805b601f840160051c820191505b81811015611f00575f8155600101612ffb565b815167ffffffffffffffff81111561302857613028612cff565b61303c816130368454612430565b84612fca565b602080601f83116001811461308e575f84156130585750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555611097565b5f858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b828110156130da578886015182559484019460019091019084016130bb565b508582101561311657878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b831515815260406020820152816040820152818360608301375f818301606090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016010192915050565b5f826131ae577f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b500490565b81810381811115610648577f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603160045260245ffdfea2646970667358221220434da885dc152cd4cb0609299995ad24e2c2f2552b77394f0a0b8fa3855bfd1264736f6c63430008180033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000000000000000000000000000000000000000000300000000000000000000000000000000000000000000000000000000000000a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000001c000000000000000000000000000000000000000000000000000000000000000040000000000000000000000000ead5ba549a6ca66150a2d1484d90c3f15f992fd0000000000000000000000007c6ff9371dd547c84f2def766007e5dce67f6a3f000000000000000000000000c58be29e4dd270967d5edca91c451e8aff7a8656000000000000000000000000e5b265fd6a08c98580c07f2537051775c943061f0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000e1e3df6fe07927623c3fa3006c7d52733bc83808000000000000000000000000f6b8cd475599707d5e6748943de76d7d310cdb6200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : threshold (uint256): 3
Arg [1] : signers (address[]): 0x0EaD5bA549A6cA66150a2d1484d90c3f15F992Fd,0x7c6FF9371dD547C84f2DEf766007E5DCE67f6A3f,0xc58bE29E4dD270967D5EdCa91c451e8aFF7A8656,0xe5b265Fd6A08C98580c07F2537051775c943061F
Arg [2] : guardians (address[]): 0xe1e3df6FE07927623C3Fa3006C7d52733bc83808,0xf6b8Cd475599707d5E6748943de76D7D310cdb62
Arg [3] : fallbackReturnSelectors (bytes4[]):
Arg [4] : fallbackReturnData (bytes[]):
-----Encoded View---------------
15 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000140
Arg [3] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [4] : 00000000000000000000000000000000000000000000000000000000000001c0
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [6] : 0000000000000000000000000ead5ba549a6ca66150a2d1484d90c3f15f992fd
Arg [7] : 0000000000000000000000007c6ff9371dd547c84f2def766007e5dce67f6a3f
Arg [8] : 000000000000000000000000c58be29e4dd270967d5edca91c451e8aff7a8656
Arg [9] : 000000000000000000000000e5b265fd6a08c98580c07f2537051775c943061f
Arg [10] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [11] : 000000000000000000000000e1e3df6fe07927623c3fa3006c7d52733bc83808
Arg [12] : 000000000000000000000000f6b8cd475599707d5e6748943de76d7d310cdb62
Arg [13] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [14] : 0000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode Sourcemap
1277:40329:4:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41154:1;41136:8;:19;41132:369;;;41171:37;41227:7;;;;41211:24;;:15;:24;;;;;41253:22;;;;41249:242;;;41295:23;41321:14;:25;;41295:51;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41447:10;41441:17;41434:4;41422:10;41418:21;41411:48;41249:242;41157:344;41132:369;41514:9;41527:1;41514:14;41510:88;;41551:36;;;;;;;;;;;;;;41510:88;1277:40329;27957:132;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;23324:389;;;;;;;;;;-1:-1:-1;23324:389:4;;;;;:::i;:::-;;:::i;:::-;;;1851:25:9;;;1839:2;1824:18;23324:389:4;1705:177:9;21438:220:4;;;;;;;;;;-1:-1:-1;21438:220:4;;;;;:::i;:::-;;:::i;8388:1633::-;;;;;;:::i;:::-;;:::i;1877:57::-;;;;;;;;;;-1:-1:-1;1877:57:4;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;14525:763::-;;;;;;;;;;-1:-1:-1;14525:763:4;;;;;:::i;:::-;;:::i;20027:233::-;;;;;;;;;;-1:-1:-1;20027:233:4;;;;;:::i;:::-;;:::i;16908:1609::-;;;;;;;;;;-1:-1:-1;16908:1609:4;;;;;:::i;:::-;;:::i;26673:133::-;;;;;;;;;;-1:-1:-1;26729:25:4;26787:12;26673:133;;26787:12;;;;10255:42:9;;10243:2;10228:18;26673:133:4;10111:192:9;22652:359:4;;;;;;;;;;-1:-1:-1;22652:359:4;;;;;:::i;:::-;;:::i;28704:172::-;;;;;;;;;;-1:-1:-1;3968:31:2;28704:172:4;27957:132;4954:532:6;;;;;;;;;;;;;:::i;27315:148:4:-;;;;;;;;;;-1:-1:-1;27315:148:4;;;;;:::i;:::-;;:::i;:::-;;;11120:14:9;;11113:22;11095:41;;11083:2;11068:18;27315:148:4;10955:187:9;28310:156:4;;;;;;;;;;;;;:::i;24168:256::-;;;;;;;;;;-1:-1:-1;24168:256:4;;;;;:::i;:::-;;:::i;27645:124::-;;;;;;;;;;;;;:::i;1670:58::-;;;;;;;;;;-1:-1:-1;1670:58:4;;;;;:::i;:::-;;;;;;;;;;;;;;6387:691;;;;;;:::i;:::-;;:::i;1564:27::-;;;;;;;;;;;;;;;;22029:220;;;;;;;;;;-1:-1:-1;22029:220:4;;;;;:::i;:::-;;:::i;20722:233::-;;;;;;;;;;-1:-1:-1;20722:233:4;;;;;:::i;:::-;;:::i;26200:325::-;;;;;;;;;;-1:-1:-1;26200:325:4;;;;;:::i;:::-;;:::i;26992:114::-;;;;;;;;;;-1:-1:-1;27039:17:4;27080:19;;;;;;26992:114;;25135:222;;;;;;;;;;-1:-1:-1;25135:222:4;;;;;:::i;:::-;;:::i;11588:1625::-;;;;;;:::i;:::-;;:::i;19044:414::-;;;;;;;;;;-1:-1:-1;19044:414:4;;;;;:::i;:::-;;:::i;27957:132::-;28004:26;28054:28;:19;:26;:28::i;:::-;28042:40;;27957:132;:::o;23324:389::-;23533:18;;23459:12;23565:42;;;:22;:42;;;;;;;;;23459:12;;23490:216;;23533:18;;23565:42;;23621:14;;;;;;;;;:::i;:::-;23649:17;;;;23680:16;;;;23649:11;23680:16;:::i;:::-;23490:29;:216::i;:::-;23483:223;23324:389;-1:-1:-1;;23324:389:4:o;21438:220::-;21575:12;21606:45;21631:5;21638:12;;21606:24;:45::i;:::-;21599:52;21438:220;-1:-1:-1;;;;21438:220:4:o;8388:1633::-;1263:21:7;:19;:21::i;:::-;8592:1:4::1;8569:24:::0;;;8565:99:::1;;8616:37;;;;;;;;;;;;;;8565:99;8720:12;::::0;8698:19:::1;8788:12:::0;8774:34:::1;::::0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;8774:34:4::1;-1:-1:-1::0;8746:62:4;-1:-1:-1;8822:24:4::1;8861:12:::0;8849:32:::1;::::0;::::1;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8822:59;;8896:10;8920:13:::0;8947:19:::1;;8980:39;9038:9;9033:726;9049:23:::0;;::::1;9033:726;;;9111:12;;9124:1;9111:15;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;9097:29:::0;-1:-1:-1;9149:14:4::1;;::::0;::::1;9097:29:::0;9149:14:::1;:::i;:::-;9144:19:::0;-1:-1:-1;9189:17:4::1;::::0;::::1;;::::0;-1:-1:-1;9231:16:4::1;;::::0;::::1;9189:11:::0;9231:16:::1;:::i;:::-;9224:23;;;;9266:14;9283:157;9332:13;;;;;;9367:2;9391:5;9418:4;;9283:27;:157::i;:::-;9266:174;;9472:6;9458:8;9467:1;9458:11;;;;;;;;:::i;:::-;;;;;;:20;;;::::0;::::1;9498:12;9512:19:::0;9535:2:::1;:7;;9550:5;9557:4;;9535:27;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9497:65;;;;9584:7;9580:165;;;9630:6;9615:9;9625:1;9615:12;;;;;;;;:::i;:::-;;;;;;:21;;;;9580:165;;;9719:6;9690:36;;;;;;;;;;;:::i;:::-;;;;;;;;9580:165;9079:680;;;9074:3;;;;;9033:726;;;-1:-1:-1::0;9773:12:4::1;:26:::0;;;9813:19:::1;9835:46;9872:8:::0;9835:36:::1;:46::i;:::-;9813:68;;9896:41;9913:11;9926:10;;9896:16;:41::i;:::-;9981:11;9956:48;9994:9;9956:48;;;;;;:::i;:::-;;;;;;;;8674:1341;;;;;;;;;1305:20:7::0;:18;:20::i;:::-;8388:1633:4;;;;:::o;1877:57::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;14525:763::-;14770:25;14798:12;;;;;14844:68;14798:12;14882:9;14893:7;;14902:9;;14844:17;:68::i;:::-;14820:92;;14922:43;14939:13;14954:10;;14922:16;:43::i;:::-;14975:57;14999:13;15014:17;14975:23;:57::i;:::-;15042:33;15056:7;;15042:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15065:9:4;;-1:-1:-1;15042:13:4;;-1:-1:-1;;15042:33:4:i;:::-;15085:26;15101:9;;15085:26;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;15085:15:4;;-1:-1:-1;;;15085:26:4:i;:::-;15145:9;:35;;;15160:20;;;;15145:35;;;;;;;;;;15205:76;;;;;;15160:20;;15250:9;;15262:7;;;;15271:9;;;;15205:76;:::i;:::-;;;;;;;;14760:528;;14525:763;;;;;;;;:::o;20027:233::-;20179:12;20210:43;20230:5;20237:2;20241:5;20248:4;;20210:19;:43::i;:::-;20203:50;20027:233;-1:-1:-1;;;;;;20027:233:4:o;16908:1609::-;17219:26;;;:86;;-1:-1:-1;17261:44:4;;;;17219:86;:146;;;-1:-1:-1;17321:44:4;;;;17219:146;:209;;;-1:-1:-1;17381:47:4;;;;17219:209;:280;;;-1:-1:-1;17444:55:4;;;;17219:280;17202:377;;;17531:37;;;;;;;;;;;;;;17202:377;17613:25;17641:12;;;;;17667:506;17683:25;;;17667:506;;;17733:21;17757:92;17775:18;17795:14;;17810:1;17795:17;;;;;;;:::i;:::-;;;;;;;17814:12;;17827:1;17814:15;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;17831:14;;17846:1;17831:17;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;17757;:92::i;:::-;17733:116;;17867:51;17884:13;17899:15;;17915:1;17899:18;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;17867:16;:51::i;:::-;17936:65;17960:13;17975:22;;17998:1;17975:25;;;;;;;:::i;:::-;;;;;;17936:23;:65::i;:::-;18019:49;18033:12;;18046:1;18033:15;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;18019:49;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;18050:14;;18065:1;18050:17;;;;;;;:::i;:::-;;;;;;;18019:13;:49::i;:::-;18086:34;18102:14;;18117:1;18102:17;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;18086:34;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;18086:15:4;;-1:-1:-1;;;18086:34:4:i;:::-;-1:-1:-1;18138:20:4;;;;;17710:3;17667:506;;;-1:-1:-1;18186:9:4;:33;;;;;;;;;;18254:25;;;18298:202;18186:33;18254:14;:25;;18376;;;;;;;:::i;:::-;;;;;;;18420:12;;18433:9;18420:23;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;18461:14;;18476:9;18461:25;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;18298:202;;;;;;;;;;;:::i;:::-;;;;;;;;17589:922;;16908:1609;;;;;;;;;;:::o;22652:359::-;22794:12;22825:179;22868:18;;22900:5;22919:14;;;;;;;;:::i;22825:179::-;22818:186;22652:359;-1:-1:-1;;;22652:359:4:o;4954:532:6:-;5066:21;:61;;;-1:-1:-1;212:66:5;5091:36:6;;;5066:61;5062:123;;;5150:24;;;;;;;;;;;;;;5062:123;5267:30;5278:18;5267:10;:30::i;:::-;5262:89;;5320:20;;;;;;;;;;;;;;5262:89;212:66:5;5398:43:6;;;;5437:4;5398:43;;;5452:27;:25;:27::i;:::-;4954:532::o;27315:148:4:-;27372:20;27422:34;:17;27449:6;27422:26;:34::i;28310:156::-;28365:32;28436:23;:21;:23::i;24168:256::-;24324:12;24373;;24355:62;;24373:12;;24387:9;24398:7;;24407:9;;24355:17;:62::i;27645:124::-;27690:24;27736:26;:17;:24;:26::i;6387:691::-;1263:21:7;:19;:21::i;:::-;6657:12:4::1;:14:::0;;::::1;::::0;::::1;::::0;;;6603::::1;::::0;6620:130:::1;::::0;6689:2;6709:5;6732:4;;6620:19:::1;:130::i;:::-;6603:147;;6764:36;6781:6;6789:10;;6764:16;:36::i;:::-;6816:12;6830:19:::0;6853:2:::1;:7;;6868:5;6875:4;;6853:27;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6815:65;;;;6898:7;6894:168;;;6950:6;6930:35;6958:6;6930:35;;;;;;:::i;:::-;;;;;;;;6579:493;;;1305:20:7::0;:18;:20::i;:::-;6387:691:4;;;;;;:::o;22029:220::-;22159:12;22190:52;22215:12;;22229;;22190:24;:52::i;20722:233::-;20867:12;20898:50;20918:12;;20932:2;20936:5;20943:4;;20898:19;:50::i;:::-;20891:57;20722:233;-1:-1:-1;;;;;20722:233:4:o;26200:325::-;26388:4;26404:34;26421:4;26427:10;;26404:16;:34::i;:::-;26448:48;26472:4;26478:17;26448:23;:48::i;:::-;-1:-1:-1;26514:4:4;26200:325;;;;;;:::o;25135:222::-;25278:4;25294:34;25311:4;25317:10;;25294:16;:34::i;:::-;-1:-1:-1;25346:4:4;25135:222;;;;;:::o;11588:1625::-;1263:21:7;:19;:21::i;:::-;11780:24:4;;;:68:::1;;-1:-1:-1::0;11808:40:4;;::::1;;11780:68;11776:143;;;11871:37;;;;;;;;;;;;;;11776:143;11953:42;12009:38;;12061:14:::0;12089:10:::1;12113:13:::0;12140:19:::1;;12179:9:::0;12174:1023:::1;12190:23:::0;;::::1;12174:1023;;;12252:12;;12265:1;12252:15;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;12238:29;;12300:10;;12311:1;12300:13;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;12285:28:::0;;-1:-1:-1;12285:28:4;-1:-1:-1;12340:18:4;::::1;::::0;-1:-1:-1;12381:14:4::1;::::0;;;::::1;::::0;::::1;;:::i;:::-;12376:19:::0;-1:-1:-1;12421:17:4::1;::::0;::::1;;::::0;-1:-1:-1;12463:16:4::1;;::::0;::::1;12421:11:::0;12463:16:::1;:::i;:::-;12456:23;;;;12502:2;:14;;;12520:1;12502:19:::0;12498:102:::1;;12552:29;;;;;;;;;;;;;;12498:102;12618:14;12714:30:::0;;;:22:::1;:30;::::0;;;;:32;;::::1;::::0;::::1;::::0;;;12635:206:::1;::::0;12686:6;;12768:2;12792:5;12819:4;;12635:29:::1;:206::i;:::-;12618:223;;12859:38;12876:6;12884:12;;12859:16;:38::i;:::-;12917:12;12931:19:::0;12954:2:::1;:7;;12969:5;12976:4;;12954:27;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12916:65;;;;13003:7;12999:184;;;13059:6;13039:35;13067:6;13039:35;;;;;;:::i;:::-;;;;;;;;12220:977;;;12215:3;;;;;12174:1023;;;;11929:1278;;;;;;;;1305:20:7::0;:18;:20::i;19044:414:4:-;19156:10;19178:4;19156:27;19152:101;;19206:36;;;;;;;;;;;;;;19152:101;19291:92;;;;;;;;19329:7;19291:92;;;;;;19362:10;;19291:92;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19291:92:4;;;;-1:-1:-1;;19263:25:4;;;;;:15;:25;;;;;;;;:120;;;;;;;;;;;;;;;;:25;;-1:-1:-1;;19263:120:4;;;;;;;:::i;:::-;;;;;19421:8;19399:52;;;;19431:7;19440:10;;19399:52;;;;;;;;:::i;:::-;;;;;;;;19044:414;;;;:::o;5818:140:6:-;5936:5;5923:11;5916:26;5818:140;;:::o;6999:169::-;7134:18;;6999:169::o;8171:123::-;8276:1;8263:11;8256:22;8171:123;:::o;6333:331::-;212:66:5;6432:36:6;;;6428:230;;;6531:5;6518:11;6511:26;6333:331;;:::o;6428:230::-;6608:26;;6333:331::o;7546:360::-;7643:13;212:66:5;7672:36:6;;;7668:232;;;-1:-1:-1;7760:18:6;;7546:360::o;7668:232::-;-1:-1:-1;7858:18:6;;7668:232;7546:360;;;:::o;8602:310::-;212:66:5;8688:36:6;;;8684:222;;;8787:1;8774:11;8767:22;8602:310;:::o;8684:222::-;8880:1;8860:22;;8602:310::o;10064:300:8:-;10127:16;10155:22;10180:19;10188:3;10180:7;:19::i;33082:538:4:-;33269:12;33300:313;886:100:0;33450:6:4;33478:5;33505:2;33529:5;33566:4;;33556:15;;;;;;;:::i;:::-;;;;;;;;;;33364:225;;;25997:25:9;;;;26038:18;;26031:34;;;;26081:18;;;26074:34;;;;26156:42;26144:55;26124:18;;;26117:83;26216:19;;;26209:35;26260:19;;;26253:35;;;;25969:19;;33364:225:4;;;;;;;;;;;;;33337:266;;;;;;33300:23;:313::i;:::-;33293:320;33082:538;-1:-1:-1;;;;;;;33082:538:4:o;35452:814::-;35590:12;35660:5;35590:12;35721;35707:34;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35707:34:4;;35679:62;;35755:39;35813:9;35808:374;35824:23;;;35808:374;;;35886:12;;35899:1;35886:15;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;35985:13;;;;35872:29;;-1:-1:-1;35919:14:4;;35936:193;;36020:14;;;;35872:29;36020:14;:::i;:::-;36056:17;;;;36095:16;;;;36056:11;36095:16;:::i;:::-;35936:27;:193::i;:::-;35919:210;;36161:6;36147:8;36156:1;36147:11;;;;;;;;:::i;:::-;;;;;;;;;;:20;-1:-1:-1;35849:3:4;;35808:374;;;;36203:46;36240:8;36203:36;:46::i;1338:368:7:-;599:1;1465:38;445:66;1465:12;:38;;:::i;:::-;:49;1461:117;;1537:30;;;;;;;;;;;;;;1461:117;1652:47;445:66;599:1;1652:12;:47;;:::i;34052:393:4:-;34213:12;436:75:0;34333:5:4;34356:2;34376:5;34409:4;;34399:15;;;;;;;:::i;:::-;;;;;;;;;;34267:161;;;26558:25:9;;;;26599:18;;26592:34;;;;26674:42;26662:55;;;26642:18;;;26635:83;26734:18;;;26727:34;26777:19;;;26770:35;;;;26530:19;;34267:161:4;;;;;;;;;;;;34244:194;;;;;;34237:201;;34052:393;;;;;;;:::o;34735:362::-;34845:12;34876:214;633:119:0;35016:32:4;35039:8;38425:13;;38392:4;38421:24;;;38380:17;;38472:19;;38220:287;35016:32;34936:130;;;;;;26990:25:9;;;;27031:18;;27024:34;26963:18;;34936:130:4;;;;;;;;;;;;;34909:171;;;;;;34876:19;:214::i;39120:921::-;39222:26;39251:19;;;;;;39285:38;;;39281:113;;;39346:37;;;;;;;;;;;;;;39281:113;39447:17;39474:33;39404:40;;39549:486;39569:18;39565:1;:22;39549:486;;;39620:10;;39631:1;39620:13;;;;;;;:::i;:::-;;;;;;;;-1:-1:-1;;39665:15:4;39651:11;;:29;39647:101;;;39707:26;;;;;;;;;;;;;;39647:101;39828:11;39779:61;;39762:14;39779:61;;;39815:11;39779:61;;;;;;27296:25:9;;;27369:4;39801:11:4;;27357:17:9;27337:18;;;27330:45;39815:11:4;;;27391:18:9;;;27384:34;39828:11:4;;;;27434:18:9;;;27427:34;39779:61:4;;27268:19:9;;39779:61:4;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;39762:78;;39868:14;39858:24;;:6;:24;;;;:53;;;-1:-1:-1;39887:24:4;:7;39904:6;39887:16;:24::i;:::-;39886:25;39858:53;39854:134;;;39938:35;;;;;;;;;;;;;;39854:134;40018:6;-1:-1:-1;39589:3:4;;39549:486;;;;39212:829;;;;39120:921;;;:::o;1712:106:7:-;1760:51;445:66;557:1;1760:12;:51;;:::i;36789:552:4:-;36974:12;37005:329;1085:105:0;37142:11:4;37175:9;37206:31;37229:7;;37206:22;:31::i;:::-;37259:33;37282:9;;37259:22;:33::i;:::-;37069:241;;;;;;27729:25:9;;;;27802:10;27790:23;;;27770:18;;;27763:51;;;;27830:18;;;27823:34;;;;27873:18;;;27866:34;27916:19;;;27909:35;27701:19;;37069:241:4;27472:478:9;40492:413:4;40616:15;40602:11;;:29;40598:93;;;40654:26;;;;;;;;;;;;;;40598:93;40767:11;40718:61;;40701:14;40718:61;;;40754:11;40718:61;;;;;;27296:25:9;;;27369:4;40740:11:4;;27357:17:9;27337:18;;;27330:45;40754:11:4;;;27391:18:9;;;27384:34;40767:11:4;;;;27434:18:9;;;27427:34;40718:61:4;;27268:19:9;;40718:61:4;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;40718:61:4;;;;;;-1:-1:-1;40794:36:4;;-1:-1:-1;40794:19:4;40718:61;40794:28;:36::i;:::-;40789:110;;40853:35;;;;;;;;;;;;;;40789:110;40588:317;40492:413;;:::o;29249:1113::-;29340:14;;;:44;;;29375:9;29358:7;:14;:26;29340:44;:76;;;-1:-1:-1;29400:16:4;29388:28;;29340:76;29336:148;;;29439:34;;;;;;;;;;;;;;29336:148;29546:17;29494:49;29606:25;29546:17;29606:23;:25::i;:::-;29573:58;-1:-1:-1;29645:26:4;;29641:335;;29731:26;;;29775:177;29810:51;29834:26;:16;29854:5;29834:19;:26::i;:::-;29810:16;;:23;:51::i;:::-;-1:-1:-1;29883:21:4;;29899:5;29883:21;29926:7;;29775:177;;;29687:279;29641:335;29986:22;30023:9;30018:289;30038:7;:14;30034:1;:18;30018:289;;;30073:14;30090:7;30098:1;30090:10;;;;;;;;:::i;:::-;;;;;;;30073:27;;30128:14;30118:24;;:6;:24;;;30114:104;;30169:34;;;;;;;;;;;;;;30114:104;30231:28;:16;30252:6;30231:20;:28::i;:::-;-1:-1:-1;30290:6:4;-1:-1:-1;30054:3:4;;30018:289;;;-1:-1:-1;;30316:9:4;:39;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;29249:1113:4:o;30658:1049::-;30734:16;;325:1:0;-1:-1:-1;30730:110:4;;;30793:36;;;;;;;;;;;;;;30730:110;30904:19;30850:51;30968:27;30904:19;30968:25;:27::i;:::-;30933:62;-1:-1:-1;31009:28:4;;31005:343;;31097:28;;;31143:181;31178:55;31204:28;:18;31226:5;31204:21;:28::i;31178:55::-;-1:-1:-1;31255:21:4;;31271:5;31255:21;31298:7;;31143:181;;;31053:285;31005:343;31358:24;31397:9;31392:309;31412:9;:16;31408:1;:20;31392:309;;;31449:16;31468:9;31478:1;31468:12;;;;;;;;:::i;:::-;;;;;;;31449:31;;31510:16;31498:28;;:8;:28;;;31494:110;;31553:36;;;;;;;;;;;;;;31494:110;31617:32;:18;31640:8;31617:22;:32::i;:::-;-1:-1:-1;31682:8:4;-1:-1:-1;31430:3:4;;31392:309;;;;30720:987;;;30658:1049;:::o;32142:460::-;32295:12;32326:269;436:75:0;32460:5:4;32487:2;32511:5;32548:4;;32538:15;;;;;;;:::i;:::-;;;;;;;;;;32386:185;;;26558:25:9;;;;26599:18;;26592:34;;;;26674:42;26662:55;;;26642:18;;;26635:83;26734:18;;;26727:34;26777:19;;;26770:35;;;;26530:19;;32386:185:4;26299:512:9;10291:407:6;10374:7;10636:17;:28;;10683:2;10671:9;:14;;;;:::i;:::-;10636:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;10627:64:6;;10291:407;-1:-1:-1;;;10291:407:6:o;1824:133:7:-;1897:53;445:66;1897:27;:53::i;8665:165:8:-;8798:23;;;8745:4;4154:21;;;:14;;;:21;;;;;;:26;;8768:55;4058:129;3488:281:2;3544:23;3600:14;3583:13;:31;3579:184;;-1:-1:-1;3648:27:2;3488:281;:::o;3579:184::-;3724:28;4108:87;;;1799:95;4108:87;;;28703:25:9;4137:11:2;28744:18:9;;;28737:34;;;;4150:14:2;28787:18:9;;;28780:34;4166:13:2;28830:18:9;;;28823:34;4189:4:2;28873:19:9;;;28866:84;4072:7:2;;28675:19:9;;4108:87:2;;;;;;;;;;;;4098:98;;;;;;4091:105;;4012:191;;5375:109:8;5431:16;5466:3;:11;;5459:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5375:109;;;:::o;4576:179:2:-;4660:12;4691:57;3968:31;4708:27;4737:10;4919:4;4913:11;4949:10;4937:23;;4989:4;4980:14;;4973:39;;;;5041:4;5032:14;;5025:34;5095:4;5080:20;;;4761:355;4399:171;4479:12;4510:53;4527:23;:21;:23::i;37573:411:4:-;37658:21;37747:4;37741:11;37798:4;37780:16;37776:27;37838:3;37833;37829:13;37823:4;37816:27;37914:3;37896:16;37892:26;37874:16;37869:3;37856:63;37949:19;;;37573:411;-1:-1:-1;;;37573:411:4:o;8911:115:8:-;8974:7;9000:19;9008:3;4350:18;;4268:107;9368:156;9442:7;9492:22;9496:3;9508:5;9492:3;:22::i;8428:156::-;8501:4;8524:53;8532:3;8552:23;;;8524:7;:53::i;8110:150::-;8180:4;8203:50;8208:3;8228:23;;;8203:4;:50::i;9120:287:6:-;212:66:5;9201:36:6;;;9197:204;;;9306:11;9300:18;9287:11;9280:39;8602:310;:::o;9197:204::-;9370:20;;;;;;;;;;;;;;4717:118:8;4784:7;4810:3;:11;;4822:5;4810:18;;;;;;;;:::i;:::-;;;;;;;;;4803:25;;4717:118;;;;:::o;2609:1368::-;2675:4;2804:21;;;:14;;;:21;;;;;;2840:13;;2836:1135;;3207:18;3228:12;3239:1;3228:8;:12;:::i;:::-;3274:18;;3207:33;;-1:-1:-1;3254:17:8;;3274:22;;3295:1;;3274:22;:::i;:::-;3254:42;;3329:9;3315:10;:23;3311:378;;3358:17;3378:3;:11;;3390:9;3378:22;;;;;;;;:::i;:::-;;;;;;;;;3358:42;;3525:9;3499:3;:11;;3511:10;3499:23;;;;;;;;:::i;:::-;;;;;;;;;;;;:35;;;;3638:25;;;:14;;;:25;;;;;:36;;;3311:378;3767:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;3870:3;:14;;:21;3885:5;3870:21;;;;;;;;;;;3863:28;;;3913:4;3906:11;;;;;;;2836:1135;3955:5;3948:12;;;;;2035:406;2098:4;4154:21;;;:14;;;:21;;;;;;2114:321;;-1:-1:-1;2156:23:8;;;;;;;;:11;:23;;;;;;;;;;;;;2338:18;;2314:21;;;:14;;;:21;;;;;;:42;;;;2370:11;;2114:321;-1:-1:-1;2419:5:8;2412:12;;14:437:9;93:1;89:12;;;;136;;;157:61;;211:4;203:6;199:17;189:27;;157:61;264:2;256:6;253:14;233:18;230:38;227:218;;301:77;298:1;291:88;402:4;399:1;392:15;430:4;427:1;420:15;227:218;;14:437;;;:::o;456:681::-;627:2;679:21;;;749:13;;652:18;;;771:22;;;598:4;;627:2;850:15;;;;824:2;809:18;;;598:4;893:218;907:6;904:1;901:13;893:218;;;972:13;;987:42;968:62;956:75;;1086:15;;;;1051:12;;;;929:1;922:9;893:218;;;-1:-1:-1;1128:3:9;;456:681;-1:-1:-1;;;;;;456:681:9:o;1142:170::-;1216:5;1261:3;1252:6;1247:3;1243:16;1239:26;1236:46;;;1278:1;1275;1268:12;1317:383;1416:6;1469:2;1457:9;1448:7;1444:23;1440:32;1437:52;;;1485:1;1482;1475:12;1437:52;1525:9;1512:23;1558:18;1550:6;1547:30;1544:50;;;1590:1;1587;1580:12;1544:50;1613:81;1686:7;1677:6;1666:9;1662:22;1613:81;:::i;1887:394::-;1977:8;1987:6;2041:3;2034:4;2026:6;2022:17;2018:27;2008:55;;2059:1;2056;2049:12;2008:55;-1:-1:-1;2082:20:9;;2125:18;2114:30;;2111:50;;;2157:1;2154;2147:12;2111:50;2194:4;2186:6;2182:17;2170:29;;2254:3;2247:4;2237:6;2234:1;2230:14;2222:6;2218:27;2214:38;2211:47;2208:67;;;2271:1;2268;2261:12;2208:67;1887:394;;;;;:::o;2286:568::-;2417:6;2425;2433;2486:2;2474:9;2465:7;2461:23;2457:32;2454:52;;;2502:1;2499;2492:12;2454:52;2538:9;2525:23;2515:33;;2599:2;2588:9;2584:18;2571:32;2626:18;2618:6;2615:30;2612:50;;;2658:1;2655;2648:12;2612:50;2697:97;2786:7;2777:6;2766:9;2762:22;2697:97;:::i;:::-;2286:568;;2813:8;;-1:-1:-1;2671:123:9;;-1:-1:-1;;;;2286:568:9:o;2859:393::-;2945:8;2955:6;3009:3;3002:4;2994:6;2990:17;2986:27;2976:55;;3027:1;3024;3017:12;2976:55;-1:-1:-1;3050:20:9;;3093:18;3082:30;;3079:50;;;3125:1;3122;3115:12;3079:50;3162:4;3154:6;3150:17;3138:29;;3225:3;3218:4;3210;3202:6;3198:17;3190:6;3186:30;3182:41;3179:50;3176:70;;;3242:1;3239;3232:12;3257:891;3447:6;3455;3463;3471;3524:2;3512:9;3503:7;3499:23;3495:32;3492:52;;;3540:1;3537;3530:12;3492:52;3580:9;3567:23;3609:18;3650:2;3642:6;3639:14;3636:34;;;3666:1;3663;3656:12;3636:34;3705:97;3794:7;3785:6;3774:9;3770:22;3705:97;:::i;:::-;3821:8;;-1:-1:-1;3679:123:9;-1:-1:-1;3909:2:9;3894:18;;3881:32;;-1:-1:-1;3925:16:9;;;3922:36;;;3954:1;3951;3944:12;3922:36;;3993:95;4080:7;4069:8;4058:9;4054:24;3993:95;:::i;:::-;3257:891;;;;-1:-1:-1;4107:8:9;-1:-1:-1;;;;3257:891:9:o;4153:219::-;4220:20;;4280:66;4269:78;;4259:89;;4249:117;;4362:1;4359;4352:12;4377:184;4435:6;4488:2;4476:9;4467:7;4463:23;4459:32;4456:52;;;4504:1;4501;4494:12;4456:52;4527:28;4545:9;4527:28;:::i;4566:481::-;4607:3;4645:5;4639:12;4672:6;4667:3;4660:19;4697:1;4707:162;4721:6;4718:1;4715:13;4707:162;;;4783:4;4839:13;;;4835:22;;4829:29;4811:11;;;4807:20;;4800:59;4736:12;4707:162;;;4711:3;4914:1;4907:4;4898:6;4893:3;4889:16;4885:27;4878:38;5036:4;4966:66;4961:2;4953:6;4949:15;4945:88;4940:3;4936:98;4932:109;4925:116;;;4566:481;;;;:::o;5052:298::-;5235:6;5228:14;5221:22;5210:9;5203:41;5280:2;5275;5264:9;5260:18;5253:30;5184:4;5300:44;5340:2;5329:9;5325:18;5317:6;5300:44;:::i;5355:162::-;5422:5;5467:2;5458:6;5453:3;5449:16;5445:25;5442:45;;;5483:1;5480;5473:12;5522:1405;5762:6;5770;5778;5786;5794;5802;5810;5818;5871:3;5859:9;5850:7;5846:23;5842:33;5839:53;;;5888:1;5885;5878:12;5839:53;5924:9;5911:23;5901:33;;5985:2;5974:9;5970:18;5957:32;6008:18;6049:2;6041:6;6038:14;6035:34;;;6065:1;6062;6055:12;6035:34;6104:97;6193:7;6184:6;6173:9;6169:22;6104:97;:::i;:::-;6220:8;;-1:-1:-1;6078:123:9;-1:-1:-1;6308:2:9;6293:18;;6280:32;;-1:-1:-1;6324:16:9;;;6321:36;;;6353:1;6350;6343:12;6321:36;6392:99;6483:7;6472:8;6461:9;6457:24;6392:99;:::i;:::-;6510:8;;-1:-1:-1;6366:125:9;-1:-1:-1;6598:2:9;6583:18;;6570:32;;-1:-1:-1;6614:16:9;;;6611:36;;;6643:1;6640;6633:12;6611:36;;6682:95;6769:7;6758:8;6747:9;6743:24;6682:95;:::i;:::-;6796:8;;-1:-1:-1;6656:121:9;-1:-1:-1;6850:71:9;;-1:-1:-1;6913:7:9;6907:3;6892:19;;6850:71;:::i;:::-;6840:81;;5522:1405;;;;;;;;;;;:::o;6932:196::-;7000:20;;7060:42;7049:54;;7039:65;;7029:93;;7118:1;7115;7108:12;7133:347;7184:8;7194:6;7248:3;7241:4;7233:6;7229:17;7225:27;7215:55;;7266:1;7263;7256:12;7215:55;-1:-1:-1;7289:20:9;;7332:18;7321:30;;7318:50;;;7364:1;7361;7354:12;7318:50;7401:4;7393:6;7389:17;7377:29;;7453:3;7446:4;7437:6;7429;7425:19;7421:30;7418:39;7415:59;;;7470:1;7467;7460:12;7485:620;7582:6;7590;7598;7606;7614;7667:3;7655:9;7646:7;7642:23;7638:33;7635:53;;;7684:1;7681;7674:12;7635:53;7720:9;7707:23;7697:33;;7749:38;7783:2;7772:9;7768:18;7749:38;:::i;:::-;7739:48;;7834:2;7823:9;7819:18;7806:32;7796:42;;7889:2;7878:9;7874:18;7861:32;7916:18;7908:6;7905:30;7902:50;;;7948:1;7945;7938:12;7902:50;7987:58;8037:7;8028:6;8017:9;8013:22;7987:58;:::i;:::-;7485:620;;;;-1:-1:-1;7485:620:9;;-1:-1:-1;8064:8:9;;7961:84;7485:620;-1:-1:-1;;;7485:620:9:o;8110:1996::-;8485:6;8493;8501;8509;8517;8525;8533;8541;8549;8557;8610:3;8598:9;8589:7;8585:23;8581:33;8578:53;;;8627:1;8624;8617:12;8578:53;8667:9;8654:23;8696:18;8737:2;8729:6;8726:14;8723:34;;;8753:1;8750;8743:12;8723:34;8792:97;8881:7;8872:6;8861:9;8857:22;8792:97;:::i;:::-;8908:8;;-1:-1:-1;8766:123:9;-1:-1:-1;8996:2:9;8981:18;;8968:32;;-1:-1:-1;9012:16:9;;;9009:36;;;9041:1;9038;9031:12;9009:36;9080:99;9171:7;9160:8;9149:9;9145:24;9080:99;:::i;:::-;9198:8;;-1:-1:-1;9054:125:9;-1:-1:-1;9286:2:9;9271:18;;9258:32;;-1:-1:-1;9302:16:9;;;9299:36;;;9331:1;9328;9321:12;9299:36;9370:99;9461:7;9450:8;9439:9;9435:24;9370:99;:::i;:::-;9488:8;;-1:-1:-1;9344:125:9;-1:-1:-1;9576:2:9;9561:18;;9548:32;;-1:-1:-1;9592:16:9;;;9589:36;;;9621:1;9618;9611:12;9589:36;9660:99;9751:7;9740:8;9729:9;9725:24;9660:99;:::i;:::-;9778:8;;-1:-1:-1;9634:125:9;-1:-1:-1;9866:3:9;9851:19;;9838:33;;-1:-1:-1;9883:16:9;;;9880:36;;;9912:1;9909;9902:12;9880:36;;9951:95;10038:7;10027:8;10016:9;10012:24;9951:95;:::i;:::-;9925:121;;10065:8;10055:18;;;10092:8;10082:18;;;8110:1996;;;;;;;;;;;;;:::o;10308:451::-;10416:6;10424;10477:2;10465:9;10456:7;10452:23;10448:32;10445:52;;;10493:1;10490;10483:12;10445:52;10529:9;10516:23;10506:33;;10590:2;10579:9;10575:18;10562:32;10617:18;10609:6;10606:30;10603:50;;;10649:1;10646;10639:12;10603:50;10672:81;10745:7;10736:6;10725:9;10721:22;10672:81;:::i;:::-;10662:91;;;10308:451;;;;;:::o;10764:186::-;10823:6;10876:2;10864:9;10855:7;10851:23;10847:32;10844:52;;;10892:1;10889;10882:12;10844:52;10915:29;10934:9;10915:29;:::i;11147:895::-;11278:6;11286;11294;11302;11310;11363:2;11351:9;11342:7;11338:23;11334:32;11331:52;;;11379:1;11376;11369:12;11331:52;11415:9;11402:23;11392:33;;11476:2;11465:9;11461:18;11448:32;11499:18;11540:2;11532:6;11529:14;11526:34;;;11556:1;11553;11546:12;11526:34;11595:97;11684:7;11675:6;11664:9;11660:22;11595:97;:::i;:::-;11711:8;;-1:-1:-1;11569:123:9;-1:-1:-1;11799:2:9;11784:18;;11771:32;;-1:-1:-1;11815:16:9;;;11812:36;;;11844:1;11841;11834:12;11812:36;;11883:99;11974:7;11963:8;11952:9;11948:24;11883:99;:::i;12047:180::-;12106:6;12159:2;12147:9;12138:7;12134:23;12130:32;12127:52;;;12175:1;12172;12165:12;12127:52;-1:-1:-1;12198:23:9;;12047:180;-1:-1:-1;12047:180:9:o;12414:943::-;12570:6;12578;12586;12594;12602;12610;12663:3;12651:9;12642:7;12638:23;12634:33;12631:53;;;12680:1;12677;12670:12;12631:53;12703:29;12722:9;12703:29;:::i;:::-;12693:39;;12779:2;12768:9;12764:18;12751:32;12741:42;;12834:2;12823:9;12819:18;12806:32;12857:18;12898:2;12890:6;12887:14;12884:34;;;12914:1;12911;12904:12;12884:34;12953:58;13003:7;12994:6;12983:9;12979:22;12953:58;:::i;:::-;13030:8;;-1:-1:-1;12927:84:9;-1:-1:-1;13118:2:9;13103:18;;13090:32;;-1:-1:-1;13134:16:9;;;13131:36;;;13163:1;13160;13153:12;13131:36;;13202:95;13289:7;13278:8;13267:9;13263:24;13202:95;:::i;:::-;12414:943;;;;-1:-1:-1;12414:943:9;;-1:-1:-1;12414:943:9;;13316:8;;12414:943;-1:-1:-1;;;12414:943:9:o;13362:500::-;13484:6;13492;13545:2;13533:9;13524:7;13520:23;13516:32;13513:52;;;13561:1;13558;13551:12;13513:52;13601:9;13588:23;13634:18;13626:6;13623:30;13620:50;;;13666:1;13663;13656:12;13620:50;13705:97;13794:7;13785:6;13774:9;13770:22;13705:97;:::i;:::-;13821:8;;13679:123;;-1:-1:-1;13362:500:9;-1:-1:-1;;;;13362:500:9:o;13867:551::-;13955:6;13963;13971;13979;14032:2;14020:9;14011:7;14007:23;14003:32;14000:52;;;14048:1;14045;14038:12;14000:52;14071:29;14090:9;14071:29;:::i;:::-;14061:39;;14147:2;14136:9;14132:18;14119:32;14109:42;;14202:2;14191:9;14187:18;14174:32;14229:18;14221:6;14218:30;14215:50;;;14261:1;14258;14251:12;14215:50;14300:58;14350:7;14341:6;14330:9;14326:22;14300:58;:::i;14423:699::-;14591:6;14599;14607;14615;14668:3;14656:9;14647:7;14643:23;14639:33;14636:53;;;14685:1;14682;14675:12;14636:53;14721:9;14708:23;14698:33;;14782:2;14771:9;14767:18;14754:32;14809:18;14801:6;14798:30;14795:50;;;14841:1;14838;14831:12;14795:50;14880:93;14965:7;14956:6;14945:9;14941:22;14880:93;:::i;:::-;14992:8;;-1:-1:-1;14854:119:9;-1:-1:-1;15046:70:9;;-1:-1:-1;15108:7:9;15103:2;15088:18;;15046:70;:::i;:::-;15036:80;;14423:699;;;;;;;:::o;15127:560::-;15254:6;15262;15270;15323:2;15311:9;15302:7;15298:23;15294:32;15291:52;;;15339:1;15336;15329:12;15291:52;15375:9;15362:23;15352:33;;15436:2;15425:9;15421:18;15408:32;15463:18;15455:6;15452:30;15449:50;;;15495:1;15492;15485:12;15449:50;15534:93;15619:7;15610:6;15599:9;15595:22;15534:93;:::i;15692:926::-;15913:6;15921;15929;15937;15990:2;15978:9;15969:7;15965:23;15961:32;15958:52;;;16006:1;16003;15996:12;15958:52;16046:9;16033:23;16075:18;16116:2;16108:6;16105:14;16102:34;;;16132:1;16129;16122:12;16102:34;16171:97;16260:7;16251:6;16240:9;16236:22;16171:97;:::i;:::-;16287:8;;-1:-1:-1;16145:123:9;-1:-1:-1;16375:2:9;16360:18;;16347:32;;-1:-1:-1;16391:16:9;;;16388:36;;;16420:1;16417;16410:12;16388:36;;16459:99;16550:7;16539:8;16528:9;16524:24;16459:99;:::i;16623:642::-;16707:6;16715;16723;16731;16784:2;16772:9;16763:7;16759:23;16755:32;16752:52;;;16800:1;16797;16790:12;16752:52;16823:28;16841:9;16823:28;:::i;:::-;16813:38;;16901:2;16890:9;16886:18;16873:32;16948:5;16941:13;16934:21;16927:5;16924:32;16914:60;;16970:1;16967;16960:12;16914:60;16993:5;-1:-1:-1;17049:2:9;17034:18;;17021:32;17076:18;17065:30;;17062:50;;;17108:1;17105;17098:12;17270:580;17347:4;17353:6;17413:11;17400:25;17503:66;17492:8;17476:14;17472:29;17468:102;17448:18;17444:127;17434:155;;17585:1;17582;17575:12;17434:155;17612:33;;17664:20;;;-1:-1:-1;17707:18:9;17696:30;;17693:50;;;17739:1;17736;17729:12;17693:50;17772:4;17760:17;;-1:-1:-1;17803:14:9;17799:27;;;17789:38;;17786:58;;;17840:1;17837;17830:12;17855:184;17907:77;17904:1;17897:88;18004:4;18001:1;17994:15;18028:4;18025:1;18018:15;18044:184;18096:77;18093:1;18086:88;18193:4;18190:1;18183:15;18217:4;18214:1;18207:15;18233:392;18335:4;18393:11;18380:25;18483:66;18472:8;18456:14;18452:29;18448:102;18428:18;18424:127;18414:155;;18565:1;18562;18555:12;18414:155;18586:33;;;;;18233:392;-1:-1:-1;;18233:392:9:o;18630:271::-;18813:6;18805;18800:3;18787:33;18769:3;18839:16;;18864:13;;;18839:16;18630:271;-1:-1:-1;18630:271:9:o;18906:217::-;19053:2;19042:9;19035:21;19016:4;19073:44;19113:2;19102:9;19098:18;19090:6;19073:44;:::i;19128:859::-;19288:4;19317:2;19357;19346:9;19342:18;19387:2;19376:9;19369:21;19410:6;19445;19439:13;19476:6;19468;19461:22;19514:2;19503:9;19499:18;19492:25;;19576:2;19566:6;19563:1;19559:14;19548:9;19544:30;19540:39;19526:53;;19614:2;19606:6;19602:15;19635:1;19645:313;19659:6;19656:1;19653:13;19645:313;;;19748:66;19736:9;19728:6;19724:22;19720:95;19715:3;19708:108;19839:39;19871:6;19862;19856:13;19839:39;:::i;:::-;19829:49;-1:-1:-1;19936:12:9;;;;19901:15;;;;19681:1;19674:9;19645:313;;;-1:-1:-1;19975:6:9;;19128:859;-1:-1:-1;;;;;;;19128:859:9:o;19992:472::-;20092:6;20087:3;20080:19;20062:3;20118:4;20147;20142:3;20138:14;20131:21;;20175:5;20198:1;20208:231;20222:6;20219:1;20216:13;20208:231;;;20315:42;20287:26;20306:6;20287:26;:::i;:::-;20283:75;20271:88;;20379:12;;;;20414:15;;;;20244:1;20237:9;20208:231;;;-1:-1:-1;20455:3:9;;19992:472;-1:-1:-1;;;;;19992:472:9:o;20469:706::-;20761:4;20790:10;20839:2;20831:6;20827:15;20816:9;20809:34;20891:2;20883:6;20879:15;20874:2;20863:9;20859:18;20852:43;;20931:3;20926:2;20915:9;20911:18;20904:31;20958:74;21027:3;21016:9;21012:19;21004:6;20996;20958:74;:::i;:::-;21080:9;21072:6;21068:22;21063:2;21052:9;21048:18;21041:50;21108:61;21162:6;21154;21146;21108:61;:::i;:::-;21100:69;20469:706;-1:-1:-1;;;;;;;;;20469:706:9:o;21180:604::-;21273:4;21279:6;21339:11;21326:25;21429:66;21418:8;21402:14;21398:29;21394:102;21374:18;21370:127;21360:155;;21511:1;21508;21501:12;21360:155;21538:33;;21590:20;;;-1:-1:-1;21633:18:9;21622:30;;21619:50;;;21665:1;21662;21655:12;21619:50;21698:4;21686:17;;-1:-1:-1;21749:1:9;21745:14;;;21729;21725:35;21715:46;;21712:66;;;21774:1;21771;21764:12;21789:639;21914:4;21920:6;21980:11;21967:25;22070:66;22059:8;22043:14;22039:29;22035:102;22015:18;22011:127;22001:155;;22152:1;22149;22142:12;22001:155;22179:33;;22231:20;;;-1:-1:-1;22274:18:9;22263:30;;22260:50;;;22306:1;22303;22296:12;22260:50;22339:4;22327:17;;-1:-1:-1;22398:4:9;22386:17;;22370:14;22366:38;22356:49;;22353:69;;;22418:1;22415;22408:12;22433:396;22539:4;22597:11;22584:25;22687:66;22676:8;22660:14;22656:29;22652:102;22632:18;22628:127;22618:155;;22769:1;22766;22759:12;22959:517;23060:2;23055:3;23052:11;23049:421;;;23096:5;23093:1;23086:16;23140:4;23137:1;23127:18;23210:2;23198:10;23194:19;23191:1;23187:27;23181:4;23177:38;23246:4;23234:10;23231:20;23228:47;;;-1:-1:-1;23269:4:9;23228:47;23324:2;23319:3;23315:12;23312:1;23308:20;23302:4;23298:31;23288:41;;23379:81;23397:2;23390:5;23387:13;23379:81;;;23456:1;23442:16;;23423:1;23412:13;23379:81;;23712:1460;23836:3;23830:10;23863:18;23855:6;23852:30;23849:56;;;23885:18;;:::i;:::-;23914:96;24003:6;23963:38;23995:4;23989:11;23963:38;:::i;:::-;23957:4;23914:96;:::i;:::-;24065:4;;24122:2;24111:14;;24139:1;24134:781;;;;24959:1;24976:6;24973:89;;;-1:-1:-1;25028:19:9;;;25022:26;24973:89;23618:66;23609:1;23605:11;;;23601:84;23597:89;23587:100;23693:1;23689:11;;;23584:117;25075:81;;24104:1062;;24134:781;22906:1;22899:14;;;22943:4;22930:18;;24182:66;24170:79;;;24346:236;24360:7;24357:1;24354:14;24346:236;;;24449:19;;;24443:26;24428:42;;24541:27;;;;24509:1;24497:14;;;;24376:19;;24346:236;;;24350:3;24610:6;24601:7;24598:19;24595:261;;;24671:19;;;24665:26;24772:66;24754:1;24750:14;;;24766:3;24746:24;24742:97;24738:102;24723:118;24708:134;;24595:261;-1:-1:-1;;;;;24902:1:9;24886:14;;;24882:22;24869:36;;-1:-1:-1;23712:1460:9:o;25177:528::-;25370:6;25363:14;25356:22;25345:9;25338:41;25415:2;25410;25399:9;25395:18;25388:30;25454:6;25449:2;25438:9;25434:18;25427:34;25511:6;25503;25498:2;25487:9;25483:18;25470:48;25567:1;25538:22;;;25562:2;25534:31;;;25527:42;;;;25621:2;25609:15;;;25626:66;25605:88;25590:104;25586:113;;25177:528;-1:-1:-1;;25177:528:9:o;27955:274::-;27995:1;28021;28011:189;;28056:77;28053:1;28046:88;28157:4;28154:1;28147:15;28185:4;28182:1;28175:15;28011:189;-1:-1:-1;28214:9:9;;27955:274::o;28961:282::-;29028:9;;;29049:11;;;29046:191;;;29093:77;29090:1;29083:88;29194:4;29191:1;29184:15;29222:4;29219:1;29212:15;29248:184;29300:77;29297:1;29290:88;29397:4;29394:1;29387:15;29421:4;29418:1;29411:15
Swarm Source
ipfs://434da885dc152cd4cb0609299995ad24e2c2f2552b77394f0a0b8fa3855bfd12
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.