Feature Tip: Add private address tag to any address under My Name Tag !
Source Code
Overview
ETH Balance
0 ETH
Eth Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Loading...
Loading
Loading...
Loading
Cross-Chain Transactions
Loading...
Loading
Contract Name:
ReallocatablePaymentSplitterUpgradeable
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/**
*Submitted for verification at Etherscan.io on 2023-05-13
*/
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
pragma solidity ^0.8.1;
/**
* @dev Collection of functions related to the address type
*/
library AddressUpgradeable {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
// OpenZeppelin Contracts (last updated v4.8.1) (proxy/utils/Initializable.sol)
/**
* @dev This is a base contract to aid in writing upgradeable contracts, or any kind of contract that will be deployed
* behind a proxy. Since proxied contracts do not make use of a constructor, it's common to move constructor logic to an
* external initializer function, usually called `initialize`. It then becomes necessary to protect this initializer
* function so it can only be called once. The {initializer} modifier provided by this contract will have this effect.
*
* The initialization functions use a version number. Once a version number is used, it is consumed and cannot be
* reused. This mechanism prevents re-execution of each "step" but allows the creation of new initialization steps in
* case an upgrade adds a module that needs to be initialized.
*
* For example:
*
* [.hljs-theme-light.nopadding]
* ```
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev Indicates that the contract has been initialized.
* @custom:oz-retyped-from bool
*/
uint8 private _initialized;
/**
* @dev Indicates that the contract is in the process of being initialized.
*/
bool private _initializing;
/**
* @dev Triggered when the contract has been initialized or reinitialized.
*/
event Initialized(uint8 version);
/**
* @dev A modifier that defines a protected initializer function that can be invoked at most once. In its scope,
* `onlyInitializing` functions can be used to initialize parent contracts.
*
* Similar to `reinitializer(1)`, except that functions marked with `initializer` can be nested in the context of a
* constructor.
*
* Emits an {Initialized} event.
*/
modifier initializer() {
bool isTopLevelCall = !_initializing;
require(
(isTopLevelCall && _initialized < 1) || (!AddressUpgradeable.isContract(address(this)) && _initialized == 1),
"Initializable: contract is already initialized"
);
_initialized = 1;
if (isTopLevelCall) {
_initializing = true;
}
_;
if (isTopLevelCall) {
_initializing = false;
emit Initialized(1);
}
}
/**
* @dev A modifier that defines a protected reinitializer function that can be invoked at most once, and only if the
* contract hasn't been initialized to a greater version before. In its scope, `onlyInitializing` functions can be
* used to initialize parent contracts.
*
* A reinitializer may be used after the original initialization step. This is essential to configure modules that
* are added through upgrades and that require initialization.
*
* When `version` is 1, this modifier is similar to `initializer`, except that functions marked with `reinitializer`
* cannot be nested. If one is invoked in the context of another, execution will revert.
*
* Note that versions can jump in increments greater than 1; this implies that if multiple reinitializers coexist in
* a contract, executing them in the right order is up to the developer or operator.
*
* WARNING: setting the version to 255 will prevent any future reinitialization.
*
* Emits an {Initialized} event.
*/
modifier reinitializer(uint8 version) {
require(!_initializing && _initialized < version, "Initializable: contract is already initialized");
_initialized = version;
_initializing = true;
_;
_initializing = false;
emit Initialized(version);
}
/**
* @dev Modifier to protect an initialization function so that it can only be invoked by functions with the
* {initializer} and {reinitializer} modifiers, directly or indirectly.
*/
modifier onlyInitializing() {
require(_initializing, "Initializable: contract is not initializing");
_;
}
/**
* @dev Locks the contract, preventing any future reinitialization. This cannot be part of an initializer call.
* Calling this in the constructor of a contract will prevent that contract from being initialized or reinitialized
* to any version. It is recommended to use this to lock implementation contracts that are designed to be called
* through proxies.
*
* Emits an {Initialized} event the first time it is successfully executed.
*/
function _disableInitializers() internal virtual {
require(!_initializing, "Initializable: contract is initializing");
if (_initialized < type(uint8).max) {
_initialized = type(uint8).max;
emit Initialized(type(uint8).max);
}
}
/**
* @dev Returns the highest version that has been initialized. See {reinitializer}.
*/
function _getInitializedVersion() internal view returns (uint8) {
return _initialized;
}
/**
* @dev Returns `true` if the contract is currently initializing. See {onlyInitializing}.
*/
function _isInitializing() internal view returns (bool) {
return _initializing;
}
}
// OpenZeppelin Contracts (last updated v4.8.0) (finance/PaymentSplitter.sol)
// OpenZeppelin Contracts (last updated v4.8.0) (finance/PaymentSplitter.sol)
// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/utils/SafeERC20.sol)
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC20/IERC20.sol)
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20Upgradeable {
/**
* @dev Emitted when `value` tokens are moved from one account (`from`) to
* another (`to`).
*
* Note that `value` may be zero.
*/
event Transfer(address indexed from, address indexed to, uint256 value);
/**
* @dev Emitted when the allowance of a `spender` for an `owner` is set by
* a call to {approve}. `value` is the new allowance.
*/
event Approval(address indexed owner, address indexed spender, uint256 value);
/**
* @dev Returns the amount of tokens in existence.
*/
function totalSupply() external view returns (uint256);
/**
* @dev Returns the amount of tokens owned by `account`.
*/
function balanceOf(address account) external view returns (uint256);
/**
* @dev Moves `amount` tokens from the caller's account to `to`.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transfer(address to, uint256 amount) external returns (bool);
/**
* @dev Returns the remaining number of tokens that `spender` will be
* allowed to spend on behalf of `owner` through {transferFrom}. This is
* zero by default.
*
* This value changes when {approve} or {transferFrom} are called.
*/
function allowance(address owner, address spender) external view returns (uint256);
/**
* @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* IMPORTANT: Beware that changing an allowance with this method brings the risk
* that someone may use both the old and the new allowance by unfortunate
* transaction ordering. One possible solution to mitigate this race
* condition is to first reduce the spender's allowance to 0 and set the
* desired value afterwards:
* https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
*
* Emits an {Approval} event.
*/
function approve(address spender, uint256 amount) external returns (bool);
/**
* @dev Moves `amount` tokens from `from` to `to` using the
* allowance mechanism. `amount` is then deducted from the caller's
* allowance.
*
* Returns a boolean value indicating whether the operation succeeded.
*
* Emits a {Transfer} event.
*/
function transferFrom(
address from,
address to,
uint256 amount
) external returns (bool);
}
// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-IERC20Permit.sol)
/**
* @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*/
interface IERC20PermitUpgradeable {
/**
* @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
* given ``owner``'s signed approval.
*
* IMPORTANT: The same issues {IERC20-approve} has related to transaction
* ordering also apply here.
*
* Emits an {Approval} event.
*
* Requirements:
*
* - `spender` cannot be the zero address.
* - `deadline` must be a timestamp in the future.
* - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
* over the EIP712-formatted function arguments.
* - the signature must use ``owner``'s current nonce (see {nonces}).
*
* For more information on the signature format, see the
* https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
* section].
*/
function permit(
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) external;
/**
* @dev Returns the current nonce for `owner`. This value must be
* included whenever a signature is generated for {permit}.
*
* Every successful call to {permit} increases ``owner``'s nonce by one. This
* prevents a signature from being used multiple times.
*/
function nonces(address owner) external view returns (uint256);
/**
* @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
*/
// solhint-disable-next-line func-name-mixedcase
function DOMAIN_SEPARATOR() external view returns (bytes32);
}
/**
* @title SafeERC20
* @dev Wrappers around ERC20 operations that throw on failure (when the token
* contract returns false). Tokens that return no value (and instead revert or
* throw on failure) are also supported, non-reverting calls are assumed to be
* successful.
* To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
* which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
*/
library SafeERC20Upgradeable {
using AddressUpgradeable for address;
function safeTransfer(
IERC20Upgradeable token,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
function safeTransferFrom(
IERC20Upgradeable token,
address from,
address to,
uint256 value
) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value));
}
/**
* @dev Deprecated. This function has issues similar to the ones found in
* {IERC20-approve}, and its usage is discouraged.
*
* Whenever possible, use {safeIncreaseAllowance} and
* {safeDecreaseAllowance} instead.
*/
function safeApprove(
IERC20Upgradeable token,
address spender,
uint256 value
) internal {
// safeApprove should only be called when setting an initial allowance,
// or when resetting it to zero. To increase and decrease it, use
// 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
require(
(value == 0) || (token.allowance(address(this), spender) == 0),
"SafeERC20: approve from non-zero to non-zero allowance"
);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value));
}
function safeIncreaseAllowance(
IERC20Upgradeable token,
address spender,
uint256 value
) internal {
uint256 newAllowance = token.allowance(address(this), spender) + value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
function safeDecreaseAllowance(
IERC20Upgradeable token,
address spender,
uint256 value
) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
uint256 newAllowance = oldAllowance - value;
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
}
}
function safePermit(
IERC20PermitUpgradeable token,
address owner,
address spender,
uint256 value,
uint256 deadline,
uint8 v,
bytes32 r,
bytes32 s
) internal {
uint256 nonceBefore = token.nonces(owner);
token.permit(owner, spender, value, deadline, v, r, s);
uint256 nonceAfter = token.nonces(owner);
require(nonceAfter == nonceBefore + 1, "SafeERC20: permit did not succeed");
}
/**
* @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
* on the return value: the return value is optional (but if data is returned, it must not be false).
* @param token The token targeted by the call.
* @param data The call data (encoded using abi.encode or one of its variants).
*/
function _callOptionalReturn(IERC20Upgradeable token, bytes memory data) private {
// We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
// we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that
// the target address contains contract code and also asserts for success in the low-level call.
bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed");
if (returndata.length > 0) {
// Return data is optional
require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
}
}
}
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal onlyInitializing {
}
function __Context_init_unchained() internal onlyInitializing {
}
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[50] private __gap;
}
/**
* @title PaymentSplitter
* @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
* that the Ether will be split in this way, since it is handled transparently by the contract.
*
* The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
* account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
* an amount proportional to the percentage of total shares they were assigned. The distribution of shares is set at the
* time of contract deployment and can't be updated thereafter.
*
* `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
* accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
* function.
*
* NOTE: This contract assumes that ERC20 tokens will behave similarly to native tokens (Ether). Rebasing tokens, and
* tokens that apply fees during transfers, are likely to not be supported as expected. If in doubt, we encourage you
* to run tests before sending real value to this contract.
*/
contract PaymentSplitterUpgradeable is Initializable, ContextUpgradeable {
event PayeeAdded(address account, uint256 shares);
event PaymentReleased(address to, uint256 amount);
event ERC20PaymentReleased(IERC20Upgradeable indexed token, address to, uint256 amount);
event PaymentReceived(address from, uint256 amount);
uint256 private _totalShares;
uint256 private _totalReleased;
mapping(address => uint256) private _shares;
mapping(address => uint256) private _released;
address[] private _payees;
mapping(IERC20Upgradeable => uint256) private _erc20TotalReleased;
mapping(IERC20Upgradeable => mapping(address => uint256)) private _erc20Released;
/**
* @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
* the matching position in the `shares` array.
*
* All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
* duplicates in `payees`.
*/
function __PaymentSplitter_init(address[] memory payees, uint256[] memory shares_) internal onlyInitializing {
__PaymentSplitter_init_unchained(payees, shares_);
}
function __PaymentSplitter_init_unchained(address[] memory payees, uint256[] memory shares_) internal onlyInitializing {
require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
require(payees.length > 0, "PaymentSplitter: no payees");
for (uint256 i = 0; i < payees.length; i++) {
_addPayee(payees[i], shares_[i]);
}
}
/**
* @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
* reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
* reliability of the events, and not the actual splitting of Ether.
*
* To learn more about this see the Solidity documentation for
* https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
* functions].
*/
receive() external payable virtual {
emit PaymentReceived(_msgSender(), msg.value);
}
/**
* @dev Getter for the total shares held by payees.
*/
function totalShares() public view returns (uint256) {
return _totalShares;
}
/**
* @dev Getter for the total amount of Ether already released.
*/
function totalReleased() public view returns (uint256) {
return _totalReleased;
}
/**
* @dev Getter for the total amount of `token` already released. `token` should be the address of an IERC20
* contract.
*/
function totalReleased(IERC20Upgradeable token) public view returns (uint256) {
return _erc20TotalReleased[token];
}
/**
* @dev Getter for the amount of shares held by an account.
*/
function shares(address account) public view returns (uint256) {
return _shares[account];
}
/**
* @dev Getter for the amount of Ether already released to a payee.
*/
function released(address account) public view returns (uint256) {
return _released[account];
}
/**
* @dev Getter for the amount of `token` tokens already released to a payee. `token` should be the address of an
* IERC20 contract.
*/
function released(IERC20Upgradeable token, address account) public view returns (uint256) {
return _erc20Released[token][account];
}
/**
* @dev Getter for the address of the payee number `index`.
*/
function payee(uint256 index) public view returns (address) {
return _payees[index];
}
/**
* @dev Getter for the amount of payee's releasable Ether.
*/
function releasable(address account) public view returns (uint256) {
uint256 totalReceived = address(this).balance + totalReleased();
return _pendingPayment(account, totalReceived, released(account));
}
/**
* @dev Getter for the amount of payee's releasable `token` tokens. `token` should be the address of an
* IERC20 contract.
*/
function releasable(IERC20Upgradeable token, address account) public view returns (uint256) {
uint256 totalReceived = token.balanceOf(address(this)) + totalReleased(token);
return _pendingPayment(account, totalReceived, released(token, account));
}
/**
* @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
* total shares and their previous withdrawals.
*/
function release(address payable account) public virtual {
require(_shares[account] > 0, "PaymentSplitter: account has no shares");
uint256 payment = releasable(account);
require(payment != 0, "PaymentSplitter: account is not due payment");
// _totalReleased is the sum of all values in _released.
// If "_totalReleased += payment" does not overflow, then "_released[account] += payment" cannot overflow.
_totalReleased += payment;
unchecked {
_released[account] += payment;
}
AddressUpgradeable.sendValue(account, payment);
emit PaymentReleased(account, payment);
}
/**
* @dev Triggers a transfer to `account` of the amount of `token` tokens they are owed, according to their
* percentage of the total shares and their previous withdrawals. `token` must be the address of an IERC20
* contract.
*/
function release(IERC20Upgradeable token, address account) public virtual {
require(_shares[account] > 0, "PaymentSplitter: account has no shares");
uint256 payment = releasable(token, account);
require(payment != 0, "PaymentSplitter: account is not due payment");
// _erc20TotalReleased[token] is the sum of all values in _erc20Released[token].
// If "_erc20TotalReleased[token] += payment" does not overflow, then "_erc20Released[token][account] += payment"
// cannot overflow.
_erc20TotalReleased[token] += payment;
unchecked {
_erc20Released[token][account] += payment;
}
SafeERC20Upgradeable.safeTransfer(token, account, payment);
emit ERC20PaymentReleased(token, account, payment);
}
/**
* @dev internal logic for computing the pending payment of an `account` given the token historical balances and
* already released amounts.
*/
function _pendingPayment(
address account,
uint256 totalReceived,
uint256 alreadyReleased
) private view returns (uint256) {
return (totalReceived * _shares[account]) / _totalShares - alreadyReleased;
}
/**
* @dev Add a new payee to the contract.
* @param account The address of the payee to add.
* @param shares_ The number of shares owned by the payee.
*/
function _addPayee(address account, uint256 shares_) private {
require(account != address(0), "PaymentSplitter: account is the zero address");
require(shares_ > 0, "PaymentSplitter: shares are 0");
require(_shares[account] == 0, "PaymentSplitter: account already has shares");
_payees.push(account);
_shares[account] = shares_;
_totalShares = _totalShares + shares_;
emit PayeeAdded(account, shares_);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[43] private __gap;
}
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract OwnableUpgradeable is Initializable, ContextUpgradeable {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
function __Ownable_init() internal onlyInitializing {
__Ownable_init_unchained();
}
function __Ownable_init_unchained() internal onlyInitializing {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
/**
* @dev This empty reserved space is put in place to allow future versions to add new
* variables without shifting down storage in the inheritance chain.
* See https://docs.openzeppelin.com/contracts/4.x/upgradeable#storage_gaps
*/
uint256[49] private __gap;
}
// Following line is a dummy import, otherwise TUP would not be compiled
// OpenZeppelin Contracts (last updated v4.8.3) (proxy/transparent/TransparentUpgradeableProxy.sol)
// OpenZeppelin Contracts (last updated v4.7.0) (proxy/ERC1967/ERC1967Proxy.sol)
// OpenZeppelin Contracts (last updated v4.6.0) (proxy/Proxy.sol)
/**
* @dev This abstract contract provides a fallback function that delegates all calls to another contract using the EVM
* instruction `delegatecall`. We refer to the second contract as the _implementation_ behind the proxy, and it has to
* be specified by overriding the virtual {_implementation} function.
*
* Additionally, delegation to the implementation can be triggered manually through the {_fallback} function, or to a
* different contract through the {_delegate} function.
*
* The success and return data of the delegated call will be returned back to the caller of the proxy.
*/
abstract contract Proxy {
/**
* @dev Delegates the current call to `implementation`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _delegate(address implementation) internal virtual {
assembly {
// Copy msg.data. We take full control of memory in this inline assembly
// block because it will not return to Solidity code. We overwrite the
// Solidity scratch pad at memory position 0.
calldatacopy(0, 0, calldatasize())
// Call the implementation.
// out and outsize are 0 because we don't know the size yet.
let result := delegatecall(gas(), implementation, 0, calldatasize(), 0, 0)
// Copy the returned data.
returndatacopy(0, 0, returndatasize())
switch result
// delegatecall returns 0 on error.
case 0 {
revert(0, returndatasize())
}
default {
return(0, returndatasize())
}
}
}
/**
* @dev This is a virtual function that should be overridden so it returns the address to which the fallback function
* and {_fallback} should delegate.
*/
function _implementation() internal view virtual returns (address);
/**
* @dev Delegates the current call to the address returned by `_implementation()`.
*
* This function does not return to its internal call site, it will return directly to the external caller.
*/
function _fallback() internal virtual {
_beforeFallback();
_delegate(_implementation());
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if no other
* function in the contract matches the call data.
*/
fallback() external payable virtual {
_fallback();
}
/**
* @dev Fallback function that delegates calls to the address returned by `_implementation()`. Will run if call data
* is empty.
*/
receive() external payable virtual {
_fallback();
}
/**
* @dev Hook that is called before falling back to the implementation. Can happen as part of a manual `_fallback`
* call, or as part of the Solidity `fallback` or `receive` functions.
*
* If overridden should call `super._beforeFallback()`.
*/
function _beforeFallback() internal virtual {}
}
// OpenZeppelin Contracts (last updated v4.8.3) (proxy/ERC1967/ERC1967Upgrade.sol)
// OpenZeppelin Contracts v4.4.1 (proxy/beacon/IBeacon.sol)
/**
* @dev This is the interface that {BeaconProxy} expects of its beacon.
*/
interface IBeacon {
/**
* @dev Must return an address that can be used as a delegate call target.
*
* {BeaconProxy} will check that this address is a contract.
*/
function implementation() external view returns (address);
}
// OpenZeppelin Contracts (last updated v4.8.3) (interfaces/IERC1967.sol)
/**
* @dev ERC-1967: Proxy Storage Slots. This interface contains the events defined in the ERC.
*
* _Available since v4.9._
*/
interface IERC1967 {
/**
* @dev Emitted when the implementation is upgraded.
*/
event Upgraded(address indexed implementation);
/**
* @dev Emitted when the admin account has changed.
*/
event AdminChanged(address previousAdmin, address newAdmin);
/**
* @dev Emitted when the beacon is changed.
*/
event BeaconUpgraded(address indexed beacon);
}
// OpenZeppelin Contracts (last updated v4.5.0) (interfaces/draft-IERC1822.sol)
/**
* @dev ERC1822: Universal Upgradeable Proxy Standard (UUPS) documents a method for upgradeability through a simplified
* proxy whose upgrades are fully controlled by the current implementation.
*/
interface IERC1822Proxiable {
/**
* @dev Returns the storage slot that the proxiable contract assumes is being used to store the implementation
* address.
*
* IMPORTANT: A proxy pointing at a proxiable contract should not be considered proxiable itself, because this risks
* bricking a proxy that upgrades to it, by delegating to itself until out of gas. Thus it is critical that this
* function revert if invoked through a proxy.
*/
function proxiableUUID() external view returns (bytes32);
}
// OpenZeppelin Contracts (last updated v4.8.0) (utils/Address.sol)
/**
* @dev Collection of functions related to the address type
*/
library Address {
/**
* @dev Returns true if `account` is a contract.
*
* [IMPORTANT]
* ====
* It is unsafe to assume that an address for which this function returns
* false is an externally-owned account (EOA) and not a contract.
*
* Among others, `isContract` will return false for the following
* types of addresses:
*
* - an externally-owned account
* - a contract in construction
* - an address where a contract will be created
* - an address where a contract lived, but was destroyed
* ====
*
* [IMPORTANT]
* ====
* You shouldn't rely on `isContract` to protect against flash loan attacks!
*
* Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
* like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
* constructor.
* ====
*/
function isContract(address account) internal view returns (bool) {
// This method relies on extcodesize/address.code.length, which returns 0
// for contracts in construction, since the code is only stored at the end
// of the constructor execution.
return account.code.length > 0;
}
/**
* @dev Replacement for Solidity's `transfer`: sends `amount` wei to
* `recipient`, forwarding all available gas and reverting on errors.
*
* https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
* of certain opcodes, possibly making contracts go over the 2300 gas limit
* imposed by `transfer`, making them unable to receive funds via
* `transfer`. {sendValue} removes this limitation.
*
* https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
*
* IMPORTANT: because control is transferred to `recipient`, care must be
* taken to not create reentrancy vulnerabilities. Consider using
* {ReentrancyGuard} or the
* https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
*/
function sendValue(address payable recipient, uint256 amount) internal {
require(address(this).balance >= amount, "Address: insufficient balance");
(bool success, ) = recipient.call{value: amount}("");
require(success, "Address: unable to send value, recipient may have reverted");
}
/**
* @dev Performs a Solidity function call using a low level `call`. A
* plain `call` is an unsafe replacement for a function call: use this
* function instead.
*
* If `target` reverts with a revert reason, it is bubbled up by this
* function (like regular Solidity function calls).
*
* Returns the raw returned data. To convert to the expected return value,
* use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
*
* Requirements:
*
* - `target` must be a contract.
* - calling `target` with `data` must not revert.
*
* _Available since v3.1._
*/
function functionCall(address target, bytes memory data) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, "Address: low-level call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
* `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
return functionCallWithValue(target, data, 0, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but also transferring `value` wei to `target`.
*
* Requirements:
*
* - the calling contract must have an ETH balance of at least `value`.
* - the called Solidity function must be `payable`.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value
) internal returns (bytes memory) {
return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
}
/**
* @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
* with `errorMessage` as a fallback revert reason when `target` reverts.
*
* _Available since v3.1._
*/
function functionCallWithValue(
address target,
bytes memory data,
uint256 value,
string memory errorMessage
) internal returns (bytes memory) {
require(address(this).balance >= value, "Address: insufficient balance for call");
(bool success, bytes memory returndata) = target.call{value: value}(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
return functionStaticCall(target, data, "Address: low-level static call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a static call.
*
* _Available since v3.3._
*/
function functionStaticCall(
address target,
bytes memory data,
string memory errorMessage
) internal view returns (bytes memory) {
(bool success, bytes memory returndata) = target.staticcall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
return functionDelegateCall(target, data, "Address: low-level delegate call failed");
}
/**
* @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
* but performing a delegate call.
*
* _Available since v3.4._
*/
function functionDelegateCall(
address target,
bytes memory data,
string memory errorMessage
) internal returns (bytes memory) {
(bool success, bytes memory returndata) = target.delegatecall(data);
return verifyCallResultFromTarget(target, success, returndata, errorMessage);
}
/**
* @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
* the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
*
* _Available since v4.8._
*/
function verifyCallResultFromTarget(
address target,
bool success,
bytes memory returndata,
string memory errorMessage
) internal view returns (bytes memory) {
if (success) {
if (returndata.length == 0) {
// only check isContract if the call was successful and the return data is empty
// otherwise we already know that it was a contract
require(isContract(target), "Address: call to non-contract");
}
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
/**
* @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
* revert reason or using the provided one.
*
* _Available since v4.3._
*/
function verifyCallResult(
bool success,
bytes memory returndata,
string memory errorMessage
) internal pure returns (bytes memory) {
if (success) {
return returndata;
} else {
_revert(returndata, errorMessage);
}
}
function _revert(bytes memory returndata, string memory errorMessage) private pure {
// Look for revert reason and bubble it up if present
if (returndata.length > 0) {
// The easiest way to bubble the revert reason is using memory via assembly
/// @solidity memory-safe-assembly
assembly {
let returndata_size := mload(returndata)
revert(add(32, returndata), returndata_size)
}
} else {
revert(errorMessage);
}
}
}
// OpenZeppelin Contracts (last updated v4.7.0) (utils/StorageSlot.sol)
/**
* @dev Library for reading and writing primitive types to specific storage slots.
*
* Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
* This library helps with reading and writing to such slots without the need for inline assembly.
*
* The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
*
* Example usage to set ERC1967 implementation slot:
* ```
* contract ERC1967 {
* bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
*
* function _getImplementation() internal view returns (address) {
* return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
* }
*
* function _setImplementation(address newImplementation) internal {
* require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
* StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
* }
* }
* ```
*
* _Available since v4.1 for `address`, `bool`, `bytes32`, and `uint256`._
*/
library StorageSlot {
struct AddressSlot {
address value;
}
struct BooleanSlot {
bool value;
}
struct Bytes32Slot {
bytes32 value;
}
struct Uint256Slot {
uint256 value;
}
/**
* @dev Returns an `AddressSlot` with member `value` located at `slot`.
*/
function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `BooleanSlot` with member `value` located at `slot`.
*/
function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
*/
function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
/**
* @dev Returns an `Uint256Slot` with member `value` located at `slot`.
*/
function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
/// @solidity memory-safe-assembly
assembly {
r.slot := slot
}
}
}
/**
* @dev This abstract contract provides getters and event emitting update functions for
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967] slots.
*
* _Available since v4.1._
*
* @custom:oz-upgrades-unsafe-allow delegatecall
*/
abstract contract ERC1967Upgrade is IERC1967 {
// This is the keccak-256 hash of "eip1967.proxy.rollback" subtracted by 1
bytes32 private constant _ROLLBACK_SLOT = 0x4910fdfa16fed3260ed0e7147f7cc6da11a60208b5b9406d12a635614ffd9143;
/**
* @dev Storage slot with the address of the current implementation.
* This is the keccak-256 hash of "eip1967.proxy.implementation" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
/**
* @dev Returns the current implementation address.
*/
function _getImplementation() internal view returns (address) {
return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 implementation slot.
*/
function _setImplementation(address newImplementation) private {
require(Address.isContract(newImplementation), "ERC1967: new implementation is not a contract");
StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
}
/**
* @dev Perform implementation upgrade
*
* Emits an {Upgraded} event.
*/
function _upgradeTo(address newImplementation) internal {
_setImplementation(newImplementation);
emit Upgraded(newImplementation);
}
/**
* @dev Perform implementation upgrade with additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCall(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
_upgradeTo(newImplementation);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(newImplementation, data);
}
}
/**
* @dev Perform implementation upgrade with security checks for UUPS proxies, and additional setup call.
*
* Emits an {Upgraded} event.
*/
function _upgradeToAndCallUUPS(
address newImplementation,
bytes memory data,
bool forceCall
) internal {
// Upgrades from old implementations will perform a rollback test. This test requires the new
// implementation to upgrade back to the old, non-ERC1822 compliant, implementation. Removing
// this special case will break upgrade paths from old UUPS implementation to new ones.
if (StorageSlot.getBooleanSlot(_ROLLBACK_SLOT).value) {
_setImplementation(newImplementation);
} else {
try IERC1822Proxiable(newImplementation).proxiableUUID() returns (bytes32 slot) {
require(slot == _IMPLEMENTATION_SLOT, "ERC1967Upgrade: unsupported proxiableUUID");
} catch {
revert("ERC1967Upgrade: new implementation is not UUPS");
}
_upgradeToAndCall(newImplementation, data, forceCall);
}
}
/**
* @dev Storage slot with the admin of the contract.
* This is the keccak-256 hash of "eip1967.proxy.admin" subtracted by 1, and is
* validated in the constructor.
*/
bytes32 internal constant _ADMIN_SLOT = 0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103;
/**
* @dev Returns the current admin.
*/
function _getAdmin() internal view returns (address) {
return StorageSlot.getAddressSlot(_ADMIN_SLOT).value;
}
/**
* @dev Stores a new address in the EIP1967 admin slot.
*/
function _setAdmin(address newAdmin) private {
require(newAdmin != address(0), "ERC1967: new admin is the zero address");
StorageSlot.getAddressSlot(_ADMIN_SLOT).value = newAdmin;
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _changeAdmin(address newAdmin) internal {
emit AdminChanged(_getAdmin(), newAdmin);
_setAdmin(newAdmin);
}
/**
* @dev The storage slot of the UpgradeableBeacon contract which defines the implementation for this proxy.
* This is bytes32(uint256(keccak256('eip1967.proxy.beacon')) - 1)) and is validated in the constructor.
*/
bytes32 internal constant _BEACON_SLOT = 0xa3f0ad74e5423aebfd80d3ef4346578335a9a72aeaee59ff6cb3582b35133d50;
/**
* @dev Returns the current beacon.
*/
function _getBeacon() internal view returns (address) {
return StorageSlot.getAddressSlot(_BEACON_SLOT).value;
}
/**
* @dev Stores a new beacon in the EIP1967 beacon slot.
*/
function _setBeacon(address newBeacon) private {
require(Address.isContract(newBeacon), "ERC1967: new beacon is not a contract");
require(
Address.isContract(IBeacon(newBeacon).implementation()),
"ERC1967: beacon implementation is not a contract"
);
StorageSlot.getAddressSlot(_BEACON_SLOT).value = newBeacon;
}
/**
* @dev Perform beacon upgrade with additional setup call. Note: This upgrades the address of the beacon, it does
* not upgrade the implementation contained in the beacon (see {UpgradeableBeacon-_setImplementation} for that).
*
* Emits a {BeaconUpgraded} event.
*/
function _upgradeBeaconToAndCall(
address newBeacon,
bytes memory data,
bool forceCall
) internal {
_setBeacon(newBeacon);
emit BeaconUpgraded(newBeacon);
if (data.length > 0 || forceCall) {
Address.functionDelegateCall(IBeacon(newBeacon).implementation(), data);
}
}
}
/**
* @dev This contract implements an upgradeable proxy. It is upgradeable because calls are delegated to an
* implementation address that can be changed. This address is stored in storage in the location specified by
* https://eips.ethereum.org/EIPS/eip-1967[EIP1967], so that it doesn't conflict with the storage layout of the
* implementation behind the proxy.
*/
contract ERC1967Proxy is Proxy, ERC1967Upgrade {
/**
* @dev Initializes the upgradeable proxy with an initial implementation specified by `_logic`.
*
* If `_data` is nonempty, it's used as data in a delegate call to `_logic`. This will typically be an encoded
* function call, and allows initializing the storage of the proxy like a Solidity constructor.
*/
constructor(address _logic, bytes memory _data) payable {
_upgradeToAndCall(_logic, _data, false);
}
/**
* @dev Returns the current implementation address.
*/
function _implementation() internal view virtual override returns (address impl) {
return ERC1967Upgrade._getImplementation();
}
}
/**
* @dev Interface for {TransparentUpgradeableProxy}. In order to implement transparency, {TransparentUpgradeableProxy}
* does not implement this interface directly, and some of its functions are implemented by an internal dispatch
* mechanism. The compiler is unaware that these functions are implemented by {TransparentUpgradeableProxy} and will not
* include them in the ABI so this interface must be used to interact with it.
*/
interface ITransparentUpgradeableProxy is IERC1967 {
function admin() external view returns (address);
function implementation() external view returns (address);
function changeAdmin(address) external;
function upgradeTo(address) external;
function upgradeToAndCall(address, bytes memory) external payable;
}
/**
* @dev This contract implements a proxy that is upgradeable by an admin.
*
* To avoid https://medium.com/nomic-labs-blog/malicious-backdoors-in-ethereum-proxies-62629adf3357[proxy selector
* clashing], which can potentially be used in an attack, this contract uses the
* https://blog.openzeppelin.com/the-transparent-proxy-pattern/[transparent proxy pattern]. This pattern implies two
* things that go hand in hand:
*
* 1. If any account other than the admin calls the proxy, the call will be forwarded to the implementation, even if
* that call matches one of the admin functions exposed by the proxy itself.
* 2. If the admin calls the proxy, it can access the admin functions, but its calls will never be forwarded to the
* implementation. If the admin tries to call a function on the implementation it will fail with an error that says
* "admin cannot fallback to proxy target".
*
* These properties mean that the admin account can only be used for admin actions like upgrading the proxy or changing
* the admin, so it's best if it's a dedicated account that is not used for anything else. This will avoid headaches due
* to sudden errors when trying to call a function from the proxy implementation.
*
* Our recommendation is for the dedicated account to be an instance of the {ProxyAdmin} contract. If set up this way,
* you should think of the `ProxyAdmin` instance as the real administrative interface of your proxy.
*
* NOTE: The real interface of this proxy is that defined in `ITransparentUpgradeableProxy`. This contract does not
* inherit from that interface, and instead the admin functions are implicitly implemented using a custom dispatch
* mechanism in `_fallback`. Consequently, the compiler will not produce an ABI for this contract. This is necessary to
* fully implement transparency without decoding reverts caused by selector clashes between the proxy and the
* implementation.
*
* WARNING: It is not recommended to extend this contract to add additional external functions. If you do so, the compiler
* will not check that there are no selector conflicts, due to the note above. A selector clash between any new function
* and the functions declared in {ITransparentUpgradeableProxy} will be resolved in favor of the new one. This could
* render the admin operations inaccessible, which could prevent upgradeability. Transparency may also be compromised.
*/
contract TransparentUpgradeableProxy is ERC1967Proxy {
/**
* @dev Initializes an upgradeable proxy managed by `_admin`, backed by the implementation at `_logic`, and
* optionally initialized with `_data` as explained in {ERC1967Proxy-constructor}.
*/
constructor(
address _logic,
address admin_,
bytes memory _data
) payable ERC1967Proxy(_logic, _data) {
_changeAdmin(admin_);
}
/**
* @dev Modifier used internally that will delegate the call to the implementation unless the sender is the admin.
*
* CAUTION: This modifier is deprecated, as it could cause issues if the modified function has arguments, and the
* implementation provides a function with the same selector.
*/
modifier ifAdmin() {
if (msg.sender == _getAdmin()) {
_;
} else {
_fallback();
}
}
/**
* @dev If caller is the admin process the call internally, otherwise transparently fallback to the proxy behavior
*/
function _fallback() internal virtual override {
if (msg.sender == _getAdmin()) {
bytes memory ret;
bytes4 selector = msg.sig;
if (selector == ITransparentUpgradeableProxy.upgradeTo.selector) {
ret = _dispatchUpgradeTo();
} else if (selector == ITransparentUpgradeableProxy.upgradeToAndCall.selector) {
ret = _dispatchUpgradeToAndCall();
} else if (selector == ITransparentUpgradeableProxy.changeAdmin.selector) {
ret = _dispatchChangeAdmin();
} else if (selector == ITransparentUpgradeableProxy.admin.selector) {
ret = _dispatchAdmin();
} else if (selector == ITransparentUpgradeableProxy.implementation.selector) {
ret = _dispatchImplementation();
} else {
revert("TransparentUpgradeableProxy: admin cannot fallback to proxy target");
}
assembly {
return(add(ret, 0x20), mload(ret))
}
} else {
super._fallback();
}
}
/**
* @dev Returns the current admin.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103`
*/
function _dispatchAdmin() private returns (bytes memory) {
_requireZeroValue();
address admin = _getAdmin();
return abi.encode(admin);
}
/**
* @dev Returns the current implementation.
*
* TIP: To get this value clients can read directly from the storage slot shown below (specified by EIP1967) using the
* https://eth.wiki/json-rpc/API#eth_getstorageat[`eth_getStorageAt`] RPC call.
* `0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc`
*/
function _dispatchImplementation() private returns (bytes memory) {
_requireZeroValue();
address implementation = _implementation();
return abi.encode(implementation);
}
/**
* @dev Changes the admin of the proxy.
*
* Emits an {AdminChanged} event.
*/
function _dispatchChangeAdmin() private returns (bytes memory) {
_requireZeroValue();
address newAdmin = abi.decode(msg.data[4:], (address));
_changeAdmin(newAdmin);
return "";
}
/**
* @dev Upgrade the implementation of the proxy.
*/
function _dispatchUpgradeTo() private returns (bytes memory) {
_requireZeroValue();
address newImplementation = abi.decode(msg.data[4:], (address));
_upgradeToAndCall(newImplementation, bytes(""), false);
return "";
}
/**
* @dev Upgrade the implementation of the proxy, and then call a function from the new implementation as specified
* by `data`, which should be an encoded function call. This is useful to initialize new storage variables in the
* proxied contract.
*/
function _dispatchUpgradeToAndCall() private returns (bytes memory) {
(address newImplementation, bytes memory data) = abi.decode(msg.data[4:], (address, bytes));
_upgradeToAndCall(newImplementation, data, true);
return "";
}
/**
* @dev Returns the current admin.
*/
function _admin() internal view virtual returns (address) {
return _getAdmin();
}
/**
* @dev To keep this contract fully transparent, all `ifAdmin` functions must be payable. This helper is here to
* emulate some proxy functions being non-payable while still allowing value to pass through.
*/
function _requireZeroValue() private {
require(msg.value == 0);
}
}
/**
* @title ReallocatablePaymentSplitter
* @dev This contract allows to split Ether payments among a group of accounts accourding to openzeppelin's PaymentSplitter.
*
* In addition, this contract allowes to transfer shares between investors.
*/
contract ReallocatablePaymentSplitterUpgradeable is PaymentSplitterUpgradeable, OwnableUpgradeable {
event sharesTransferred(address from, address to, uint256 shares);
function initialize(address[] memory payees, uint256[] memory shares_) external initializer {
__PaymentSplitter_init_unchained(payees, shares_);
__Ownable_init_unchained();
}
/**
* @dev Triggers a transfer to `msg.sender` of the amount of Ether they are owed, according to their percentage of the
* total shares and their previous withdrawals.
*/
function releaseMyETH() external {
release(payable(msg.sender));
}
/**
* @dev releases funds first, then transfers all shares `from` one account to another one (`to`)
*/
function reallocate(address payable from, address payable to) external onlyOwner {
require(from != to, "ReallocatablePaymentSplitterUpgradeable: reallocate to same account");
uint256 sharesFrom;
uint256 sharesTo;
uint256 sharesFromSlot;
uint256 sharesToSlot;
//cleanup: release funds first
if(releasable(from) > 0) {
release(from);
}
if(releasable(to) > 0) {
release(to);
}
//load mappings
assembly {
let _sharesSlot := 53
mstore(32, _sharesSlot)
//shareFrom = _share[from]
mstore(0, from)
sharesFromSlot := keccak256(0, 64)
sharesFrom := sload(sharesFromSlot)
//shareTo = _share[to]
mstore(0, to)
sharesToSlot := keccak256(0, 64)
sharesTo := sload(sharesToSlot)
}
sharesTo += sharesFrom;
sharesFrom = 0;
//write back to storage
assembly {
sstore(sharesFromSlot, sharesFrom) //_share[from] = shareFrom
sstore(sharesToSlot, sharesTo) //_share[to] = shareTo
}
// adapt released values
uint256 releasedFrom;
uint256 releasedTo;
uint256 releasedFromSlot;
uint256 releasedToSlot;
//load mappings
assembly {
let _releasedSlot := 54
mstore(32, _releasedSlot)
//releasedFrom = _released[from]
mstore(0, from)
releasedFromSlot := keccak256(0, 64)
releasedFrom := sload(releasedFromSlot)
//releasedTo = _released[to]
mstore(0, to)
releasedToSlot := keccak256(0, 64)
releasedTo := sload(releasedToSlot)
}
// uint256 totalPool = (totalReleased() + address(this).balance);
// uint256 sharesBoth = sharesFrom + sharesTo;
releasedTo += releasedFrom;
releasedFrom = 0;
//write back to storage
assembly {
sstore(releasedFromSlot, releasedFrom) // share[from] = shareFrom
sstore(releasedToSlot, releasedTo) // share[to] = shareTo
}
emit sharesTransferred(from, to, sharesFrom);
}
/**
* @dev rescue function if something goes wrong: transfers contract balance to owner
*/
function rescue() external onlyOwner {
AddressUpgradeable.sendValue(payable(owner()), address(this).balance);
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"anonymous":false,"inputs":[{"indexed":true,"internalType":"contract IERC20Upgradeable","name":"token","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint8","name":"version","type":"uint8"}],"name":"Initialized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"sharesTransferred","type":"event"},{"inputs":[{"internalType":"address[]","name":"payees","type":"address[]"},{"internalType":"uint256[]","name":"shares_","type":"uint256[]"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"from","type":"address"},{"internalType":"address payable","name":"to","type":"address"}],"name":"reallocate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"releasable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"releaseMyETH","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"token","type":"address"},{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rescue","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable","name":"token","type":"address"}],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
608060405234801561001057600080fd5b50612b93806100206000396000f3fe60806040526004361061010d5760003560e01c80638b83209b11610095578063c45ac05011610064578063c45ac0501461038c578063ce7c2ac2146103c9578063d79779b214610406578063e33b7de314610443578063f2fde38b1461046e57610154565b80638b83209b146102aa5780638da5cb5b146102e75780639852595c14610312578063a3f8eace1461034f57610154565b8063406072a9116100dc578063406072a9146101ed57806348b750441461022a578063715018a61461025357806372b8894c1461026a5780637fbbe46f1461028157610154565b80630bdeca911461015957806319165587146101825780631fbe1979146101ab5780633a98ef39146101c257610154565b36610154577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77061013b610497565b3460405161014a929190611fcf565b60405180910390a1005b600080fd5b34801561016557600080fd5b50610180600480360381019061017b9190611a84565b61049f565b005b34801561018e57600080fd5b506101a960048036038101906101a49190611a5b565b610619565b005b3480156101b757600080fd5b506101c0610799565b005b3480156101ce57600080fd5b506101d76107b4565b6040516101e49190612255565b60405180910390f35b3480156101f957600080fd5b50610214600480360381019061020f9190611b7e565b6107be565b6040516102219190612255565b60405180910390f35b34801561023657600080fd5b50610251600480360381019061024c9190611b7e565b610845565b005b34801561025f57600080fd5b50610268610a59565b005b34801561027657600080fd5b5061027f610a6d565b005b34801561028d57600080fd5b506102a860048036038101906102a39190611ac0565b610a78565b005b3480156102b657600080fd5b506102d160048036038101906102cc9190611bba565b610bc2565b6040516102de9190611f54565b60405180910390f35b3480156102f357600080fd5b506102fc610c30565b6040516103099190611f54565b60405180910390f35b34801561031e57600080fd5b5061033960048036038101906103349190611a32565b610c5a565b6040516103469190612255565b60405180910390f35b34801561035b57600080fd5b5061037660048036038101906103719190611a32565b610ca3565b6040516103839190612255565b60405180910390f35b34801561039857600080fd5b506103b360048036038101906103ae9190611b7e565b610cd6565b6040516103c09190612255565b60405180910390f35b3480156103d557600080fd5b506103f060048036038101906103eb9190611a32565b610d94565b6040516103fd9190612255565b60405180910390f35b34801561041257600080fd5b5061042d60048036038101906104289190611b55565b610ddd565b60405161043a9190612255565b60405180910390f35b34801561044f57600080fd5b50610458610e26565b6040516104659190612255565b60405180910390f35b34801561047a57600080fd5b5061049560048036038101906104909190611a32565b610e30565b005b600033905090565b6104a7610eb4565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610516576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050d90612035565b60405180910390fd5b600080600080600061052787610ca3565b11156105375761053686610619565b5b600061054286610ca3565b11156105525761055185610619565b5b603580602052866000526040600020925082549450856000526040600020915081549350508383610583919061231f565b9250600093508382558281556000806000806036806020528a60005260406000209250825494508960005260406000209150815493505083836105c6919061231f565b9250600093508382558281557f4fef33fbbf76f1d52a425faec63d0f183cae150d4cb4f0a3dd8e645af1f6f1088a8a8a60405161060593929190611f6f565b60405180910390a150505050505050505050565b6000603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541161069b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069290612095565b60405180910390fd5b60006106a682610ca3565b905060008114156106ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e390612115565b60405180910390fd5b80603460008282546106fe919061231f565b9250508190555080603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061075c8282610f32565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056828260405161078d929190611fa6565b60405180910390a15050565b6107a1610eb4565b6107b26107ac610c30565b47610f32565b565b6000603354905090565b6000603960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054116108c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108be90612095565b60405180910390fd5b60006108d38383610cd6565b90506000811415610919576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091090612115565b60405180910390fd5b80603860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610968919061231f565b9250508190555080603960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550610a04838383611026565b8273ffffffffffffffffffffffffffffffffffffffff167f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a8383604051610a4c929190611fcf565b60405180910390a2505050565b610a61610eb4565b610a6b60006110ac565b565b610a7633610619565b565b60008060019054906101000a900460ff16159050808015610aa95750600160008054906101000a900460ff1660ff16105b80610ad65750610ab830611172565b158015610ad55750600160008054906101000a900460ff1660ff16145b5b610b15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0c90612135565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610b52576001600060016101000a81548160ff0219169083151502179055505b610b5c8383611195565b610b6461131a565b8015610bbd5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051610bb49190611ff8565b60405180910390a15b505050565b600060378281548110610bfe577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000606560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000603660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080610cae610e26565b47610cb9919061231f565b9050610cce8382610cc986610c5a565b61137b565b915050919050565b600080610ce284610ddd565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610d1b9190611f54565b60206040518083038186803b158015610d3357600080fd5b505afa158015610d47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6b9190611be3565b610d75919061231f565b9050610d8b8382610d8687876107be565b61137b565b91505092915050565b6000603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000603860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000603454905090565b610e38610eb4565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9f90612075565b60405180910390fd5b610eb1816110ac565b50565b610ebc610497565b73ffffffffffffffffffffffffffffffffffffffff16610eda610c30565b73ffffffffffffffffffffffffffffffffffffffff1614610f30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2790612155565b60405180910390fd5b565b80471015610f75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6c906120d5565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051610f9b90611f3f565b60006040518083038185875af1925050503d8060008114610fd8576040519150601f19603f3d011682016040523d82523d6000602084013e610fdd565b606091505b5050905080611021576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611018906120b5565b60405180910390fd5b505050565b6110a78363a9059cbb60e01b8484604051602401611045929190611fcf565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506113e9565b505050565b6000606560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081606560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff166111e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111db906121b5565b60405180910390fd5b8051825114611228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121f90612175565b60405180910390fd5b600082511161126c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126390612215565b60405180910390fd5b60005b8251811015611315576113028382815181106112b4577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518383815181106112f5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516114b0565b808061130d90612559565b91505061126f565b505050565b600060019054906101000a900460ff16611369576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611360906121b5565b60405180910390fd5b611379611374610497565b6110ac565b565b600081603354603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054856113cc91906123a6565b6113d69190612375565b6113e09190612400565b90509392505050565b600061144b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166116dd9092919063ffffffff16565b90506000815111156114ab578080602001905181019061146b9190611b2c565b6114aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a1906121f5565b60405180910390fd5b5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611520576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151790612055565b60405180910390fd5b60008111611563576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155a90612235565b60405180910390fd5b6000603560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146115e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115dc906121d5565b60405180910390fd5b6037829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080603560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508060335461169a919061231f565b6033819055507f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac82826040516116d1929190611fcf565b60405180910390a15050565b60606116ec84846000856116f5565b90509392505050565b60608247101561173a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611731906120f5565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516117639190611f28565b60006040518083038185875af1925050503d80600081146117a0576040519150601f19603f3d011682016040523d82523d6000602084013e6117a5565b606091505b50915091506117b6878383876117c2565b92505050949350505050565b606083156118255760008351141561181d576117dd85611172565b61181c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181390612195565b60405180910390fd5b5b829050611830565b61182f8383611838565b5b949350505050565b60008251111561184b5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187f9190612013565b60405180910390fd5b600061189b61189684612295565b612270565b905080838252602082019050828560208602820111156118ba57600080fd5b60005b858110156118ea57816118d08882611960565b8452602084019350602083019250506001810190506118bd565b5050509392505050565b6000611907611902846122c1565b612270565b9050808382526020820190508285602086028201111561192657600080fd5b60005b85811015611956578161193c8882611a08565b845260208401935060208301925050600181019050611929565b5050509392505050565b60008135905061196f81612aea565b92915050565b60008135905061198481612b01565b92915050565b600082601f83011261199b57600080fd5b81356119ab848260208601611888565b91505092915050565b600082601f8301126119c557600080fd5b81356119d58482602086016118f4565b91505092915050565b6000815190506119ed81612b18565b92915050565b600081359050611a0281612b2f565b92915050565b600081359050611a1781612b46565b92915050565b600081519050611a2c81612b46565b92915050565b600060208284031215611a4457600080fd5b6000611a5284828501611960565b91505092915050565b600060208284031215611a6d57600080fd5b6000611a7b84828501611975565b91505092915050565b60008060408385031215611a9757600080fd5b6000611aa585828601611975565b9250506020611ab685828601611975565b9150509250929050565b60008060408385031215611ad357600080fd5b600083013567ffffffffffffffff811115611aed57600080fd5b611af98582860161198a565b925050602083013567ffffffffffffffff811115611b1657600080fd5b611b22858286016119b4565b9150509250929050565b600060208284031215611b3e57600080fd5b6000611b4c848285016119de565b91505092915050565b600060208284031215611b6757600080fd5b6000611b75848285016119f3565b91505092915050565b60008060408385031215611b9157600080fd5b6000611b9f858286016119f3565b9250506020611bb085828601611960565b9150509250929050565b600060208284031215611bcc57600080fd5b6000611bda84828501611a08565b91505092915050565b600060208284031215611bf557600080fd5b6000611c0384828501611a1d565b91505092915050565b611c15816124ad565b82525050565b611c2481612434565b82525050565b6000611c35826122ed565b611c3f8185612303565b9350611c4f8185602086016124f5565b80840191505092915050565b611c64816124bf565b82525050565b6000611c75826122f8565b611c7f818561230e565b9350611c8f8185602086016124f5565b611c988161262f565b840191505092915050565b6000611cb060438361230e565b9150611cbb82612640565b606082019050919050565b6000611cd3602c8361230e565b9150611cde826126b5565b604082019050919050565b6000611cf660268361230e565b9150611d0182612704565b604082019050919050565b6000611d1960268361230e565b9150611d2482612753565b604082019050919050565b6000611d3c603a8361230e565b9150611d47826127a2565b604082019050919050565b6000611d5f601d8361230e565b9150611d6a826127f1565b602082019050919050565b6000611d8260268361230e565b9150611d8d8261281a565b604082019050919050565b6000611da5602b8361230e565b9150611db082612869565b604082019050919050565b6000611dc8602e8361230e565b9150611dd3826128b8565b604082019050919050565b6000611deb60208361230e565b9150611df682612907565b602082019050919050565b6000611e0e60328361230e565b9150611e1982612930565b604082019050919050565b6000611e31600083612303565b9150611e3c8261297f565b600082019050919050565b6000611e54601d8361230e565b9150611e5f82612982565b602082019050919050565b6000611e77602b8361230e565b9150611e82826129ab565b604082019050919050565b6000611e9a602b8361230e565b9150611ea5826129fa565b604082019050919050565b6000611ebd602a8361230e565b9150611ec882612a49565b604082019050919050565b6000611ee0601a8361230e565b9150611eeb82612a98565b602082019050919050565b6000611f03601d8361230e565b9150611f0e82612ac1565b602082019050919050565b611f2281612496565b82525050565b6000611f348284611c2a565b915081905092915050565b6000611f4a82611e24565b9150819050919050565b6000602082019050611f696000830184611c1b565b92915050565b6000606082019050611f846000830186611c0c565b611f916020830185611c0c565b611f9e6040830184611f19565b949350505050565b6000604082019050611fbb6000830185611c0c565b611fc86020830184611f19565b9392505050565b6000604082019050611fe46000830185611c1b565b611ff16020830184611f19565b9392505050565b600060208201905061200d6000830184611c5b565b92915050565b6000602082019050818103600083015261202d8184611c6a565b905092915050565b6000602082019050818103600083015261204e81611ca3565b9050919050565b6000602082019050818103600083015261206e81611cc6565b9050919050565b6000602082019050818103600083015261208e81611ce9565b9050919050565b600060208201905081810360008301526120ae81611d0c565b9050919050565b600060208201905081810360008301526120ce81611d2f565b9050919050565b600060208201905081810360008301526120ee81611d52565b9050919050565b6000602082019050818103600083015261210e81611d75565b9050919050565b6000602082019050818103600083015261212e81611d98565b9050919050565b6000602082019050818103600083015261214e81611dbb565b9050919050565b6000602082019050818103600083015261216e81611dde565b9050919050565b6000602082019050818103600083015261218e81611e01565b9050919050565b600060208201905081810360008301526121ae81611e47565b9050919050565b600060208201905081810360008301526121ce81611e6a565b9050919050565b600060208201905081810360008301526121ee81611e8d565b9050919050565b6000602082019050818103600083015261220e81611eb0565b9050919050565b6000602082019050818103600083015261222e81611ed3565b9050919050565b6000602082019050818103600083015261224e81611ef6565b9050919050565b600060208201905061226a6000830184611f19565b92915050565b600061227a61228b565b90506122868282612528565b919050565b6000604051905090565b600067ffffffffffffffff8211156122b0576122af612600565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156122dc576122db612600565b5b602082029050602081019050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600061232a82612496565b915061233583612496565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561236a576123696125a2565b5b828201905092915050565b600061238082612496565b915061238b83612496565b92508261239b5761239a6125d1565b5b828204905092915050565b60006123b182612496565b91506123bc83612496565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156123f5576123f46125a2565b5b828202905092915050565b600061240b82612496565b915061241683612496565b925082821015612429576124286125a2565b5b828203905092915050565b600061243f82612476565b9050919050565b600061245182612476565b9050919050565b60008115159050919050565b600061246f82612434565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60006124b8826124d1565b9050919050565b60006124ca826124a0565b9050919050565b60006124dc826124e3565b9050919050565b60006124ee82612476565b9050919050565b60005b838110156125135780820151818401526020810190506124f8565b83811115612522576000848401525b50505050565b6125318261262f565b810181811067ffffffffffffffff821117156125505761254f612600565b5b80604052505050565b600061256482612496565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612597576125966125a2565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f5265616c6c6f63617461626c655061796d656e7453706c69747465725570677260008201527f61646561626c653a207265616c6c6f6361746520746f2073616d65206163636f60208201527f756e740000000000000000000000000000000000000000000000000000000000604082015250565b7f5061796d656e7453706c69747465723a206163636f756e74206973207468652060008201527f7a65726f20616464726573730000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060008201527f7368617265730000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060008201527f647565207061796d656e74000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f5061796d656e7453706c69747465723a2070617965657320616e64207368617260008201527f6573206c656e677468206d69736d617463680000000000000000000000000000602082015250565b50565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960008201527f2068617320736861726573000000000000000000000000000000000000000000602082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f5061796d656e7453706c69747465723a206e6f20706179656573000000000000600082015250565b7f5061796d656e7453706c69747465723a20736861726573206172652030000000600082015250565b612af381612434565b8114612afe57600080fd5b50565b612b0a81612446565b8114612b1557600080fd5b50565b612b2181612458565b8114612b2c57600080fd5b50565b612b3881612464565b8114612b4357600080fd5b50565b612b4f81612496565b8114612b5a57600080fd5b5056fea26469706673582212208ab40d3eb99dbb48fc9dc35e9321ceb350035bc039681d515cbd05d355a4792164736f6c63430008040033
Deployed Bytecode
0x60806040526004361061010d5760003560e01c80638b83209b11610095578063c45ac05011610064578063c45ac0501461038c578063ce7c2ac2146103c9578063d79779b214610406578063e33b7de314610443578063f2fde38b1461046e57610154565b80638b83209b146102aa5780638da5cb5b146102e75780639852595c14610312578063a3f8eace1461034f57610154565b8063406072a9116100dc578063406072a9146101ed57806348b750441461022a578063715018a61461025357806372b8894c1461026a5780637fbbe46f1461028157610154565b80630bdeca911461015957806319165587146101825780631fbe1979146101ab5780633a98ef39146101c257610154565b36610154577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77061013b610497565b3460405161014a929190611fcf565b60405180910390a1005b600080fd5b34801561016557600080fd5b50610180600480360381019061017b9190611a84565b61049f565b005b34801561018e57600080fd5b506101a960048036038101906101a49190611a5b565b610619565b005b3480156101b757600080fd5b506101c0610799565b005b3480156101ce57600080fd5b506101d76107b4565b6040516101e49190612255565b60405180910390f35b3480156101f957600080fd5b50610214600480360381019061020f9190611b7e565b6107be565b6040516102219190612255565b60405180910390f35b34801561023657600080fd5b50610251600480360381019061024c9190611b7e565b610845565b005b34801561025f57600080fd5b50610268610a59565b005b34801561027657600080fd5b5061027f610a6d565b005b34801561028d57600080fd5b506102a860048036038101906102a39190611ac0565b610a78565b005b3480156102b657600080fd5b506102d160048036038101906102cc9190611bba565b610bc2565b6040516102de9190611f54565b60405180910390f35b3480156102f357600080fd5b506102fc610c30565b6040516103099190611f54565b60405180910390f35b34801561031e57600080fd5b5061033960048036038101906103349190611a32565b610c5a565b6040516103469190612255565b60405180910390f35b34801561035b57600080fd5b5061037660048036038101906103719190611a32565b610ca3565b6040516103839190612255565b60405180910390f35b34801561039857600080fd5b506103b360048036038101906103ae9190611b7e565b610cd6565b6040516103c09190612255565b60405180910390f35b3480156103d557600080fd5b506103f060048036038101906103eb9190611a32565b610d94565b6040516103fd9190612255565b60405180910390f35b34801561041257600080fd5b5061042d60048036038101906104289190611b55565b610ddd565b60405161043a9190612255565b60405180910390f35b34801561044f57600080fd5b50610458610e26565b6040516104659190612255565b60405180910390f35b34801561047a57600080fd5b5061049560048036038101906104909190611a32565b610e30565b005b600033905090565b6104a7610eb4565b8073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610516576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161050d90612035565b60405180910390fd5b600080600080600061052787610ca3565b11156105375761053686610619565b5b600061054286610ca3565b11156105525761055185610619565b5b603580602052866000526040600020925082549450856000526040600020915081549350508383610583919061231f565b9250600093508382558281556000806000806036806020528a60005260406000209250825494508960005260406000209150815493505083836105c6919061231f565b9250600093508382558281557f4fef33fbbf76f1d52a425faec63d0f183cae150d4cb4f0a3dd8e645af1f6f1088a8a8a60405161060593929190611f6f565b60405180910390a150505050505050505050565b6000603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541161069b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161069290612095565b60405180910390fd5b60006106a682610ca3565b905060008114156106ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106e390612115565b60405180910390fd5b80603460008282546106fe919061231f565b9250508190555080603660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061075c8282610f32565b7fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056828260405161078d929190611fa6565b60405180910390a15050565b6107a1610eb4565b6107b26107ac610c30565b47610f32565b565b6000603354905090565b6000603960008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b6000603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054116108c7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108be90612095565b60405180910390fd5b60006108d38383610cd6565b90506000811415610919576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091090612115565b60405180910390fd5b80603860008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610968919061231f565b9250508190555080603960008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550610a04838383611026565b8273ffffffffffffffffffffffffffffffffffffffff167f3be5b7a71e84ed12875d241991c70855ac5817d847039e17a9d895c1ceb0f18a8383604051610a4c929190611fcf565b60405180910390a2505050565b610a61610eb4565b610a6b60006110ac565b565b610a7633610619565b565b60008060019054906101000a900460ff16159050808015610aa95750600160008054906101000a900460ff1660ff16105b80610ad65750610ab830611172565b158015610ad55750600160008054906101000a900460ff1660ff16145b5b610b15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0c90612135565b60405180910390fd5b60016000806101000a81548160ff021916908360ff1602179055508015610b52576001600060016101000a81548160ff0219169083151502179055505b610b5c8383611195565b610b6461131a565b8015610bbd5760008060016101000a81548160ff0219169083151502179055507f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024986001604051610bb49190611ff8565b60405180910390a15b505050565b600060378281548110610bfe577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000606560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6000603660008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b600080610cae610e26565b47610cb9919061231f565b9050610cce8382610cc986610c5a565b61137b565b915050919050565b600080610ce284610ddd565b8473ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b8152600401610d1b9190611f54565b60206040518083038186803b158015610d3357600080fd5b505afa158015610d47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610d6b9190611be3565b610d75919061231f565b9050610d8b8382610d8687876107be565b61137b565b91505092915050565b6000603560008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000603860008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000603454905090565b610e38610eb4565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610ea8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e9f90612075565b60405180910390fd5b610eb1816110ac565b50565b610ebc610497565b73ffffffffffffffffffffffffffffffffffffffff16610eda610c30565b73ffffffffffffffffffffffffffffffffffffffff1614610f30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f2790612155565b60405180910390fd5b565b80471015610f75576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f6c906120d5565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051610f9b90611f3f565b60006040518083038185875af1925050503d8060008114610fd8576040519150601f19603f3d011682016040523d82523d6000602084013e610fdd565b606091505b5050905080611021576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611018906120b5565b60405180910390fd5b505050565b6110a78363a9059cbb60e01b8484604051602401611045929190611fcf565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff83818316178352505050506113e9565b505050565b6000606560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081606560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b600060019054906101000a900460ff166111e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111db906121b5565b60405180910390fd5b8051825114611228576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161121f90612175565b60405180910390fd5b600082511161126c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161126390612215565b60405180910390fd5b60005b8251811015611315576113028382815181106112b4577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518383815181106112f5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101516114b0565b808061130d90612559565b91505061126f565b505050565b600060019054906101000a900460ff16611369576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611360906121b5565b60405180910390fd5b611379611374610497565b6110ac565b565b600081603354603560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054856113cc91906123a6565b6113d69190612375565b6113e09190612400565b90509392505050565b600061144b826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166116dd9092919063ffffffff16565b90506000815111156114ab578080602001905181019061146b9190611b2c565b6114aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a1906121f5565b60405180910390fd5b5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611520576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161151790612055565b60405180910390fd5b60008111611563576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161155a90612235565b60405180910390fd5b6000603560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054146115e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115dc906121d5565b60405180910390fd5b6037829080600181540180825580915050600190039060005260206000200160009091909190916101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555080603560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508060335461169a919061231f565b6033819055507f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac82826040516116d1929190611fcf565b60405180910390a15050565b60606116ec84846000856116f5565b90509392505050565b60608247101561173a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611731906120f5565b60405180910390fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516117639190611f28565b60006040518083038185875af1925050503d80600081146117a0576040519150601f19603f3d011682016040523d82523d6000602084013e6117a5565b606091505b50915091506117b6878383876117c2565b92505050949350505050565b606083156118255760008351141561181d576117dd85611172565b61181c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181390612195565b60405180910390fd5b5b829050611830565b61182f8383611838565b5b949350505050565b60008251111561184b5781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187f9190612013565b60405180910390fd5b600061189b61189684612295565b612270565b905080838252602082019050828560208602820111156118ba57600080fd5b60005b858110156118ea57816118d08882611960565b8452602084019350602083019250506001810190506118bd565b5050509392505050565b6000611907611902846122c1565b612270565b9050808382526020820190508285602086028201111561192657600080fd5b60005b85811015611956578161193c8882611a08565b845260208401935060208301925050600181019050611929565b5050509392505050565b60008135905061196f81612aea565b92915050565b60008135905061198481612b01565b92915050565b600082601f83011261199b57600080fd5b81356119ab848260208601611888565b91505092915050565b600082601f8301126119c557600080fd5b81356119d58482602086016118f4565b91505092915050565b6000815190506119ed81612b18565b92915050565b600081359050611a0281612b2f565b92915050565b600081359050611a1781612b46565b92915050565b600081519050611a2c81612b46565b92915050565b600060208284031215611a4457600080fd5b6000611a5284828501611960565b91505092915050565b600060208284031215611a6d57600080fd5b6000611a7b84828501611975565b91505092915050565b60008060408385031215611a9757600080fd5b6000611aa585828601611975565b9250506020611ab685828601611975565b9150509250929050565b60008060408385031215611ad357600080fd5b600083013567ffffffffffffffff811115611aed57600080fd5b611af98582860161198a565b925050602083013567ffffffffffffffff811115611b1657600080fd5b611b22858286016119b4565b9150509250929050565b600060208284031215611b3e57600080fd5b6000611b4c848285016119de565b91505092915050565b600060208284031215611b6757600080fd5b6000611b75848285016119f3565b91505092915050565b60008060408385031215611b9157600080fd5b6000611b9f858286016119f3565b9250506020611bb085828601611960565b9150509250929050565b600060208284031215611bcc57600080fd5b6000611bda84828501611a08565b91505092915050565b600060208284031215611bf557600080fd5b6000611c0384828501611a1d565b91505092915050565b611c15816124ad565b82525050565b611c2481612434565b82525050565b6000611c35826122ed565b611c3f8185612303565b9350611c4f8185602086016124f5565b80840191505092915050565b611c64816124bf565b82525050565b6000611c75826122f8565b611c7f818561230e565b9350611c8f8185602086016124f5565b611c988161262f565b840191505092915050565b6000611cb060438361230e565b9150611cbb82612640565b606082019050919050565b6000611cd3602c8361230e565b9150611cde826126b5565b604082019050919050565b6000611cf660268361230e565b9150611d0182612704565b604082019050919050565b6000611d1960268361230e565b9150611d2482612753565b604082019050919050565b6000611d3c603a8361230e565b9150611d47826127a2565b604082019050919050565b6000611d5f601d8361230e565b9150611d6a826127f1565b602082019050919050565b6000611d8260268361230e565b9150611d8d8261281a565b604082019050919050565b6000611da5602b8361230e565b9150611db082612869565b604082019050919050565b6000611dc8602e8361230e565b9150611dd3826128b8565b604082019050919050565b6000611deb60208361230e565b9150611df682612907565b602082019050919050565b6000611e0e60328361230e565b9150611e1982612930565b604082019050919050565b6000611e31600083612303565b9150611e3c8261297f565b600082019050919050565b6000611e54601d8361230e565b9150611e5f82612982565b602082019050919050565b6000611e77602b8361230e565b9150611e82826129ab565b604082019050919050565b6000611e9a602b8361230e565b9150611ea5826129fa565b604082019050919050565b6000611ebd602a8361230e565b9150611ec882612a49565b604082019050919050565b6000611ee0601a8361230e565b9150611eeb82612a98565b602082019050919050565b6000611f03601d8361230e565b9150611f0e82612ac1565b602082019050919050565b611f2281612496565b82525050565b6000611f348284611c2a565b915081905092915050565b6000611f4a82611e24565b9150819050919050565b6000602082019050611f696000830184611c1b565b92915050565b6000606082019050611f846000830186611c0c565b611f916020830185611c0c565b611f9e6040830184611f19565b949350505050565b6000604082019050611fbb6000830185611c0c565b611fc86020830184611f19565b9392505050565b6000604082019050611fe46000830185611c1b565b611ff16020830184611f19565b9392505050565b600060208201905061200d6000830184611c5b565b92915050565b6000602082019050818103600083015261202d8184611c6a565b905092915050565b6000602082019050818103600083015261204e81611ca3565b9050919050565b6000602082019050818103600083015261206e81611cc6565b9050919050565b6000602082019050818103600083015261208e81611ce9565b9050919050565b600060208201905081810360008301526120ae81611d0c565b9050919050565b600060208201905081810360008301526120ce81611d2f565b9050919050565b600060208201905081810360008301526120ee81611d52565b9050919050565b6000602082019050818103600083015261210e81611d75565b9050919050565b6000602082019050818103600083015261212e81611d98565b9050919050565b6000602082019050818103600083015261214e81611dbb565b9050919050565b6000602082019050818103600083015261216e81611dde565b9050919050565b6000602082019050818103600083015261218e81611e01565b9050919050565b600060208201905081810360008301526121ae81611e47565b9050919050565b600060208201905081810360008301526121ce81611e6a565b9050919050565b600060208201905081810360008301526121ee81611e8d565b9050919050565b6000602082019050818103600083015261220e81611eb0565b9050919050565b6000602082019050818103600083015261222e81611ed3565b9050919050565b6000602082019050818103600083015261224e81611ef6565b9050919050565b600060208201905061226a6000830184611f19565b92915050565b600061227a61228b565b90506122868282612528565b919050565b6000604051905090565b600067ffffffffffffffff8211156122b0576122af612600565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156122dc576122db612600565b5b602082029050602081019050919050565b600081519050919050565b600081519050919050565b600081905092915050565b600082825260208201905092915050565b600061232a82612496565b915061233583612496565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0382111561236a576123696125a2565b5b828201905092915050565b600061238082612496565b915061238b83612496565b92508261239b5761239a6125d1565b5b828204905092915050565b60006123b182612496565b91506123bc83612496565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156123f5576123f46125a2565b5b828202905092915050565b600061240b82612496565b915061241683612496565b925082821015612429576124286125a2565b5b828203905092915050565b600061243f82612476565b9050919050565b600061245182612476565b9050919050565b60008115159050919050565b600061246f82612434565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60006124b8826124d1565b9050919050565b60006124ca826124a0565b9050919050565b60006124dc826124e3565b9050919050565b60006124ee82612476565b9050919050565b60005b838110156125135780820151818401526020810190506124f8565b83811115612522576000848401525b50505050565b6125318261262f565b810181811067ffffffffffffffff821117156125505761254f612600565b5b80604052505050565b600061256482612496565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612597576125966125a2565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f5265616c6c6f63617461626c655061796d656e7453706c69747465725570677260008201527f61646561626c653a207265616c6c6f6361746520746f2073616d65206163636f60208201527f756e740000000000000000000000000000000000000000000000000000000000604082015250565b7f5061796d656e7453706c69747465723a206163636f756e74206973207468652060008201527f7a65726f20616464726573730000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060008201527f7368617265730000000000000000000000000000000000000000000000000000602082015250565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b7f416464726573733a20696e73756666696369656e742062616c616e636520666f60008201527f722063616c6c0000000000000000000000000000000000000000000000000000602082015250565b7f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060008201527f647565207061796d656e74000000000000000000000000000000000000000000602082015250565b7f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160008201527f647920696e697469616c697a6564000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f5061796d656e7453706c69747465723a2070617965657320616e64207368617260008201527f6573206c656e677468206d69736d617463680000000000000000000000000000602082015250565b50565b7f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000600082015250565b7f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960008201527f6e697469616c697a696e67000000000000000000000000000000000000000000602082015250565b7f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960008201527f2068617320736861726573000000000000000000000000000000000000000000602082015250565b7f5361666545524332303a204552433230206f7065726174696f6e20646964206e60008201527f6f74207375636365656400000000000000000000000000000000000000000000602082015250565b7f5061796d656e7453706c69747465723a206e6f20706179656573000000000000600082015250565b7f5061796d656e7453706c69747465723a20736861726573206172652030000000600082015250565b612af381612434565b8114612afe57600080fd5b50565b612b0a81612446565b8114612b1557600080fd5b50565b612b2181612458565b8114612b2c57600080fd5b50565b612b3881612464565b8114612b4357600080fd5b50565b612b4f81612496565b8114612b5a57600080fd5b5056fea26469706673582212208ab40d3eb99dbb48fc9dc35e9321ceb350035bc039681d515cbd05d355a4792164736f6c63430008040033
Deployed Bytecode Sourcemap
71852:2869:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;29742:40;29758:12;:10;:12::i;:::-;29772:9;29742:40;;;;;;;:::i;:::-;;;;;;;;71852:2869;;;;;72585:1905;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;32296:682;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74594:122;;;;;;;;;;;;;:::i;:::-;;29873:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31013:146;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33246:814;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37455:103;;;;;;;;;;;;;:::i;:::-;;72398:71;;;;;;;;;;;;;:::i;:::-;;72028:182;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;31250:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36807:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30735:109;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31440:225;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31825:271;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30531:105;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30310:130;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;30058:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;37713:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;25738:98;25791:7;25818:10;25811:17;;25738:98;:::o;72585:1905::-;36693:13;:11;:13::i;:::-;72689:2:::1;72681:10;;:4;:10;;;;72673:90;;;;;;;;;;;;:::i;:::-;;;;;;;;;72770:18;72793:16:::0;72816:22:::1;72843:20:::0;72926:1:::1;72907:16;72918:4;72907:10;:16::i;:::-;:20;72904:50;;;72935:13;72943:4;72935:7;:13::i;:::-;72904:50;72978:1;72961:14;72972:2;72961:10;:14::i;:::-;:18;72958:46;;;72987:11;72995:2;72987:7;:11::i;:::-;72958:46;73063:2;73081:11;73077:2;73070:23;73141:4;73138:1;73131:15;73182:2;73179:1;73169:16;73151:34;;73210:14;73204:21;73190:35;;73269:2;73266:1;73259:13;73306:2;73303:1;73293:16;73277:32;;73332:12;73326:19;73314:31;;73038:312;73368:10;73356:22;;;;;:::i;:::-;;;73396:1;73383:14;;73469:10;73453:14;73446:34;73533:8;73519:12;73512:30;73604:20;73629:18:::0;73654:24:::1;73683:22:::0;73767:2:::1;73785:13;73781:2;73774:25;73853:4;73850:1;73843:15;73896:2;73893:1;73883:16;73863:36;;73926:16;73920:23;73904:39;;73993:2;73990:1;73983:13;74032:2;74029:1;74019:16;74001:34;;74060:14;74054:21;74040:35;;73740:340;74221:12;74207:26;;;;;:::i;:::-;;;74253:1;74238:16;;74328:12;74310:16;74303:38;74396:10;74380:14;74373:34;74446:39;74464:4;74470:2;74474:10;74446:39;;;;;;;;:::i;:::-;;;;;;;;36717:1;;;;;;;;72585:1905:::0;;:::o;32296:682::-;32391:1;32372:7;:16;32380:7;32372:16;;;;;;;;;;;;;;;;:20;32364:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;32448:15;32466:19;32477:7;32466:10;:19::i;:::-;32448:37;;32517:1;32506:7;:12;;32498:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;32779:7;32761:14;;:25;;;;;;;:::i;:::-;;;;;;;;32844:7;32822:9;:18;32832:7;32822:18;;;;;;;;;;;;;;;;:29;;;;;;;;;;;32875:46;32904:7;32913;32875:28;:46::i;:::-;32937:33;32953:7;32962;32937:33;;;;;;;:::i;:::-;;;;;;;;32296:682;;:::o;74594:122::-;36693:13;:11;:13::i;:::-;74642:69:::1;74679:7;:5;:7::i;:::-;74689:21;74642:28;:69::i;:::-;74594:122::o:0;29873:91::-;29917:7;29944:12;;29937:19;;29873:91;:::o;31013:146::-;31094:7;31121:14;:21;31136:5;31121:21;;;;;;;;;;;;;;;:30;31143:7;31121:30;;;;;;;;;;;;;;;;31114:37;;31013:146;;;;:::o;33246:814::-;33358:1;33339:7;:16;33347:7;33339:16;;;;;;;;;;;;;;;;:20;33331:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;33415:15;33433:26;33444:5;33451:7;33433:10;:26::i;:::-;33415:44;;33491:1;33480:7;:12;;33472:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;33825:7;33795:19;:26;33815:5;33795:26;;;;;;;;;;;;;;;;:37;;;;;;;:::i;:::-;;;;;;;;33902:7;33868:14;:21;33883:5;33868:21;;;;;;;;;;;;;;;:30;33890:7;33868:30;;;;;;;;;;;;;;;;:41;;;;;;;;;;;33933:58;33967:5;33974:7;33983;33933:33;:58::i;:::-;34028:5;34007:45;;;34035:7;34044;34007:45;;;;;;;:::i;:::-;;;;;;;;33246:814;;;:::o;37455:103::-;36693:13;:11;:13::i;:::-;37520:30:::1;37547:1;37520:18;:30::i;:::-;37455:103::o:0;72398:71::-;72436:28;72452:10;72436:7;:28::i;:::-;72398:71::o;72028:182::-;11754:19;11777:13;;;;;;;;;;;11776:14;11754:36;;11824:14;:34;;;;;11857:1;11842:12;;;;;;;;;;:16;;;11824:34;11823:108;;;;11865:44;11903:4;11865:29;:44::i;:::-;11864:45;:66;;;;;11929:1;11913:12;;;;;;;;;;:17;;;11864:66;11823:108;11801:204;;;;;;;;;;;;:::i;:::-;;;;;;;;;12031:1;12016:12;;:16;;;;;;;;;;;;;;;;;;12047:14;12043:67;;;12094:4;12078:13;;:20;;;;;;;;;;;;;;;;;;12043:67;72125:49:::1;72158:6;72166:7;72125:32;:49::i;:::-;72179:26;:24;:26::i;:::-;12136:14:::0;12132:102;;;12183:5;12167:13;;:21;;;;;;;;;;;;;;;;;;12208:14;12220:1;12208:14;;;;;;:::i;:::-;;;;;;;;12132:102;72028:182;;;:::o;31250:100::-;31301:7;31328;31336:5;31328:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31321:21;;31250:100;;;:::o;36807:87::-;36853:7;36880:6;;;;;;;;;;;36873:13;;36807:87;:::o;30735:109::-;30791:7;30818:9;:18;30828:7;30818:18;;;;;;;;;;;;;;;;30811:25;;30735:109;;;:::o;31440:225::-;31498:7;31518:21;31566:15;:13;:15::i;:::-;31542:21;:39;;;;:::i;:::-;31518:63;;31599:58;31615:7;31624:13;31639:17;31648:7;31639:8;:17::i;:::-;31599:15;:58::i;:::-;31592:65;;;31440:225;;;:::o;31825:271::-;31908:7;31928:21;31985:20;31999:5;31985:13;:20::i;:::-;31952:5;:15;;;31976:4;31952:30;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:53;;;;:::i;:::-;31928:77;;32023:65;32039:7;32048:13;32063:24;32072:5;32079:7;32063:8;:24::i;:::-;32023:15;:65::i;:::-;32016:72;;;31825:271;;;;:::o;30531:105::-;30585:7;30612;:16;30620:7;30612:16;;;;;;;;;;;;;;;;30605:23;;30531:105;;;:::o;30310:130::-;30379:7;30406:19;:26;30426:5;30406:26;;;;;;;;;;;;;;;;30399:33;;30310:130;;;:::o;30058:95::-;30104:7;30131:14;;30124:21;;30058:95;:::o;37713:201::-;36693:13;:11;:13::i;:::-;37822:1:::1;37802:22;;:8;:22;;;;37794:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;37878:28;37897:8;37878:18;:28::i;:::-;37713:201:::0;:::o;36972:132::-;37047:12;:10;:12::i;:::-;37036:23;;:7;:5;:7::i;:::-;:23;;;37028:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;36972:132::o;2482:317::-;2597:6;2572:21;:31;;2564:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2651:12;2669:9;:14;;2691:6;2669:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2650:52;;;2721:7;2713:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;2482:317;;;:::o;21093:222::-;21221:86;21241:5;21271:23;;;21296:2;21300:5;21248:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21221:19;:86::i;:::-;21093:222;;;:::o;38074:191::-;38148:16;38167:6;;;;;;;;;;;38148:25;;38193:8;38184:6;;:17;;;;;;;;;;;;;;;;;;38248:8;38217:40;;38238:8;38217:40;;;;;;;;;;;;38074:191;;:::o;1221:326::-;1281:4;1538:1;1516:7;:19;;;:23;1509:30;;1221:326;;;:::o;28754:414::-;13897:13;;;;;;;;;;;13889:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;28909:7:::1;:14;28892:6;:13;:31;28884:94;;;;;;;;;;;;:::i;:::-;;;;;;;;;29013:1;28997:6;:13;:17;28989:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;29063:9;29058:103;29082:6;:13;29078:1;:17;29058:103;;;29117:32;29127:6;29134:1;29127:9;;;;;;;;;;;;;;;;;;;;;;29138:7;29146:1;29138:10;;;;;;;;;;;;;;;;;;;;;;29117:9;:32::i;:::-;29097:3;;;;;:::i;:::-;;;;29058:103;;;;28754:414:::0;;:::o;36455:113::-;13897:13;;;;;;;;;;;13889:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;36528:32:::1;36547:12;:10;:12::i;:::-;36528:18;:32::i;:::-;36455:113::o:0;34238:248::-;34384:7;34463:15;34448:12;;34428:7;:16;34436:7;34428:16;;;;;;;;;;;;;;;;34412:13;:32;;;;:::i;:::-;34411:49;;;;:::i;:::-;:67;;;;:::i;:::-;34404:74;;34238:248;;;;;:::o;24226:727::-;24661:23;24687:69;24715:4;24687:69;;;;;;;;;;;;;;;;;24695:5;24687:27;;;;:69;;;;;:::i;:::-;24661:95;;24791:1;24771:10;:17;:21;24767:179;;;24868:10;24857:30;;;;;;;;;;;;:::i;:::-;24849:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;24767:179;24226:727;;;:::o;34678:473::-;34777:1;34758:21;;:7;:21;;;;34750:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;34857:1;34847:7;:11;34839:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;34931:1;34911:7;:16;34919:7;34911:16;;;;;;;;;;;;;;;;:21;34903:77;;;;;;;;;;;;:::i;:::-;;;;;;;;;34993:7;35006;34993:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;35044:7;35025;:16;35033:7;35025:16;;;;;;;;;;;;;;;:26;;;;35092:7;35077:12;;:22;;;;:::i;:::-;35062:12;:37;;;;35115:28;35126:7;35135;35115:28;;;;;;;:::i;:::-;;;;;;;;34678:473;;:::o;3978:229::-;4115:12;4147:52;4169:6;4177:4;4183:1;4186:12;4147:21;:52::i;:::-;4140:59;;3978:229;;;;;:::o;5098:455::-;5268:12;5326:5;5301:21;:30;;5293:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;5386:12;5400:23;5427:6;:11;;5446:5;5453:4;5427:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5385:73;;;;5476:69;5503:6;5511:7;5520:10;5532:12;5476:26;:69::i;:::-;5469:76;;;;5098:455;;;;;;:::o;6758:644::-;6943:12;6972:7;6968:427;;;7021:1;7000:10;:17;:22;6996:290;;;7218:18;7229:6;7218:10;:18::i;:::-;7210:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;6996:290;7307:10;7300:17;;;;6968:427;7350:33;7358:10;7370:12;7350:7;:33::i;:::-;6758:644;;;;;;;:::o;7944:552::-;8125:1;8105:10;:17;:21;8101:388;;;8337:10;8331:17;8394:15;8381:10;8377:2;8373:19;8366:44;8289:136;8464:12;8457:20;;;;;;;;;;;:::i;:::-;;;;;;;;24:655:1;120:5;145:81;161:64;218:6;161:64;:::i;:::-;145:81;:::i;:::-;136:90;;246:5;275:6;268:5;261:21;309:4;302:5;298:16;291:23;;335:6;385:3;377:4;369:6;365:17;360:3;356:27;353:36;350:2;;;414:1;411;404:12;350:2;450:1;435:238;460:6;457:1;454:13;435:238;;;528:3;557:37;590:3;578:10;557:37;:::i;:::-;552:3;545:50;624:4;619:3;615:14;608:21;;658:4;653:3;649:14;642:21;;495:178;482:1;479;475:9;470:14;;435:238;;;439:14;126:553;;;;;;;:::o;702:655::-;798:5;823:81;839:64;896:6;839:64;:::i;:::-;823:81;:::i;:::-;814:90;;924:5;953:6;946:5;939:21;987:4;980:5;976:16;969:23;;1013:6;1063:3;1055:4;1047:6;1043:17;1038:3;1034:27;1031:36;1028:2;;;1092:1;1089;1082:12;1028:2;1128:1;1113:238;1138:6;1135:1;1132:13;1113:238;;;1206:3;1235:37;1268:3;1256:10;1235:37;:::i;:::-;1230:3;1223:50;1302:4;1297:3;1293:14;1286:21;;1336:4;1331:3;1327:14;1320:21;;1173:178;1160:1;1157;1153:9;1148:14;;1113:238;;;1117:14;804:553;;;;;;;:::o;1363:139::-;1409:5;1447:6;1434:20;1425:29;;1463:33;1490:5;1463:33;:::i;:::-;1415:87;;;;:::o;1508:155::-;1562:5;1600:6;1587:20;1578:29;;1616:41;1651:5;1616:41;:::i;:::-;1568:95;;;;:::o;1686:303::-;1757:5;1806:3;1799:4;1791:6;1787:17;1783:27;1773:2;;1824:1;1821;1814:12;1773:2;1864:6;1851:20;1889:94;1979:3;1971:6;1964:4;1956:6;1952:17;1889:94;:::i;:::-;1880:103;;1763:226;;;;;:::o;2012:303::-;2083:5;2132:3;2125:4;2117:6;2113:17;2109:27;2099:2;;2150:1;2147;2140:12;2099:2;2190:6;2177:20;2215:94;2305:3;2297:6;2290:4;2282:6;2278:17;2215:94;:::i;:::-;2206:103;;2089:226;;;;;:::o;2321:137::-;2375:5;2406:6;2400:13;2391:22;;2422:30;2446:5;2422:30;:::i;:::-;2381:77;;;;:::o;2464:189::-;2535:5;2573:6;2560:20;2551:29;;2589:58;2641:5;2589:58;:::i;:::-;2541:112;;;;:::o;2659:139::-;2705:5;2743:6;2730:20;2721:29;;2759:33;2786:5;2759:33;:::i;:::-;2711:87;;;;:::o;2804:143::-;2861:5;2892:6;2886:13;2877:22;;2908:33;2935:5;2908:33;:::i;:::-;2867:80;;;;:::o;2953:262::-;3012:6;3061:2;3049:9;3040:7;3036:23;3032:32;3029:2;;;3077:1;3074;3067:12;3029:2;3120:1;3145:53;3190:7;3181:6;3170:9;3166:22;3145:53;:::i;:::-;3135:63;;3091:117;3019:196;;;;:::o;3221:278::-;3288:6;3337:2;3325:9;3316:7;3312:23;3308:32;3305:2;;;3353:1;3350;3343:12;3305:2;3396:1;3421:61;3474:7;3465:6;3454:9;3450:22;3421:61;:::i;:::-;3411:71;;3367:125;3295:204;;;;:::o;3505:439::-;3589:6;3597;3646:2;3634:9;3625:7;3621:23;3617:32;3614:2;;;3662:1;3659;3652:12;3614:2;3705:1;3730:61;3783:7;3774:6;3763:9;3759:22;3730:61;:::i;:::-;3720:71;;3676:125;3840:2;3866:61;3919:7;3910:6;3899:9;3895:22;3866:61;:::i;:::-;3856:71;;3811:126;3604:340;;;;;:::o;3950:693::-;4068:6;4076;4125:2;4113:9;4104:7;4100:23;4096:32;4093:2;;;4141:1;4138;4131:12;4093:2;4212:1;4201:9;4197:17;4184:31;4242:18;4234:6;4231:30;4228:2;;;4274:1;4271;4264:12;4228:2;4302:78;4372:7;4363:6;4352:9;4348:22;4302:78;:::i;:::-;4292:88;;4155:235;4457:2;4446:9;4442:18;4429:32;4488:18;4480:6;4477:30;4474:2;;;4520:1;4517;4510:12;4474:2;4548:78;4618:7;4609:6;4598:9;4594:22;4548:78;:::i;:::-;4538:88;;4400:236;4083:560;;;;;:::o;4649:278::-;4716:6;4765:2;4753:9;4744:7;4740:23;4736:32;4733:2;;;4781:1;4778;4771:12;4733:2;4824:1;4849:61;4902:7;4893:6;4882:9;4878:22;4849:61;:::i;:::-;4839:71;;4795:125;4723:204;;;;:::o;4933:312::-;5017:6;5066:2;5054:9;5045:7;5041:23;5037:32;5034:2;;;5082:1;5079;5072:12;5034:2;5125:1;5150:78;5220:7;5211:6;5200:9;5196:22;5150:78;:::i;:::-;5140:88;;5096:142;5024:221;;;;:::o;5251:457::-;5344:6;5352;5401:2;5389:9;5380:7;5376:23;5372:32;5369:2;;;5417:1;5414;5407:12;5369:2;5460:1;5485:78;5555:7;5546:6;5535:9;5531:22;5485:78;:::i;:::-;5475:88;;5431:142;5612:2;5638:53;5683:7;5674:6;5663:9;5659:22;5638:53;:::i;:::-;5628:63;;5583:118;5359:349;;;;;:::o;5714:262::-;5773:6;5822:2;5810:9;5801:7;5797:23;5793:32;5790:2;;;5838:1;5835;5828:12;5790:2;5881:1;5906:53;5951:7;5942:6;5931:9;5927:22;5906:53;:::i;:::-;5896:63;;5852:117;5780:196;;;;:::o;5982:284::-;6052:6;6101:2;6089:9;6080:7;6076:23;6072:32;6069:2;;;6117:1;6114;6107:12;6069:2;6160:1;6185:64;6241:7;6232:6;6221:9;6217:22;6185:64;:::i;:::-;6175:74;;6131:128;6059:207;;;;:::o;6272:147::-;6367:45;6406:5;6367:45;:::i;:::-;6362:3;6355:58;6345:74;;:::o;6425:118::-;6512:24;6530:5;6512:24;:::i;:::-;6507:3;6500:37;6490:53;;:::o;6549:373::-;6653:3;6681:38;6713:5;6681:38;:::i;:::-;6735:88;6816:6;6811:3;6735:88;:::i;:::-;6728:95;;6832:52;6877:6;6872:3;6865:4;6858:5;6854:16;6832:52;:::i;:::-;6909:6;6904:3;6900:16;6893:23;;6657:265;;;;;:::o;6928:143::-;7021:43;7058:5;7021:43;:::i;:::-;7016:3;7009:56;6999:72;;:::o;7077:364::-;7165:3;7193:39;7226:5;7193:39;:::i;:::-;7248:71;7312:6;7307:3;7248:71;:::i;:::-;7241:78;;7328:52;7373:6;7368:3;7361:4;7354:5;7350:16;7328:52;:::i;:::-;7405:29;7427:6;7405:29;:::i;:::-;7400:3;7396:39;7389:46;;7169:272;;;;;:::o;7447:366::-;7589:3;7610:67;7674:2;7669:3;7610:67;:::i;:::-;7603:74;;7686:93;7775:3;7686:93;:::i;:::-;7804:2;7799:3;7795:12;7788:19;;7593:220;;;:::o;7819:366::-;7961:3;7982:67;8046:2;8041:3;7982:67;:::i;:::-;7975:74;;8058:93;8147:3;8058:93;:::i;:::-;8176:2;8171:3;8167:12;8160:19;;7965:220;;;:::o;8191:366::-;8333:3;8354:67;8418:2;8413:3;8354:67;:::i;:::-;8347:74;;8430:93;8519:3;8430:93;:::i;:::-;8548:2;8543:3;8539:12;8532:19;;8337:220;;;:::o;8563:366::-;8705:3;8726:67;8790:2;8785:3;8726:67;:::i;:::-;8719:74;;8802:93;8891:3;8802:93;:::i;:::-;8920:2;8915:3;8911:12;8904:19;;8709:220;;;:::o;8935:366::-;9077:3;9098:67;9162:2;9157:3;9098:67;:::i;:::-;9091:74;;9174:93;9263:3;9174:93;:::i;:::-;9292:2;9287:3;9283:12;9276:19;;9081:220;;;:::o;9307:366::-;9449:3;9470:67;9534:2;9529:3;9470:67;:::i;:::-;9463:74;;9546:93;9635:3;9546:93;:::i;:::-;9664:2;9659:3;9655:12;9648:19;;9453:220;;;:::o;9679:366::-;9821:3;9842:67;9906:2;9901:3;9842:67;:::i;:::-;9835:74;;9918:93;10007:3;9918:93;:::i;:::-;10036:2;10031:3;10027:12;10020:19;;9825:220;;;:::o;10051:366::-;10193:3;10214:67;10278:2;10273:3;10214:67;:::i;:::-;10207:74;;10290:93;10379:3;10290:93;:::i;:::-;10408:2;10403:3;10399:12;10392:19;;10197:220;;;:::o;10423:366::-;10565:3;10586:67;10650:2;10645:3;10586:67;:::i;:::-;10579:74;;10662:93;10751:3;10662:93;:::i;:::-;10780:2;10775:3;10771:12;10764:19;;10569:220;;;:::o;10795:366::-;10937:3;10958:67;11022:2;11017:3;10958:67;:::i;:::-;10951:74;;11034:93;11123:3;11034:93;:::i;:::-;11152:2;11147:3;11143:12;11136:19;;10941:220;;;:::o;11167:366::-;11309:3;11330:67;11394:2;11389:3;11330:67;:::i;:::-;11323:74;;11406:93;11495:3;11406:93;:::i;:::-;11524:2;11519:3;11515:12;11508:19;;11313:220;;;:::o;11539:398::-;11698:3;11719:83;11800:1;11795:3;11719:83;:::i;:::-;11712:90;;11811:93;11900:3;11811:93;:::i;:::-;11929:1;11924:3;11920:11;11913:18;;11702:235;;;:::o;11943:366::-;12085:3;12106:67;12170:2;12165:3;12106:67;:::i;:::-;12099:74;;12182:93;12271:3;12182:93;:::i;:::-;12300:2;12295:3;12291:12;12284:19;;12089:220;;;:::o;12315:366::-;12457:3;12478:67;12542:2;12537:3;12478:67;:::i;:::-;12471:74;;12554:93;12643:3;12554:93;:::i;:::-;12672:2;12667:3;12663:12;12656:19;;12461:220;;;:::o;12687:366::-;12829:3;12850:67;12914:2;12909:3;12850:67;:::i;:::-;12843:74;;12926:93;13015:3;12926:93;:::i;:::-;13044:2;13039:3;13035:12;13028:19;;12833:220;;;:::o;13059:366::-;13201:3;13222:67;13286:2;13281:3;13222:67;:::i;:::-;13215:74;;13298:93;13387:3;13298:93;:::i;:::-;13416:2;13411:3;13407:12;13400:19;;13205:220;;;:::o;13431:366::-;13573:3;13594:67;13658:2;13653:3;13594:67;:::i;:::-;13587:74;;13670:93;13759:3;13670:93;:::i;:::-;13788:2;13783:3;13779:12;13772:19;;13577:220;;;:::o;13803:366::-;13945:3;13966:67;14030:2;14025:3;13966:67;:::i;:::-;13959:74;;14042:93;14131:3;14042:93;:::i;:::-;14160:2;14155:3;14151:12;14144:19;;13949:220;;;:::o;14175:118::-;14262:24;14280:5;14262:24;:::i;:::-;14257:3;14250:37;14240:53;;:::o;14299:271::-;14429:3;14451:93;14540:3;14531:6;14451:93;:::i;:::-;14444:100;;14561:3;14554:10;;14433:137;;;;:::o;14576:379::-;14760:3;14782:147;14925:3;14782:147;:::i;:::-;14775:154;;14946:3;14939:10;;14764:191;;;:::o;14961:222::-;15054:4;15092:2;15081:9;15077:18;15069:26;;15105:71;15173:1;15162:9;15158:17;15149:6;15105:71;:::i;:::-;15059:124;;;;:::o;15189:474::-;15354:4;15392:2;15381:9;15377:18;15369:26;;15405:79;15481:1;15470:9;15466:17;15457:6;15405:79;:::i;:::-;15494:80;15570:2;15559:9;15555:18;15546:6;15494:80;:::i;:::-;15584:72;15652:2;15641:9;15637:18;15628:6;15584:72;:::i;:::-;15359:304;;;;;;:::o;15669:348::-;15798:4;15836:2;15825:9;15821:18;15813:26;;15849:79;15925:1;15914:9;15910:17;15901:6;15849:79;:::i;:::-;15938:72;16006:2;15995:9;15991:18;15982:6;15938:72;:::i;:::-;15803:214;;;;;:::o;16023:332::-;16144:4;16182:2;16171:9;16167:18;16159:26;;16195:71;16263:1;16252:9;16248:17;16239:6;16195:71;:::i;:::-;16276:72;16344:2;16333:9;16329:18;16320:6;16276:72;:::i;:::-;16149:206;;;;;:::o;16361:234::-;16460:4;16498:2;16487:9;16483:18;16475:26;;16511:77;16585:1;16574:9;16570:17;16561:6;16511:77;:::i;:::-;16465:130;;;;:::o;16601:313::-;16714:4;16752:2;16741:9;16737:18;16729:26;;16801:9;16795:4;16791:20;16787:1;16776:9;16772:17;16765:47;16829:78;16902:4;16893:6;16829:78;:::i;:::-;16821:86;;16719:195;;;;:::o;16920:419::-;17086:4;17124:2;17113:9;17109:18;17101:26;;17173:9;17167:4;17163:20;17159:1;17148:9;17144:17;17137:47;17201:131;17327:4;17201:131;:::i;:::-;17193:139;;17091:248;;;:::o;17345:419::-;17511:4;17549:2;17538:9;17534:18;17526:26;;17598:9;17592:4;17588:20;17584:1;17573:9;17569:17;17562:47;17626:131;17752:4;17626:131;:::i;:::-;17618:139;;17516:248;;;:::o;17770:419::-;17936:4;17974:2;17963:9;17959:18;17951:26;;18023:9;18017:4;18013:20;18009:1;17998:9;17994:17;17987:47;18051:131;18177:4;18051:131;:::i;:::-;18043:139;;17941:248;;;:::o;18195:419::-;18361:4;18399:2;18388:9;18384:18;18376:26;;18448:9;18442:4;18438:20;18434:1;18423:9;18419:17;18412:47;18476:131;18602:4;18476:131;:::i;:::-;18468:139;;18366:248;;;:::o;18620:419::-;18786:4;18824:2;18813:9;18809:18;18801:26;;18873:9;18867:4;18863:20;18859:1;18848:9;18844:17;18837:47;18901:131;19027:4;18901:131;:::i;:::-;18893:139;;18791:248;;;:::o;19045:419::-;19211:4;19249:2;19238:9;19234:18;19226:26;;19298:9;19292:4;19288:20;19284:1;19273:9;19269:17;19262:47;19326:131;19452:4;19326:131;:::i;:::-;19318:139;;19216:248;;;:::o;19470:419::-;19636:4;19674:2;19663:9;19659:18;19651:26;;19723:9;19717:4;19713:20;19709:1;19698:9;19694:17;19687:47;19751:131;19877:4;19751:131;:::i;:::-;19743:139;;19641:248;;;:::o;19895:419::-;20061:4;20099:2;20088:9;20084:18;20076:26;;20148:9;20142:4;20138:20;20134:1;20123:9;20119:17;20112:47;20176:131;20302:4;20176:131;:::i;:::-;20168:139;;20066:248;;;:::o;20320:419::-;20486:4;20524:2;20513:9;20509:18;20501:26;;20573:9;20567:4;20563:20;20559:1;20548:9;20544:17;20537:47;20601:131;20727:4;20601:131;:::i;:::-;20593:139;;20491:248;;;:::o;20745:419::-;20911:4;20949:2;20938:9;20934:18;20926:26;;20998:9;20992:4;20988:20;20984:1;20973:9;20969:17;20962:47;21026:131;21152:4;21026:131;:::i;:::-;21018:139;;20916:248;;;:::o;21170:419::-;21336:4;21374:2;21363:9;21359:18;21351:26;;21423:9;21417:4;21413:20;21409:1;21398:9;21394:17;21387:47;21451:131;21577:4;21451:131;:::i;:::-;21443:139;;21341:248;;;:::o;21595:419::-;21761:4;21799:2;21788:9;21784:18;21776:26;;21848:9;21842:4;21838:20;21834:1;21823:9;21819:17;21812:47;21876:131;22002:4;21876:131;:::i;:::-;21868:139;;21766:248;;;:::o;22020:419::-;22186:4;22224:2;22213:9;22209:18;22201:26;;22273:9;22267:4;22263:20;22259:1;22248:9;22244:17;22237:47;22301:131;22427:4;22301:131;:::i;:::-;22293:139;;22191:248;;;:::o;22445:419::-;22611:4;22649:2;22638:9;22634:18;22626:26;;22698:9;22692:4;22688:20;22684:1;22673:9;22669:17;22662:47;22726:131;22852:4;22726:131;:::i;:::-;22718:139;;22616:248;;;:::o;22870:419::-;23036:4;23074:2;23063:9;23059:18;23051:26;;23123:9;23117:4;23113:20;23109:1;23098:9;23094:17;23087:47;23151:131;23277:4;23151:131;:::i;:::-;23143:139;;23041:248;;;:::o;23295:419::-;23461:4;23499:2;23488:9;23484:18;23476:26;;23548:9;23542:4;23538:20;23534:1;23523:9;23519:17;23512:47;23576:131;23702:4;23576:131;:::i;:::-;23568:139;;23466:248;;;:::o;23720:419::-;23886:4;23924:2;23913:9;23909:18;23901:26;;23973:9;23967:4;23963:20;23959:1;23948:9;23944:17;23937:47;24001:131;24127:4;24001:131;:::i;:::-;23993:139;;23891:248;;;:::o;24145:222::-;24238:4;24276:2;24265:9;24261:18;24253:26;;24289:71;24357:1;24346:9;24342:17;24333:6;24289:71;:::i;:::-;24243:124;;;;:::o;24373:129::-;24407:6;24434:20;;:::i;:::-;24424:30;;24463:33;24491:4;24483:6;24463:33;:::i;:::-;24414:88;;;:::o;24508:75::-;24541:6;24574:2;24568:9;24558:19;;24548:35;:::o;24589:311::-;24666:4;24756:18;24748:6;24745:30;24742:2;;;24778:18;;:::i;:::-;24742:2;24828:4;24820:6;24816:17;24808:25;;24888:4;24882;24878:15;24870:23;;24671:229;;;:::o;24906:311::-;24983:4;25073:18;25065:6;25062:30;25059:2;;;25095:18;;:::i;:::-;25059:2;25145:4;25137:6;25133:17;25125:25;;25205:4;25199;25195:15;25187:23;;24988:229;;;:::o;25223:98::-;25274:6;25308:5;25302:12;25292:22;;25281:40;;;:::o;25327:99::-;25379:6;25413:5;25407:12;25397:22;;25386:40;;;:::o;25432:147::-;25533:11;25570:3;25555:18;;25545:34;;;;:::o;25585:169::-;25669:11;25703:6;25698:3;25691:19;25743:4;25738:3;25734:14;25719:29;;25681:73;;;;:::o;25760:305::-;25800:3;25819:20;25837:1;25819:20;:::i;:::-;25814:25;;25853:20;25871:1;25853:20;:::i;:::-;25848:25;;26007:1;25939:66;25935:74;25932:1;25929:81;25926:2;;;26013:18;;:::i;:::-;25926:2;26057:1;26054;26050:9;26043:16;;25804:261;;;;:::o;26071:185::-;26111:1;26128:20;26146:1;26128:20;:::i;:::-;26123:25;;26162:20;26180:1;26162:20;:::i;:::-;26157:25;;26201:1;26191:2;;26206:18;;:::i;:::-;26191:2;26248:1;26245;26241:9;26236:14;;26113:143;;;;:::o;26262:348::-;26302:7;26325:20;26343:1;26325:20;:::i;:::-;26320:25;;26359:20;26377:1;26359:20;:::i;:::-;26354:25;;26547:1;26479:66;26475:74;26472:1;26469:81;26464:1;26457:9;26450:17;26446:105;26443:2;;;26554:18;;:::i;:::-;26443:2;26602:1;26599;26595:9;26584:20;;26310:300;;;;:::o;26616:191::-;26656:4;26676:20;26694:1;26676:20;:::i;:::-;26671:25;;26710:20;26728:1;26710:20;:::i;:::-;26705:25;;26749:1;26746;26743:8;26740:2;;;26754:18;;:::i;:::-;26740:2;26799:1;26796;26792:9;26784:17;;26661:146;;;;:::o;26813:96::-;26850:7;26879:24;26897:5;26879:24;:::i;:::-;26868:35;;26858:51;;;:::o;26915:104::-;26960:7;26989:24;27007:5;26989:24;:::i;:::-;26978:35;;26968:51;;;:::o;27025:90::-;27059:7;27102:5;27095:13;27088:21;27077:32;;27067:48;;;:::o;27121:121::-;27183:7;27212:24;27230:5;27212:24;:::i;:::-;27201:35;;27191:51;;;:::o;27248:126::-;27285:7;27325:42;27318:5;27314:54;27303:65;;27293:81;;;:::o;27380:77::-;27417:7;27446:5;27435:16;;27425:32;;;:::o;27463:86::-;27498:7;27538:4;27531:5;27527:16;27516:27;;27506:43;;;:::o;27555:134::-;27613:9;27646:37;27677:5;27646:37;:::i;:::-;27633:50;;27623:66;;;:::o;27695:117::-;27751:9;27784:22;27800:5;27784:22;:::i;:::-;27771:35;;27761:51;;;:::o;27818:126::-;27868:9;27901:37;27932:5;27901:37;:::i;:::-;27888:50;;27878:66;;;:::o;27950:113::-;28000:9;28033:24;28051:5;28033:24;:::i;:::-;28020:37;;28010:53;;;:::o;28069:307::-;28137:1;28147:113;28161:6;28158:1;28155:13;28147:113;;;28246:1;28241:3;28237:11;28231:18;28227:1;28222:3;28218:11;28211:39;28183:2;28180:1;28176:10;28171:15;;28147:113;;;28278:6;28275:1;28272:13;28269:2;;;28358:1;28349:6;28344:3;28340:16;28333:27;28269:2;28118:258;;;;:::o;28382:281::-;28465:27;28487:4;28465:27;:::i;:::-;28457:6;28453:40;28595:6;28583:10;28580:22;28559:18;28547:10;28544:34;28541:62;28538:2;;;28606:18;;:::i;:::-;28538:2;28646:10;28642:2;28635:22;28425:238;;;:::o;28669:233::-;28708:3;28731:24;28749:5;28731:24;:::i;:::-;28722:33;;28777:66;28770:5;28767:77;28764:2;;;28847:18;;:::i;:::-;28764:2;28894:1;28887:5;28883:13;28876:20;;28712:190;;;:::o;28908:180::-;28956:77;28953:1;28946:88;29053:4;29050:1;29043:15;29077:4;29074:1;29067:15;29094:180;29142:77;29139:1;29132:88;29239:4;29236:1;29229:15;29263:4;29260:1;29253:15;29280:180;29328:77;29325:1;29318:88;29425:4;29422:1;29415:15;29449:4;29446:1;29439:15;29466:102;29507:6;29558:2;29554:7;29549:2;29542:5;29538:14;29534:28;29524:38;;29514:54;;;:::o;29574:291::-;29714:34;29710:1;29702:6;29698:14;29691:58;29783:34;29778:2;29770:6;29766:15;29759:59;29852:5;29847:2;29839:6;29835:15;29828:30;29680:185;:::o;29871:231::-;30011:34;30007:1;29999:6;29995:14;29988:58;30080:14;30075:2;30067:6;30063:15;30056:39;29977:125;:::o;30108:225::-;30248:34;30244:1;30236:6;30232:14;30225:58;30317:8;30312:2;30304:6;30300:15;30293:33;30214:119;:::o;30339:225::-;30479:34;30475:1;30467:6;30463:14;30456:58;30548:8;30543:2;30535:6;30531:15;30524:33;30445:119;:::o;30570:245::-;30710:34;30706:1;30698:6;30694:14;30687:58;30779:28;30774:2;30766:6;30762:15;30755:53;30676:139;:::o;30821:179::-;30961:31;30957:1;30949:6;30945:14;30938:55;30927:73;:::o;31006:225::-;31146:34;31142:1;31134:6;31130:14;31123:58;31215:8;31210:2;31202:6;31198:15;31191:33;31112:119;:::o;31237:230::-;31377:34;31373:1;31365:6;31361:14;31354:58;31446:13;31441:2;31433:6;31429:15;31422:38;31343:124;:::o;31473:233::-;31613:34;31609:1;31601:6;31597:14;31590:58;31682:16;31677:2;31669:6;31665:15;31658:41;31579:127;:::o;31712:182::-;31852:34;31848:1;31840:6;31836:14;31829:58;31818:76;:::o;31900:237::-;32040:34;32036:1;32028:6;32024:14;32017:58;32109:20;32104:2;32096:6;32092:15;32085:45;32006:131;:::o;32143:114::-;32249:8;:::o;32263:179::-;32403:31;32399:1;32391:6;32387:14;32380:55;32369:73;:::o;32448:230::-;32588:34;32584:1;32576:6;32572:14;32565:58;32657:13;32652:2;32644:6;32640:15;32633:38;32554:124;:::o;32684:230::-;32824:34;32820:1;32812:6;32808:14;32801:58;32893:13;32888:2;32880:6;32876:15;32869:38;32790:124;:::o;32920:229::-;33060:34;33056:1;33048:6;33044:14;33037:58;33129:12;33124:2;33116:6;33112:15;33105:37;33026:123;:::o;33155:176::-;33295:28;33291:1;33283:6;33279:14;33272:52;33261:70;:::o;33337:179::-;33477:31;33473:1;33465:6;33461:14;33454:55;33443:73;:::o;33522:122::-;33595:24;33613:5;33595:24;:::i;:::-;33588:5;33585:35;33575:2;;33634:1;33631;33624:12;33575:2;33565:79;:::o;33650:138::-;33731:32;33757:5;33731:32;:::i;:::-;33724:5;33721:43;33711:2;;33778:1;33775;33768:12;33711:2;33701:87;:::o;33794:116::-;33864:21;33879:5;33864:21;:::i;:::-;33857:5;33854:32;33844:2;;33900:1;33897;33890:12;33844:2;33834:76;:::o;33916:172::-;34014:49;34057:5;34014:49;:::i;:::-;34007:5;34004:60;33994:2;;34078:1;34075;34068:12;33994:2;33984:104;:::o;34094:122::-;34167:24;34185:5;34167:24;:::i;:::-;34160:5;34157:35;34147:2;;34206:1;34203;34196:12;34147:2;34137:79;:::o
Swarm Source
ipfs://8ab40d3eb99dbb48fc9dc35e9321ceb350035bc039681d515cbd05d355a47921
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 33 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.