Source Code
Overview
ETH Balance
ETH Value
$0.00Latest 25 from a total of 89 transactions
| Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
|---|---|---|---|---|---|---|---|---|---|
| Swap And Deposit | 11514794 | 419 days ago | IN | 0.01559 ETH | 0.00002818 | ||||
| Swap And Deposit | 11514297 | 419 days ago | IN | 0.0149 ETH | 0.00003199 | ||||
| Swap And Deposit | 11511680 | 419 days ago | IN | 0.0071 ETH | 0.00002175 | ||||
| Swap And Deposit | 11510810 | 419 days ago | IN | 0.0153 ETH | 0.00005647 | ||||
| Swap And Deposit | 11509844 | 419 days ago | IN | 0 ETH | 0.00001905 | ||||
| Swap And Deposit | 11505837 | 419 days ago | IN | 0.001 ETH | 0.00005033 | ||||
| Swap And Deposit | 11504455 | 419 days ago | IN | 0.0048 ETH | 0.0000451 | ||||
| Swap And Deposit | 11502957 | 419 days ago | IN | 0.0048 ETH | 0.00003103 | ||||
| Swap And Deposit | 11501201 | 419 days ago | IN | 0 ETH | 0.00005043 | ||||
| Swap And Deposit | 11500912 | 419 days ago | IN | 0.00045 ETH | 0.00002769 | ||||
| Swap And Deposit | 11499447 | 419 days ago | IN | 0 ETH | 0.00004031 | ||||
| Swap And Deposit | 11498136 | 419 days ago | IN | 0.0003 ETH | 0.00008939 | ||||
| Swap And Deposit | 11491006 | 420 days ago | IN | 0.002 ETH | 0.00002429 | ||||
| Swap And Deposit | 11490511 | 420 days ago | IN | 0.0018 ETH | 0.00004231 | ||||
| Swap And Deposit | 11488986 | 420 days ago | IN | 0 ETH | 0.00003579 | ||||
| Swap And Deposit | 11483871 | 420 days ago | IN | 0.015 ETH | 0.0001693 | ||||
| Swap In Same Cha... | 11476764 | 420 days ago | IN | 0 ETH | 0.00008287 | ||||
| Swap In Same Cha... | 11476529 | 420 days ago | IN | 0 ETH | 0.00008154 | ||||
| Swap In Same Cha... | 11476193 | 420 days ago | IN | 0 ETH | 0.00008089 | ||||
| Swap In Same Cha... | 11474718 | 420 days ago | IN | 0 ETH | 0.00042578 | ||||
| Swap And Deposit | 11471756 | 420 days ago | IN | 0 ETH | 0.00010544 | ||||
| Swap And Deposit | 11471574 | 420 days ago | IN | 0 ETH | 0.00010557 | ||||
| Swap And Deposit | 11471312 | 420 days ago | IN | 0 ETH | 0.00009168 | ||||
| Swap In Same Cha... | 11469194 | 420 days ago | IN | 0 ETH | 0.00004083 | ||||
| Swap In Same Cha... | 11469167 | 420 days ago | IN | 0 ETH | 0.00002517 |
Latest 25 internal transactions (View All)
Advanced mode:
| Parent Transaction Hash | Block | From | To | |||
|---|---|---|---|---|---|---|
| 11514794 | 419 days ago | 0.01559 ETH | ||||
| 11514297 | 419 days ago | 0.0149 ETH | ||||
| 11511680 | 419 days ago | 0.0071 ETH | ||||
| 11510810 | 419 days ago | 0.0153 ETH | ||||
| 11505837 | 419 days ago | 0.001 ETH | ||||
| 11504455 | 419 days ago | 0.0048 ETH | ||||
| 11502957 | 419 days ago | 0.0048 ETH | ||||
| 11500912 | 419 days ago | 0.00045 ETH | ||||
| 11498136 | 419 days ago | 0.0003 ETH | ||||
| 11491006 | 420 days ago | 0.002 ETH | ||||
| 11490511 | 420 days ago | 0.0018 ETH | ||||
| 11483871 | 420 days ago | 0.015 ETH | ||||
| 11476764 | 420 days ago | 0.0009531 ETH | ||||
| 11476764 | 420 days ago | 0.0009531 ETH | ||||
| 11476529 | 420 days ago | 0.00039683 ETH | ||||
| 11476529 | 420 days ago | 0.00039683 ETH | ||||
| 11476193 | 420 days ago | 0.00073814 ETH | ||||
| 11476193 | 420 days ago | 0.00073814 ETH | ||||
| 11474718 | 420 days ago | 0.00027688 ETH | ||||
| 11474718 | 420 days ago | 0.00027688 ETH | ||||
| 11469194 | 420 days ago | 0.00030106 ETH | ||||
| 11469194 | 420 days ago | 0.00030106 ETH | ||||
| 11469140 | 420 days ago | 0.00027868 ETH | ||||
| 11469140 | 420 days ago | 0.00027868 ETH | ||||
| 11452544 | 421 days ago | 0.00093367 ETH |
Cross-Chain Transactions
Loading...
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.
Contract Name:
DexSpan
Compiler Version
v0.8.21+commit.d9974bed
Contract Source Code (Solidity)
/**
*Submitted for verification at scrollscan.com on 2024-11-21
*/
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0 ^0.8.1 ^0.8.2 ^0.8.20;
// contracts/dexspan/interface/IAugustusSwapper.sol
interface IAugustusSwapper {
function getTokenTransferProxy() external view returns (address);
}
// contracts/dexspan/interface/IEthHandler.sol
interface IEthHandler {
function withdraw(address WETH, uint256) external;
}
// contracts/dexspan/interface/IHandlerReserve.sol
interface IHandlerReserve {
function _lpToContract(address token) external returns (address);
function _contractToLP(address token) external returns (address);
}
// contracts/dexspan/libraries/TransferHelper.sol
// helper methods for interacting with ERC20 tokens and sending ETH that do not consistently return true/false
library TransferHelper {
function safeApprove(address token, address to, uint256 value) internal {
// bytes4(keccak256(bytes('approve(address,uint256)')));
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0x095ea7b3, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper::safeApprove: approve failed"
);
}
function safeTransfer(address token, address to, uint256 value) internal {
// bytes4(keccak256(bytes('transfer(address,uint256)')));
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0xa9059cbb, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper::safeTransfer: transfer failed"
);
}
function safeTransferFrom(
address token,
address from,
address to,
uint256 value
) internal {
// bytes4(keccak256(bytes('transferFrom(address,address,uint256)')));
(bool success, bytes memory data) = token.call(
abi.encodeWithSelector(0x23b872dd, from, to, value)
);
require(
success && (data.length == 0 || abi.decode(data, (bool))),
"TransferHelper::transferFrom: transferFrom failed"
);
}
}
// contracts/interfaces/IAssetForwarder.sol
/// @title Interface for handler contracts that support deposits and deposit executions.
/// @author Router Protocol.
interface IAssetForwarder {
event FundsDeposited(
uint256 partnerId,
uint256 amount,
bytes32 destChainIdBytes,
uint256 destAmount,
uint256 depositId,
address srcToken,
address depositor,
bytes recipient,
bytes destToken
);
event FundsDepositedWithMessage(
uint256 partnerId,
uint256 amount,
bytes32 destChainIdBytes,
uint256 destAmount,
uint256 depositId,
address srcToken,
bytes recipient,
address depositor,
bytes destToken,
bytes message
);
event FundsPaid(bytes32 messageHash, address forwarder, uint256 nonce);
event DepositInfoUpdate(
address srcToken,
uint256 feeAmount,
uint256 depositId,
uint256 eventNonce,
bool initiatewithdrawal,
address depositor
);
event FundsPaidWithMessage(
bytes32 messageHash,
address forwarder,
uint256 nonce,
bool execFlag,
bytes execData
);
struct RelayData {
uint256 amount;
bytes32 srcChainId;
uint256 depositId;
address destToken;
address recipient;
}
struct RelayDataMessage {
uint256 amount;
bytes32 srcChainId;
uint256 depositId;
address destToken;
address recipient;
bytes message;
}
struct DepositData {
uint256 partnerId;
uint256 amount;
uint256 destAmount;
address srcToken;
address refundRecipient;
bytes32 destChainIdBytes;
}
function iDeposit(
DepositData memory depositData,
bytes memory destToken,
bytes memory recipient
) external payable;
function iDepositInfoUpdate(
address srcToken,
uint256 feeAmount,
uint256 depositId,
bool initiatewithdrawal
) external payable;
function iDepositMessage(
DepositData memory depositData,
bytes memory destToken,
bytes memory recipient,
bytes memory message
) external payable;
function iRelay(RelayData memory relayData) external payable;
function iRelayMessage(RelayDataMessage memory relayData) external payable;
}
// contracts/interfaces/IMessageHandler.sol
/// @title Handles ERC20 deposits and deposit executions.
/// @author Router Protocol.
/// @notice This contract is intended to be used with the Bridge contract.
interface IMessageHandler {
function handleMessage(
address tokenSent,
uint256 amount,
bytes memory message
) external;
}
// node_modules/@openzeppelin/contracts/access/IAccessControl.sol
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)
/**
* @dev External interface of AccessControl declared to support ERC165 detection.
*/
interface IAccessControl {
/**
* @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
*
* `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
* {RoleAdminChanged} not being emitted signaling this.
*
* _Available since v3.1._
*/
event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);
/**
* @dev Emitted when `account` is granted `role`.
*
* `sender` is the account that originated the contract call, an admin role
* bearer except when using {AccessControl-_setupRole}.
*/
event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Emitted when `account` is revoked `role`.
*
* `sender` is the account that originated the contract call:
* - if using `revokeRole`, it is the admin role bearer
* - if using `renounceRole`, it is the role bearer (i.e. `account`)
*/
event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) external view returns (bool);
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {AccessControl-_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) external view returns (bytes32);
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function grantRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*/
function revokeRole(bytes32 role, address account) external;
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been granted `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*/
function renounceRole(bytes32 role, address account) external;
}
// node_modules/@openzeppelin/contracts/token/ERC20/IERC20.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/IERC20.sol)
/**
* @dev Interface of the ERC20 standard as defined in the EIP.
*/
interface IERC20 {
/**
* @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);
}
// node_modules/@openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/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 IERC20Permit {
/**
* @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);
}
// node_modules/@openzeppelin/contracts/utils/Address.sol
// OpenZeppelin Contracts (last updated v4.9.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
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [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://consensys.net/diligence/blog/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.8.0/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);
}
}
}
// node_modules/@openzeppelin/contracts/utils/Context.sol
// 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 Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// node_modules/@openzeppelin/contracts/utils/introspection/IERC165.sol
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}
// node_modules/@openzeppelin/contracts/utils/math/Math.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library Math {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
// node_modules/@openzeppelin/contracts/utils/math/SafeMath.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMath {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
// node_modules/@openzeppelin/contracts/utils/math/SignedMath.sol
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)
/**
* @dev Standard signed math utilities missing in the Solidity language.
*/
library SignedMath {
/**
* @dev Returns the largest of two signed numbers.
*/
function max(int256 a, int256 b) internal pure returns (int256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two signed numbers.
*/
function min(int256 a, int256 b) internal pure returns (int256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two signed numbers without overflow.
* The result is rounded towards zero.
*/
function average(int256 a, int256 b) internal pure returns (int256) {
// Formula from the book "Hacker's Delight"
int256 x = (a & b) + ((a ^ b) >> 1);
return x + (int256(uint256(x) >> 255) & (a ^ b));
}
/**
* @dev Returns the absolute unsigned value of a signed value.
*/
function abs(int256 n) internal pure returns (uint256) {
unchecked {
// must be unchecked in order to support `n = type(int256).min`
return uint256(n >= 0 ? n : -n);
}
}
}
// node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/IERC20Upgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.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);
}
// node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/extensions/IERC20PermitUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/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);
}
// node_modules/@openzeppelin/contracts-upgradeable/utils/AddressUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Address.sol)
/**
* @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
*
* Furthermore, `isContract` will also return true if the target contract within
* the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
* which only has an effect at the end of a transaction.
* ====
*
* [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://consensys.net/diligence/blog/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.8.0/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);
}
}
}
// node_modules/@openzeppelin/contracts-upgradeable/utils/math/MathUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)
/**
* @dev Standard math utilities missing in the Solidity language.
*/
library MathUpgradeable {
enum Rounding {
Down, // Toward negative infinity
Up, // Toward infinity
Zero // Toward zero
}
/**
* @dev Returns the largest of two numbers.
*/
function max(uint256 a, uint256 b) internal pure returns (uint256) {
return a > b ? a : b;
}
/**
* @dev Returns the smallest of two numbers.
*/
function min(uint256 a, uint256 b) internal pure returns (uint256) {
return a < b ? a : b;
}
/**
* @dev Returns the average of two numbers. The result is rounded towards
* zero.
*/
function average(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b) / 2 can overflow.
return (a & b) + (a ^ b) / 2;
}
/**
* @dev Returns the ceiling of the division of two numbers.
*
* This differs from standard division with `/` in that it rounds up instead
* of rounding down.
*/
function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
// (a + b - 1) / b can overflow on addition, so we distribute.
return a == 0 ? 0 : (a - 1) / b + 1;
}
/**
* @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
* @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
* with further edits by Uniswap Labs also under MIT license.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
unchecked {
// 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
// use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
// variables such that product = prod1 * 2^256 + prod0.
uint256 prod0; // Least significant 256 bits of the product
uint256 prod1; // Most significant 256 bits of the product
assembly {
let mm := mulmod(x, y, not(0))
prod0 := mul(x, y)
prod1 := sub(sub(mm, prod0), lt(mm, prod0))
}
// Handle non-overflow cases, 256 by 256 division.
if (prod1 == 0) {
// Solidity will revert if denominator == 0, unlike the div opcode on its own.
// The surrounding unchecked block does not change this fact.
// See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
return prod0 / denominator;
}
// Make sure the result is less than 2^256. Also prevents denominator == 0.
require(denominator > prod1, "Math: mulDiv overflow");
///////////////////////////////////////////////
// 512 by 256 division.
///////////////////////////////////////////////
// Make division exact by subtracting the remainder from [prod1 prod0].
uint256 remainder;
assembly {
// Compute remainder using mulmod.
remainder := mulmod(x, y, denominator)
// Subtract 256 bit number from 512 bit number.
prod1 := sub(prod1, gt(remainder, prod0))
prod0 := sub(prod0, remainder)
}
// Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
// See https://cs.stackexchange.com/q/138556/92363.
// Does not overflow because the denominator cannot be zero at this stage in the function.
uint256 twos = denominator & (~denominator + 1);
assembly {
// Divide denominator by twos.
denominator := div(denominator, twos)
// Divide [prod1 prod0] by twos.
prod0 := div(prod0, twos)
// Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
twos := add(div(sub(0, twos), twos), 1)
}
// Shift in bits from prod1 into prod0.
prod0 |= prod1 * twos;
// Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
// that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
// four bits. That is, denominator * inv = 1 mod 2^4.
uint256 inverse = (3 * denominator) ^ 2;
// Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
// in modular arithmetic, doubling the correct bits in each step.
inverse *= 2 - denominator * inverse; // inverse mod 2^8
inverse *= 2 - denominator * inverse; // inverse mod 2^16
inverse *= 2 - denominator * inverse; // inverse mod 2^32
inverse *= 2 - denominator * inverse; // inverse mod 2^64
inverse *= 2 - denominator * inverse; // inverse mod 2^128
inverse *= 2 - denominator * inverse; // inverse mod 2^256
// Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
// This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
// less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
// is no longer required.
result = prod0 * inverse;
return result;
}
}
/**
* @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
*/
function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
uint256 result = mulDiv(x, y, denominator);
if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
result += 1;
}
return result;
}
/**
* @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
*
* Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
*/
function sqrt(uint256 a) internal pure returns (uint256) {
if (a == 0) {
return 0;
}
// For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
//
// We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
// `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
//
// This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
// → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
// → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
//
// Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
uint256 result = 1 << (log2(a) >> 1);
// At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
// since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
// every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
// into the expected uint128 result.
unchecked {
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
result = (result + a / result) >> 1;
return min(result, a / result);
}
}
/**
* @notice Calculates sqrt(a), following the selected rounding direction.
*/
function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = sqrt(a);
return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
}
}
/**
* @dev Return the log in base 2, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 128;
}
if (value >> 64 > 0) {
value >>= 64;
result += 64;
}
if (value >> 32 > 0) {
value >>= 32;
result += 32;
}
if (value >> 16 > 0) {
value >>= 16;
result += 16;
}
if (value >> 8 > 0) {
value >>= 8;
result += 8;
}
if (value >> 4 > 0) {
value >>= 4;
result += 4;
}
if (value >> 2 > 0) {
value >>= 2;
result += 2;
}
if (value >> 1 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 2, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log2(value);
return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 10, rounded down, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >= 10 ** 64) {
value /= 10 ** 64;
result += 64;
}
if (value >= 10 ** 32) {
value /= 10 ** 32;
result += 32;
}
if (value >= 10 ** 16) {
value /= 10 ** 16;
result += 16;
}
if (value >= 10 ** 8) {
value /= 10 ** 8;
result += 8;
}
if (value >= 10 ** 4) {
value /= 10 ** 4;
result += 4;
}
if (value >= 10 ** 2) {
value /= 10 ** 2;
result += 2;
}
if (value >= 10 ** 1) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 10, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log10(value);
return result + (rounding == Rounding.Up && 10 ** result < value ? 1 : 0);
}
}
/**
* @dev Return the log in base 256, rounded down, of a positive value.
* Returns 0 if given 0.
*
* Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
*/
function log256(uint256 value) internal pure returns (uint256) {
uint256 result = 0;
unchecked {
if (value >> 128 > 0) {
value >>= 128;
result += 16;
}
if (value >> 64 > 0) {
value >>= 64;
result += 8;
}
if (value >> 32 > 0) {
value >>= 32;
result += 4;
}
if (value >> 16 > 0) {
value >>= 16;
result += 2;
}
if (value >> 8 > 0) {
result += 1;
}
}
return result;
}
/**
* @dev Return the log in base 256, following the selected rounding direction, of a positive value.
* Returns 0 if given 0.
*/
function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
unchecked {
uint256 result = log256(value);
return result + (rounding == Rounding.Up && 1 << (result << 3) < value ? 1 : 0);
}
}
}
// node_modules/@openzeppelin/contracts-upgradeable/utils/math/SafeMathUpgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/SafeMath.sol)
// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.
/**
* @dev Wrappers over Solidity's arithmetic operations.
*
* NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
* now has built in overflow checking.
*/
library SafeMathUpgradeable {
/**
* @dev Returns the addition of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
uint256 c = a + b;
if (c < a) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the subtraction of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b > a) return (false, 0);
return (true, a - b);
}
}
/**
* @dev Returns the multiplication of two unsigned integers, with an overflow flag.
*
* _Available since v3.4._
*/
function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
// Gas optimization: this is cheaper than requiring 'a' not being zero, but the
// benefit is lost if 'b' is also tested.
// See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
if (a == 0) return (true, 0);
uint256 c = a * b;
if (c / a != b) return (false, 0);
return (true, c);
}
}
/**
* @dev Returns the division of two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a / b);
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
*
* _Available since v3.4._
*/
function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
unchecked {
if (b == 0) return (false, 0);
return (true, a % b);
}
}
/**
* @dev Returns the addition of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `+` operator.
*
* Requirements:
*
* - Addition cannot overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256) {
return a + b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting on
* overflow (when the result is negative).
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
return a - b;
}
/**
* @dev Returns the multiplication of two unsigned integers, reverting on
* overflow.
*
* Counterpart to Solidity's `*` operator.
*
* Requirements:
*
* - Multiplication cannot overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256) {
return a * b;
}
/**
* @dev Returns the integer division of two unsigned integers, reverting on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator.
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
return a / b;
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting when dividing by zero.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b) internal pure returns (uint256) {
return a % b;
}
/**
* @dev Returns the subtraction of two unsigned integers, reverting with custom message on
* overflow (when the result is negative).
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {trySub}.
*
* Counterpart to Solidity's `-` operator.
*
* Requirements:
*
* - Subtraction cannot overflow.
*/
function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b <= a, errorMessage);
return a - b;
}
}
/**
* @dev Returns the integer division of two unsigned integers, reverting with custom message on
* division by zero. The result is rounded towards zero.
*
* Counterpart to Solidity's `/` operator. Note: this function uses a
* `revert` opcode (which leaves remaining gas untouched) while Solidity
* uses an invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a / b;
}
}
/**
* @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
* reverting with custom message when dividing by zero.
*
* CAUTION: This function is deprecated because it requires allocating memory for the error
* message unnecessarily. For custom revert reasons use {tryMod}.
*
* Counterpart to Solidity's `%` operator. This function uses a `revert`
* opcode (which leaves remaining gas untouched) while Solidity uses an
* invalid opcode to revert (consuming all remaining gas).
*
* Requirements:
*
* - The divisor cannot be zero.
*/
function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
unchecked {
require(b > 0, errorMessage);
return a % b;
}
}
}
// contracts/dexspan/IDexSpan.sol
contract DexSpanFlags {
// flags = FLAG_DISABLE_UNISWAP + FLAG_DISABLE_BANCOR + ...
uint256 internal constant FLAG_DISABLE_UNISWAP = 0x400;
uint256 internal constant FLAG_DISABLE_SPLIT_RECALCULATION = 0x800000000000;
uint256 internal constant FLAG_DISABLE_ALL_SPLIT_SOURCES = 0x20000000;
uint256 internal constant FLAG_DISABLE_UNISWAP_V2_ALL = 0x400;
uint256 internal constant FLAG_DISABLE_EMPTY = 0x100000000000;
uint256 internal constant FLAG_DISABLE_DFYN = 0x800;
uint256 internal constant FLAG_DISABLE_PANCAKESWAP = 0x80;
uint256 internal constant FLAG_DISABLE_QUICKSWAP = 0x40000000000;
uint256 internal constant FLAG_DISABLE_SUSHISWAP = 0x1000000;
uint256 internal constant FLAG_DISABLE_ONEINCH = 0x100000;
}
abstract contract IDexSpan is DexSpanFlags {
function getExpectedReturn(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
uint256 parts,
uint256 flags // See constants in IOneSplit.sol
)
public
view
virtual
returns (uint256 returnAmount, uint256[] memory distribution);
function getExpectedReturnWithGasMulti(
IERC20Upgradeable[] memory tokens,
uint256 amount,
uint256[] memory parts,
uint256[] memory flags,
uint256[] memory destTokenEthPriceTimesGasPrices
)
public
view
virtual
returns (
uint256[] memory returnAmounts,
uint256 estimateGasAmount,
uint256[] memory distribution
);
function getExpectedReturnWithGas(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
uint256 parts,
uint256 flags, // See constants in IOneSplit.sol
uint256 destTokenEthPriceTimesGasPrice
)
public
view
virtual
returns (
uint256 returnAmount,
uint256 estimateGasAmount,
uint256[] memory distribution
);
function setHandlerAddress(
address _handlerAddress
) external virtual returns (bool);
function setReserveAddress(
address _reserveAddress
) external virtual returns (bool);
function setBridgeAddress(
address _bridgeAddress
) external virtual returns (bool);
function withdraw(
address tokenAddress,
address recipient,
uint256 amount
) public payable virtual returns (bool);
function swap(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
uint256 minReturn,
uint256 flags,
bytes memory dataTx,
bool isWrapper
) public payable virtual returns (uint256 returnAmount);
function swapWithRecipient(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
uint256 minReturn,
uint256 flags,
bytes memory dataTx,
bool isWrapper,
address recipient
) public payable virtual returns (uint256 returnAmount);
function swapMulti(
IERC20Upgradeable[] memory tokens,
uint256 amount,
uint256 minReturn,
uint256[] memory flags,
bytes[] memory dataTx,
bool isWrapper
) public payable virtual returns (uint256 returnAmount);
function swapMultiWithRecipient(
IERC20Upgradeable[] memory tokens,
uint256 amount,
uint256 minReturn,
uint256[] memory flags,
bytes[] memory dataTx,
bool isWrapper,
address recipient
) public payable virtual returns (uint256 returnAmount);
function getExpectedReturnETH(
IERC20Upgradeable srcStablefromtoken,
uint256 srcStableFromTokenAmount,
uint256 parts,
uint256 flags
) public view virtual returns (uint256 returnAmount);
function swapInSameChain(
address[] memory tokens,
uint256 amount,
uint256 minReturn,
uint256[] memory flags,
bytes[] memory dataTx,
bool isWrapper,
address recipient,
uint256 widgetID
) public payable virtual returns (uint256 returnAmount);
}
// contracts/dexspan/interface/IUniswapExchange.sol
interface IUniswapExchange {
function getEthToTokenInputPrice(
uint256 ethSold
) external view returns (uint256 tokensBought);
function getTokenToEthInputPrice(
uint256 tokensSold
) external view returns (uint256 ethBought);
function ethToTokenSwapInput(
uint256 minTokens,
uint256 deadline
) external payable returns (uint256 tokensBought);
function tokenToEthSwapInput(
uint256 tokensSold,
uint256 minEth,
uint256 deadline
) external returns (uint256 ethBought);
function tokenToTokenSwapInput(
uint256 tokensSold,
uint256 minTokensBought,
uint256 minEthBought,
uint256 deadline,
address tokenAddr
) external returns (uint256 tokensBought);
}
// contracts/dexspan/interface/IWETH.sol
abstract contract IWETH is IERC20Upgradeable {
function deposit() external payable virtual;
function withdraw(uint256 amount) external virtual;
}
// node_modules/@openzeppelin/contracts/access/Ownable.sol
// OpenZeppelin Contracts (last updated v4.9.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 Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_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. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby disabling any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
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);
}
}
// node_modules/@openzeppelin/contracts/utils/Multicall.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Multicall.sol)
/**
* @dev Provides a function to batch together multiple calls in a single external call.
*
* _Available since v4.1._
*/
abstract contract Multicall_0 {
/**
* @dev Receives and executes a batch of function calls on this contract.
* @custom:oz-upgrades-unsafe-allow-reachable delegatecall
*/
function multicall(bytes[] calldata data) external virtual returns (bytes[] memory results) {
results = new bytes[](data.length);
for (uint256 i = 0; i < data.length; i++) {
results[i] = Address.functionDelegateCall(address(this), data[i]);
}
return results;
}
}
// node_modules/@openzeppelin/contracts/utils/introspection/ERC165.sol
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)
/**
* @dev Implementation of the {IERC165} interface.
*
* Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
* for the additional interface id that will be supported. For example:
*
* ```solidity
* function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
* return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
* }
* ```
*
* Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
*/
abstract contract ERC165 is IERC165 {
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IERC165).interfaceId;
}
}
// node_modules/@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol
// OpenZeppelin Contracts (last updated v4.9.0) (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]
* ```solidity
* contract MyToken is ERC20Upgradeable {
* function initialize() initializer public {
* __ERC20_init("MyToken", "MTK");
* }
* }
*
* contract MyTokenV2 is MyToken, ERC20PermitUpgradeable {
* function initializeV2() reinitializer(2) public {
* __ERC20Permit_init("MyToken");
* }
* }
* ```
*
* TIP: To avoid leaving the proxy in an uninitialized state, the initializer function should be called as early as
* possible by providing the encoded function call as the `_data` argument to {ERC1967Proxy-constructor}.
*
* CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure
* that all initializers are idempotent. This is not verified automatically as constructors are by Solidity.
*
* [CAUTION]
* ====
* Avoid leaving a contract uninitialized.
*
* An uninitialized contract can be taken over by an attacker. This applies to both a proxy and its implementation
* contract, which may impact the proxy. To prevent the implementation contract from being used, you should invoke
* the {_disableInitializers} function in the constructor to automatically lock it when it is deployed:
*
* [.hljs-theme-light.nopadding]
* ```
* /// @custom:oz-upgrades-unsafe-allow constructor
* constructor() {
* _disableInitializers();
* }
* ```
* ====
*/
abstract contract Initializable {
/**
* @dev 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;
}
}
// contracts/dexspan/interface/IUniswapFactory.sol
interface IUniswapFactory {
function getExchange(
IERC20Upgradeable token
) external view returns (IUniswapExchange exchange);
}
// contracts/dexspan/libraries/Multicall.sol
/// @notice Helper utility that enables calling multiple local methods in a single call.
/// @author Modified from Uniswap (https://github.com/Uniswap/v3-periphery/blob/main/contracts/base/Multicall.sol)
/// License-Identifier: GPL-2.0-or-later
abstract contract Multicall_1 is Initializable {
function __Multicall_init() internal onlyInitializing {}
function __Multicall_init_unchained() internal onlyInitializing {}
function multicall(
bytes[] calldata data
) public payable returns (bytes[] memory results) {
results = new bytes[](data.length);
for (uint256 i; i < data.length; ) {
(bool success, bytes memory result) = address(this).delegatecall(
data[i]
);
if (!success) {
// Next 5 lines from https://ethereum.stackexchange.com/a/83577
if (result.length < 68) revert();
assembly {
result := add(result, 0x04)
}
revert(abi.decode(result, (string)));
}
results[i] = result;
// cannot realistically overflow on human timescales
unchecked {
++i;
}
}
}
}
// node_modules/@openzeppelin/contracts/utils/Strings.sol
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)
/**
* @dev String operations.
*/
library Strings {
bytes16 private constant _SYMBOLS = "0123456789abcdef";
uint8 private constant _ADDRESS_LENGTH = 20;
/**
* @dev Converts a `uint256` to its ASCII `string` decimal representation.
*/
function toString(uint256 value) internal pure returns (string memory) {
unchecked {
uint256 length = Math.log10(value) + 1;
string memory buffer = new string(length);
uint256 ptr;
/// @solidity memory-safe-assembly
assembly {
ptr := add(buffer, add(32, length))
}
while (true) {
ptr--;
/// @solidity memory-safe-assembly
assembly {
mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
}
value /= 10;
if (value == 0) break;
}
return buffer;
}
}
/**
* @dev Converts a `int256` to its ASCII `string` decimal representation.
*/
function toString(int256 value) internal pure returns (string memory) {
return string(abi.encodePacked(value < 0 ? "-" : "", toString(SignedMath.abs(value))));
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
*/
function toHexString(uint256 value) internal pure returns (string memory) {
unchecked {
return toHexString(value, Math.log256(value) + 1);
}
}
/**
* @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
*/
function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
bytes memory buffer = new bytes(2 * length + 2);
buffer[0] = "0";
buffer[1] = "x";
for (uint256 i = 2 * length + 1; i > 1; --i) {
buffer[i] = _SYMBOLS[value & 0xf];
value >>= 4;
}
require(value == 0, "Strings: hex length insufficient");
return string(buffer);
}
/**
* @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
*/
function toHexString(address addr) internal pure returns (string memory) {
return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
}
/**
* @dev Returns true if the two strings are equal.
*/
function equal(string memory a, string memory b) internal pure returns (bool) {
return keccak256(bytes(a)) == keccak256(bytes(b));
}
}
// node_modules/@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
/**
* @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 SafeERC20 {
using Address for address;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20 token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
function safeTransferFrom(IERC20 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(IERC20 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));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeDecreaseAllowance(IERC20 token, address spender, uint256 value) internal {
unchecked {
uint256 oldAllowance = token.allowance(address(this), spender);
require(oldAllowance >= value, "SafeERC20: decreased allowance below zero");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20 token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
function safePermit(
IERC20Permit 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(IERC20 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");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation 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).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) {
// 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 cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && Address.isContract(address(token));
}
}
// node_modules/@openzeppelin/contracts-upgradeable/token/ERC20/utils/SafeERC20Upgradeable.sol
// OpenZeppelin Contracts (last updated v4.9.3) (token/ERC20/utils/SafeERC20.sol)
/**
* @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;
/**
* @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeTransfer(IERC20Upgradeable token, address to, uint256 value) internal {
_callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
}
/**
* @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the
* calling contract. If `token` returns no value, non-reverting calls are assumed to be successful.
*/
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));
}
/**
* @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
function safeIncreaseAllowance(IERC20Upgradeable token, address spender, uint256 value) internal {
uint256 oldAllowance = token.allowance(address(this), spender);
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance + value));
}
/**
* @dev Decrease the calling contract's allowance toward `spender` by `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful.
*/
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");
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, oldAllowance - value));
}
}
/**
* @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value,
* non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval
* to be set to zero before setting it to a non-zero value, such as USDT.
*/
function forceApprove(IERC20Upgradeable token, address spender, uint256 value) internal {
bytes memory approvalCall = abi.encodeWithSelector(token.approve.selector, spender, value);
if (!_callOptionalReturnBool(token, approvalCall)) {
_callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, 0));
_callOptionalReturn(token, approvalCall);
}
}
/**
* @dev Use a ERC-2612 signature to set the `owner` approval toward `spender` on `token`.
* Revert on invalid signature.
*/
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");
require(returndata.length == 0 || abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation 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).
*
* This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead.
*/
function _callOptionalReturnBool(IERC20Upgradeable token, bytes memory data) private returns (bool) {
// 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 cannot use {Address-functionCall} here since this should return false
// and not revert is the subcall reverts.
(bool success, bytes memory returndata) = address(token).call(data);
return
success && (returndata.length == 0 || abi.decode(returndata, (bool))) && AddressUpgradeable.isContract(address(token));
}
}
// contracts/dexspan/UniversalERC20.sol
library UniversalERC20 {
using SafeMathUpgradeable for uint256;
using SafeERC20Upgradeable for IERC20Upgradeable;
IERC20Upgradeable private constant ZERO_ADDRESS =
IERC20Upgradeable(0x0000000000000000000000000000000000000000);
IERC20Upgradeable private constant ETH_ADDRESS =
IERC20Upgradeable(0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE);
function universalTransfer(
IERC20Upgradeable token,
address to,
uint256 amount
) internal returns (bool) {
if (amount == 0) {
return true;
}
if (isETH(token)) {
(bool success, ) = payable(address(uint160(to))).call{
value: amount
}("");
assert(success == true);
} else {
TransferHelper.safeTransfer(address(token), to, amount);
return true;
}
}
function universalTransferFrom(
IERC20Upgradeable token,
address from,
address to,
uint256 amount
) internal {
if (amount == 0) {
return;
}
if (isETH(token)) {
require(
from == msg.sender && msg.value >= amount,
"Wrong usage of ETH.universalTransferFrom()"
);
if (to != address(this)) {
(bool success, ) = payable(address(uint160(to))).call{
value: amount
}("");
assert(success == true);
}
if (msg.value > amount) {
(bool success, ) = payable(msg.sender).call{
value: msg.value.sub(amount)
}("");
assert(success == true);
}
} else {
TransferHelper.safeTransferFrom(address(token), from, to, amount);
}
}
function universalTransferFromSenderToThis(
IERC20Upgradeable token,
uint256 amount
) internal {
if (amount == 0) {
return;
}
if (isETH(token)) {
if (msg.value > amount) {
// Return remainder if exist
(bool success, ) = payable(msg.sender).call{
value: msg.value.sub(amount)
}("");
assert(success == true);
}
} else {
TransferHelper.safeTransferFrom(
address(token),
msg.sender,
address(this),
amount
);
}
}
function universalApprove(
IERC20Upgradeable token,
address to,
uint256 amount
) internal {
if (!isETH(token)) {
// if (amount == 0) {
// TransferHelper.safeApprove(address(token), to, 0);
// return;
// }
// uint256 allowance = token.allowance(address(this), to);
// if (allowance < amount) {
// if (allowance > 0) {
// TransferHelper.safeApprove(address(token), to, 0);
// }
// TransferHelper.safeApprove(address(token), to, amount);
// }
TransferHelper.safeApprove(address(token), to, 0);
TransferHelper.safeApprove(address(token), to, amount);
}
}
function universalBalanceOf(
IERC20Upgradeable token,
address who
) internal view returns (uint256) {
if (isETH(token)) {
return who.balance;
} else {
return token.balanceOf(who);
}
}
function isETH(IERC20Upgradeable token) internal pure returns (bool) {
return (address(token) == address(ZERO_ADDRESS) ||
address(token) == address(ETH_ADDRESS));
}
function eq(
IERC20Upgradeable a,
IERC20Upgradeable b
) internal pure returns (bool) {
return a == b || (isETH(a) && isETH(b));
}
}
// node_modules/@openzeppelin/contracts/access/AccessControl.sol
// OpenZeppelin Contracts (last updated v4.9.0) (access/AccessControl.sol)
/**
* @dev Contract module that allows children to implement role-based access
* control mechanisms. This is a lightweight version that doesn't allow enumerating role
* members except through off-chain means by accessing the contract event logs. Some
* applications may benefit from on-chain enumerability, for those cases see
* {AccessControlEnumerable}.
*
* Roles are referred to by their `bytes32` identifier. These should be exposed
* in the external API and be unique. The best way to achieve this is by
* using `public constant` hash digests:
*
* ```solidity
* bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
* ```
*
* Roles can be used to represent a set of permissions. To restrict access to a
* function call, use {hasRole}:
*
* ```solidity
* function foo() public {
* require(hasRole(MY_ROLE, msg.sender));
* ...
* }
* ```
*
* Roles can be granted and revoked dynamically via the {grantRole} and
* {revokeRole} functions. Each role has an associated admin role, and only
* accounts that have a role's admin role can call {grantRole} and {revokeRole}.
*
* By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
* that only accounts with this role will be able to grant or revoke other
* roles. More complex role relationships can be created by using
* {_setRoleAdmin}.
*
* WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
* grant and revoke this role. Extra precautions should be taken to secure
* accounts that have been granted it. We recommend using {AccessControlDefaultAdminRules}
* to enforce additional security measures for this role.
*/
abstract contract AccessControl is Context, IAccessControl, ERC165 {
struct RoleData {
mapping(address => bool) members;
bytes32 adminRole;
}
mapping(bytes32 => RoleData) private _roles;
bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;
/**
* @dev Modifier that checks that an account has a specific role. Reverts
* with a standardized message including the required role.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*
* _Available since v4.1._
*/
modifier onlyRole(bytes32 role) {
_checkRole(role);
_;
}
/**
* @dev See {IERC165-supportsInterface}.
*/
function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
}
/**
* @dev Returns `true` if `account` has been granted `role`.
*/
function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
return _roles[role].members[account];
}
/**
* @dev Revert with a standard message if `_msgSender()` is missing `role`.
* Overriding this function changes the behavior of the {onlyRole} modifier.
*
* Format of the revert message is described in {_checkRole}.
*
* _Available since v4.6._
*/
function _checkRole(bytes32 role) internal view virtual {
_checkRole(role, _msgSender());
}
/**
* @dev Revert with a standard message if `account` is missing `role`.
*
* The format of the revert reason is given by the following regular expression:
*
* /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
*/
function _checkRole(bytes32 role, address account) internal view virtual {
if (!hasRole(role, account)) {
revert(
string(
abi.encodePacked(
"AccessControl: account ",
Strings.toHexString(account),
" is missing role ",
Strings.toHexString(uint256(role), 32)
)
)
);
}
}
/**
* @dev Returns the admin role that controls `role`. See {grantRole} and
* {revokeRole}.
*
* To change a role's admin, use {_setRoleAdmin}.
*/
function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
return _roles[role].adminRole;
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleGranted} event.
*/
function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_grantRole(role, account);
}
/**
* @dev Revokes `role` from `account`.
*
* If `account` had been granted `role`, emits a {RoleRevoked} event.
*
* Requirements:
*
* - the caller must have ``role``'s admin role.
*
* May emit a {RoleRevoked} event.
*/
function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
_revokeRole(role, account);
}
/**
* @dev Revokes `role` from the calling account.
*
* Roles are often managed via {grantRole} and {revokeRole}: this function's
* purpose is to provide a mechanism for accounts to lose their privileges
* if they are compromised (such as when a trusted device is misplaced).
*
* If the calling account had been revoked `role`, emits a {RoleRevoked}
* event.
*
* Requirements:
*
* - the caller must be `account`.
*
* May emit a {RoleRevoked} event.
*/
function renounceRole(bytes32 role, address account) public virtual override {
require(account == _msgSender(), "AccessControl: can only renounce roles for self");
_revokeRole(role, account);
}
/**
* @dev Grants `role` to `account`.
*
* If `account` had not been already granted `role`, emits a {RoleGranted}
* event. Note that unlike {grantRole}, this function doesn't perform any
* checks on the calling account.
*
* May emit a {RoleGranted} event.
*
* [WARNING]
* ====
* This function should only be called from the constructor when setting
* up the initial roles for the system.
*
* Using this function in any other way is effectively circumventing the admin
* system imposed by {AccessControl}.
* ====
*
* NOTE: This function is deprecated in favor of {_grantRole}.
*/
function _setupRole(bytes32 role, address account) internal virtual {
_grantRole(role, account);
}
/**
* @dev Sets `adminRole` as ``role``'s admin role.
*
* Emits a {RoleAdminChanged} event.
*/
function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
bytes32 previousAdminRole = getRoleAdmin(role);
_roles[role].adminRole = adminRole;
emit RoleAdminChanged(role, previousAdminRole, adminRole);
}
/**
* @dev Grants `role` to `account`.
*
* Internal function without access restriction.
*
* May emit a {RoleGranted} event.
*/
function _grantRole(bytes32 role, address account) internal virtual {
if (!hasRole(role, account)) {
_roles[role].members[account] = true;
emit RoleGranted(role, account, _msgSender());
}
}
/**
* @dev Revokes `role` from `account`.
*
* Internal function without access restriction.
*
* May emit a {RoleRevoked} event.
*/
function _revokeRole(bytes32 role, address account) internal virtual {
if (hasRole(role, account)) {
_roles[role].members[account] = false;
emit RoleRevoked(role, account, _msgSender());
}
}
}
// contracts/dexspan/interface/IUniswapV2Exchange.sol
interface IUniswapV2Exchange {
function getReserves()
external
view
returns (
uint112 _reserve0,
uint112 _reserve1,
uint32 _blockTimestampLast
);
function swap(
uint256 amount0Out,
uint256 amount1Out,
address to,
bytes calldata data
) external;
function skim(address to) external;
function sync() external;
}
library UniswapV2ExchangeLib {
using MathUpgradeable for uint256;
using SafeMathUpgradeable for uint256;
using UniversalERC20 for IERC20Upgradeable;
function getReturn(
IUniswapV2Exchange exchange,
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amountIn
) internal view returns (uint256 result, bool needSync, bool needSkim) {
uint256 reserveIn = fromToken.universalBalanceOf(address(exchange));
uint256 reserveOut = destToken.universalBalanceOf(address(exchange));
(uint112 reserve0, uint112 reserve1, ) = exchange.getReserves();
if (fromToken > destToken) {
(reserve0, reserve1) = (reserve1, reserve0);
}
needSync = (reserveIn < reserve0 || reserveOut < reserve1);
needSkim = !needSync && (reserveIn > reserve0 || reserveOut > reserve1);
uint256 amountInWithFee = amountIn.mul(997);
uint256 numerator = amountInWithFee.mul(
MathUpgradeable.min(reserveOut, reserve1)
);
uint256 denominator = MathUpgradeable
.min(reserveIn, reserve0)
.mul(1000)
.add(amountInWithFee);
result = (denominator == 0) ? 0 : numerator.div(denominator);
}
}
// contracts/dexspan/interface/IUniswapV2Factory.sol
interface IUniswapV2Factory {
function getPair(
IERC20Upgradeable tokenA,
IERC20Upgradeable tokenB
) external view returns (IUniswapV2Exchange pair);
}
// contracts/dexspan/DexSpanRoot.sol
// import "./libraries/Multicall.sol";
library DisableFlags {
function check(uint256 flags, uint256 flag) internal pure returns (bool) {
return (flags & flag) != 0;
}
}
contract DexSpanRoot {
using SafeMath for uint256;
using DisableFlags for uint256;
using UniversalERC20 for IERC20Upgradeable;
using UniversalERC20 for IWETH;
using UniswapV2ExchangeLib for IUniswapV2Exchange;
uint256 internal constant DEXES_COUNT = 4;
uint256 public constant DEXES_COUNT_UPDATED = 1;
IERC20Upgradeable internal ZERO_ADDRESS;
int256 internal constant VERY_NEGATIVE_VALUE = -1e72;
IWETH public wnativeAddress;
IERC20Upgradeable public nativeAddress;
function _findBestDistribution(
uint256 s, // parts
int256[][] memory amounts // exchangesReturns
)
internal
pure
returns (int256 returnAmount, uint256[] memory distribution)
{
uint256 n = amounts.length;
int256[][] memory answer = new int256[][](n); // int[n][s+1]
uint256[][] memory parent = new uint256[][](n); // int[n][s+1]
for (uint256 i; i < n; i++) {
answer[i] = new int256[](s + 1);
parent[i] = new uint256[](s + 1);
}
for (uint256 j; j <= s; j++) {
answer[0][j] = amounts[0][j];
for (uint256 i = 1; i < n; i++) {
answer[i][j] = -1e72;
}
parent[0][j] = 0;
}
for (uint256 i = 1; i < n; i++) {
for (uint256 j; j <= s; j++) {
answer[i][j] = answer[i - 1][j];
parent[i][j] = j;
for (uint256 k = 1; k <= j; k++) {
if (answer[i - 1][j - k] + amounts[i][k] > answer[i][j]) {
answer[i][j] = answer[i - 1][j - k] + amounts[i][k];
parent[i][j] = j - k;
}
}
}
}
distribution = new uint256[](DEXES_COUNT_UPDATED);
uint256 partsLeft = s;
for (uint256 curExchange = n - 1; partsLeft > 0; curExchange--) {
distribution[curExchange] =
partsLeft -
parent[curExchange][partsLeft];
partsLeft = parent[curExchange][partsLeft];
}
returnAmount = (answer[n - 1][s] == VERY_NEGATIVE_VALUE)
? int256(0)
: answer[n - 1][s];
}
function _linearInterpolation(
uint256 value,
uint256 parts
) internal pure returns (uint256[] memory rets) {
rets = new uint256[](parts);
for (uint256 i = 0; i < parts; i++) {
rets[i] = value.mul(i + 1).div(parts);
}
}
function _tokensEqual(
IERC20Upgradeable tokenA,
IERC20Upgradeable tokenB
) internal pure returns (bool) {
return ((tokenA.isETH() && tokenB.isETH()) || tokenA == tokenB);
}
}
// contracts/dexspan/DexSpanView.sol
abstract contract IDexSpanView is DexSpanFlags {
function getExpectedReturn(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
uint256 parts,
uint256 flags
)
public
view
virtual
returns (uint256 returnAmount, uint256[] memory distribution);
function getExpectedReturnWithGas(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
uint256 parts,
uint256 flags,
uint256 destTokenEthPriceTimesGasPrice
)
public
view
virtual
returns (
uint256 returnAmount,
uint256 estimateGasAmount,
uint256[] memory distribution
);
}
contract DexSpanView is IDexSpanView, DexSpanRoot, AccessControl {
using SafeMath for uint256;
using DisableFlags for uint256;
using SafeERC20 for IERC20Upgradeable;
using UniversalERC20 for IERC20Upgradeable;
constructor() {
_setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
}
function getExpectedReturn(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
uint256 parts,
uint256 flags // See constants in IOneSplit.sol
)
public
view
override
returns (uint256 returnAmount, uint256[] memory distribution)
{
(returnAmount, , distribution) = getExpectedReturnWithGas(
fromToken,
destToken,
amount,
parts,
flags,
0
);
}
function getExpectedReturnWithGas(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
uint256 parts,
uint256 flags, // See constants in IOneSplit.sol
uint256 destTokenEthPriceTimesGasPrice
)
public
view
override
returns (
uint256 returnAmount,
uint256 estimateGasAmount,
uint256[] memory distribution
)
{
distribution = new uint256[](DEXES_COUNT_UPDATED);
if (fromToken == destToken) {
return (amount, 0, distribution);
}
function(IERC20Upgradeable, IERC20Upgradeable, uint256, uint256)
view
returns (uint256[] memory, uint256)[DEXES_COUNT_UPDATED]
memory reserves = _getAllReserves(flags);
int256[][] memory matrix = new int256[][](DEXES_COUNT_UPDATED);
uint256[DEXES_COUNT_UPDATED] memory gases;
bool atLeastOnePositive = false;
for (uint256 i; i < DEXES_COUNT_UPDATED; i++) {
uint256[] memory rets;
(rets, gases[i]) = reserves[i](fromToken, destToken, amount, parts);
// Prepend zero and sub gas
int256 gas = int256(
gases[i].mul(destTokenEthPriceTimesGasPrice).div(1e18)
);
matrix[i] = new int256[](parts + 1);
for (uint256 j; j < rets.length; j++) {
matrix[i][j + 1] = int256(rets[j]) - gas;
atLeastOnePositive =
atLeastOnePositive ||
(matrix[i][j + 1] > 0);
}
}
if (!atLeastOnePositive) {
for (uint256 i; i < DEXES_COUNT_UPDATED; i++) {
for (uint256 j = 1; j < parts + 1; j++) {
if (matrix[i][j] == 0) {
matrix[i][j] = VERY_NEGATIVE_VALUE;
}
}
}
}
(, distribution) = _findBestDistribution(parts, matrix);
(returnAmount, estimateGasAmount) = _getReturnAndGasByDistribution(
Args({
fromToken: fromToken,
destToken: destToken,
amount: amount,
parts: parts,
flags: flags,
destTokenEthPriceTimesGasPrice: destTokenEthPriceTimesGasPrice,
distribution: distribution,
matrix: matrix,
gases: gases,
reserves: reserves
})
);
return (returnAmount, estimateGasAmount, distribution);
}
struct Args {
IERC20Upgradeable fromToken;
IERC20Upgradeable destToken;
uint256 amount;
uint256 parts;
uint256 flags;
uint256 destTokenEthPriceTimesGasPrice;
uint256[] distribution;
int256[][] matrix;
uint256[DEXES_COUNT_UPDATED] gases;
function(IERC20Upgradeable, IERC20Upgradeable, uint256, uint256)
view
returns (uint256[] memory, uint256)[DEXES_COUNT_UPDATED] reserves;
}
function _getReturnAndGasByDistribution(
Args memory args
) internal view returns (uint256 returnAmount, uint256 estimateGasAmount) {
bool[DEXES_COUNT_UPDATED] memory exact = [
true //empty
];
for (uint256 i; i < DEXES_COUNT_UPDATED; i++) {
if (args.distribution[i] > 0) {
if (
args.distribution[i] == args.parts ||
exact[i] ||
args.flags.check(FLAG_DISABLE_SPLIT_RECALCULATION)
) {
estimateGasAmount = estimateGasAmount.add(args.gases[i]);
int256 value = args.matrix[i][args.distribution[i]];
returnAmount = returnAmount.add(
uint256(
(value == VERY_NEGATIVE_VALUE ? int256(0) : value) +
int256(
args
.gases[i]
.mul(
args.destTokenEthPriceTimesGasPrice
)
.div(1e18)
)
)
);
} else {
(uint256[] memory rets, uint256 gas) = args.reserves[i](
args.fromToken,
args.destToken,
args.amount.mul(args.distribution[i]).div(args.parts),
1
);
estimateGasAmount = estimateGasAmount.add(gas);
returnAmount = returnAmount.add(rets[0]);
}
}
}
}
function _getAllReserves(
uint256 flags
)
internal
pure
returns (
function(IERC20Upgradeable, IERC20Upgradeable, uint256, uint256)
view
returns (uint256[] memory, uint256)[DEXES_COUNT_UPDATED]
memory
)
{
return [_calculateNoReturn];
}
function _calculateUniswapFormula(
uint256 fromBalance,
uint256 toBalance,
uint256 amount
) internal pure returns (uint256) {
if (amount == 0) {
return 0;
}
return
amount.mul(toBalance).mul(997).div(
fromBalance.mul(1000).add(amount.mul(997))
);
}
function _calculateSwap(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256[] memory amounts,
IUniswapV2Factory exchangeInstance
) internal view returns (uint256[] memory rets, uint256 gas) {
rets = new uint256[](amounts.length);
IERC20Upgradeable fromTokenReal = fromToken.isETH()
? wnativeAddress
: fromToken;
IERC20Upgradeable destTokenReal = destToken.isETH()
? wnativeAddress
: destToken;
IUniswapV2Exchange exchange = exchangeInstance.getPair(
fromTokenReal,
destTokenReal
);
if (exchange != IUniswapV2Exchange(address(0))) {
uint256 fromTokenBalance = fromTokenReal.universalBalanceOf(
address(exchange)
);
uint256 destTokenBalance = destTokenReal.universalBalanceOf(
address(exchange)
);
for (uint256 i = 0; i < amounts.length; i++) {
rets[i] = _calculateUniswapFormula(
fromTokenBalance,
destTokenBalance,
amounts[i]
);
}
return (rets, 50_000);
}
}
function _calculateNoReturn(
IERC20Upgradeable /*fromToken*/,
IERC20Upgradeable /*destToken*/,
uint256 /*amount*/,
uint256 parts
) internal view returns (uint256[] memory rets, uint256 gas) {
this;
return (new uint256[](parts), 0);
}
}
// contracts/dexspan/DexSpan.sol
// import "./libraries/Multicall.sol";
contract DexSpan is DexSpanFlags, DexSpanRoot, AccessControl, Multicall_0 {
using UniversalERC20 for IERC20Upgradeable;
using SafeMath for uint256;
using DisableFlags for uint256;
using UniswapV2ExchangeLib for IUniswapV2Exchange;
IAssetForwarder public assetForwarder;
address public assetBridge;
address public univ2SkimAddress;
address public newOwner;
// IWETH public wnativeAddress;
mapping(uint256 => address) public flagToAddress;
event Swap(
string indexed funcName,
IERC20Upgradeable[] tokenPath,
uint256 amount,
address indexed sender,
address indexed receiver,
uint256 finalAmt,
uint256[] flags,
uint256 widgetID
);
event SwapWithRecipient(
string indexed funcName,
IERC20Upgradeable[] tokenPath,
uint256 amount,
address indexed sender,
address indexed receiver,
uint256 finalAmt,
uint256[] flags,
uint256 widgetID
);
event SwapOnSameChain(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint amount,
bytes _data,
uint256 flags
);
event SetAssetForwarder(address assetForwarder, address admin);
event SetAssetBridge(address assetBridge, address admin);
event SetFlagToFactory(uint flag, address factoryAddress);
event SetFactorySetter(address factorySetter);
event SetWNativeAddresses(address wrappedNative);
event TransferOwnership(address newOwner);
event ClaimOwnership(address newOwner);
error InvalidPool();
error InvalidCaller();
error ZeroAddress();
error ZeroFlag();
error RestrictNativeToken();
error WrongTokenSent();
error WrongDataLength();
error AmountTooLow();
error ExcecutionFailed();
error AlreadyFactorySetter();
error InvalidDepositType();
struct DexesArgs {
IERC20Upgradeable factoryAddress;
uint256 _exchangeCode;
}
struct SwapParams {
IERC20Upgradeable[] tokens;
uint256 amount;
uint256 minReturn;
uint256[] flags;
bytes[] dataTx;
bool isWrapper;
address recipient;
bytes destToken;
}
bytes32 public constant FACTORY_SETTER_ROLE =
keccak256("FACTORY_SETTER_ROLE");
bytes4 internal constant SWAP_MULTI_WITH_RECEPIENT_SELECTOR = 0xe738aa8d;
receive() external payable {}
constructor(
address _assetForwarderAddress,
address _native,
address _wrappedNative,
address _univ2SkimAddress
) {
if (_assetForwarderAddress == address(0)) revert ZeroAddress();
if (_native == address(0)) revert ZeroAddress();
if (_wrappedNative == address(0)) revert ZeroAddress();
if (_univ2SkimAddress == address(0)) revert ZeroAddress();
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
assetForwarder = IAssetForwarder(_assetForwarderAddress);
nativeAddress = IERC20Upgradeable(_native);
wnativeAddress = IWETH(_wrappedNative);
univ2SkimAddress = _univ2SkimAddress;
}
function transferOwnership(
address _newOwner
) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (_newOwner == address(0)) revert ZeroAddress();
newOwner = _newOwner;
emit TransferOwnership(_newOwner);
}
function claimOwnership() external {
if (newOwner != msg.sender) {
revert InvalidCaller();
}
_setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
emit ClaimOwnership(msg.sender);
}
function setAssetForwarder(
address _forwarder
) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (_forwarder == address(0)) revert ZeroAddress();
assetForwarder = IAssetForwarder(_forwarder);
emit SetAssetForwarder(_forwarder, msg.sender);
}
function setAssetBridge(
address _assetBridge
) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (_assetBridge == address(0)) revert ZeroAddress();
assetBridge = _assetBridge;
emit SetAssetBridge(_assetBridge, msg.sender);
}
function setFlagToFactoryAddress(
uint256 _flagCode,
address _factoryAddress
) external onlyRole(FACTORY_SETTER_ROLE) {
if (_flagCode == 0) revert ZeroFlag();
if (_factoryAddress == address(0)) revert ZeroAddress();
flagToAddress[_flagCode] = address(_factoryAddress);
emit SetFlagToFactory(_flagCode, _factoryAddress);
}
function setFactorySetter(
address _factorySetter
) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (_factorySetter == address(0)) revert ZeroAddress();
if (hasRole(FACTORY_SETTER_ROLE, _factorySetter))
revert AlreadyFactorySetter();
_setupRole(FACTORY_SETTER_ROLE, _factorySetter);
emit SetFactorySetter(_factorySetter);
}
function setWNativeAddresses(
address _native,
address _wrappedNative
) external onlyRole(DEFAULT_ADMIN_ROLE) {
if (_native == address(0)) revert ZeroAddress();
if (_wrappedNative == address(0)) revert ZeroAddress();
nativeAddress = IERC20Upgradeable(_native);
wnativeAddress = IWETH(_wrappedNative);
emit SetWNativeAddresses(_wrappedNative);
}
function handleMessage(
address _tokenSent,
uint256 _amount,
bytes memory message
) external {
if (
msg.sender != address(assetForwarder) &&
msg.sender != address(assetBridge)
) revert InvalidCaller();
messageHandler(_tokenSent, _amount, message);
}
function swapInSameChain(
IERC20Upgradeable[] memory tokens,
uint256 amount,
uint256 minReturn,
uint256[] memory flags,
bytes[] memory dataTx,
bool isWrapper,
address recipient,
uint256 widgetID
) public payable returns (uint256 returnAmount) {
returnAmount = swapMultiWithRecipient(
tokens,
amount,
minReturn,
flags,
dataTx,
isWrapper,
recipient
);
emit Swap(
"swapInSameChain",
tokens,
amount,
msg.sender,
recipient,
returnAmount,
flags,
widgetID
);
}
function swapMultiWithRecipient(
IERC20Upgradeable[] memory tokens,
uint256 amount,
uint256 minReturn,
uint256[] memory flags,
bytes[] memory dataTx,
bool isWrapper,
address recipient
) public payable returns (uint256 returnAmount) {
returnAmount = _swapMultiInternal(
tokens,
amount,
minReturn,
flags,
dataTx,
isWrapper,
recipient
);
emit SwapWithRecipient(
"swapMultiWithRecipient",
tokens,
amount,
msg.sender,
recipient,
returnAmount,
flags,
0
);
}
function swapAndDeposit(
uint256 partnerId,
bytes32 destChainIdBytes,
bytes calldata recipient,
uint8 depositType,
uint256 destAmount,
bytes memory message,
SwapParams memory swapData,
address refundRecipient
) public payable {
_swapMultiInternal(
swapData.tokens,
swapData.amount,
swapData.minReturn,
swapData.flags,
swapData.dataTx,
swapData.isWrapper,
address(this)
);
IERC20Upgradeable reserveToken = swapData.tokens[
swapData.tokens.length - 1
];
// swapAndDeposit
if (depositType == 0) {
uint256 amount = reserveToken.universalBalanceOf(address(this));
reserveToken.universalApprove(address(assetForwarder), amount);
assetForwarder.iDeposit{value: reserveToken.isETH() ? amount : 0}(
IAssetForwarder.DepositData(
partnerId,
amount,
destAmount,
address(reserveToken),
refundRecipient,
destChainIdBytes
),
swapData.destToken,
recipient
);
return;
}
// swapAndDepositWithMessage
if (depositType == 1) {
uint256 amount = reserveToken.universalBalanceOf(address(this));
reserveToken.universalApprove(
address(assetForwarder),
swapData.minReturn
);
assetForwarder.iDepositMessage{
value: reserveToken.isETH() ? amount : 0
}(
IAssetForwarder.DepositData(
partnerId,
swapData.minReturn,
destAmount,
address(reserveToken),
refundRecipient,
destChainIdBytes
),
swapData.destToken,
recipient,
message
);
if (amount > swapData.minReturn) {
reserveToken.universalTransfer(
refundRecipient,
amount - swapData.minReturn
);
}
return;
}
revert InvalidDepositType();
}
function messageHandler(
address _tokenSent,
uint256 _amount,
bytes memory message
) internal {
(
IERC20Upgradeable[] memory tokens,
uint256 minReturn,
bytes[] memory dataTx,
uint256[] memory flags,
address recipient,
bool isInstruction,
bytes memory instruction
) = abi.decode(
message,
(
IERC20Upgradeable[],
uint256,
bytes[],
uint256[],
address,
bool,
bytes
)
);
if (_tokenSent != address(tokens[0])) revert WrongTokenSent();
bytes memory execData;
bool execFlag;
(execFlag, execData) = address(this).call(
abi.encodeWithSelector(
SWAP_MULTI_WITH_RECEPIENT_SELECTOR,
tokens,
_amount,
minReturn,
flags,
dataTx,
true,
recipient
)
);
if (!execFlag) {
tokens[0].universalTransfer(recipient, _amount);
}
if (isInstruction) {
uint256 finalAmount = execFlag
? uint256(bytes32(execData))
: _amount;
address finalToken = execFlag
? address(tokens[tokens.length - 1])
: _tokenSent;
(execFlag, execData) = recipient.call(
abi.encodeWithSelector(
IMessageHandler.handleMessage.selector,
finalToken,
finalAmount,
instruction
)
);
}
}
function _swapMultiInternal(
IERC20Upgradeable[] memory tokens,
uint256 amount,
uint256 minReturn,
uint256[] memory flags,
bytes[] memory dataTx,
bool isWrapper,
address recipient
) internal returns (uint256 returnAmount) {
if (recipient == address(0)) revert ZeroAddress();
if (tokens.length - 1 != flags.length) {
revert WrongDataLength();
}
if (!isWrapper) {
if (!tokens[0].isETH() && msg.value != 0) {
revert RestrictNativeToken();
}
tokens[0].universalTransferFrom(msg.sender, address(this), amount);
}
returnAmount = tokens[0].universalBalanceOf(address(this));
IERC20Upgradeable destinationToken = tokens[tokens.length - 1];
for (uint256 i = 1; i < tokens.length; i++) {
if (tokens[i - 1] == tokens[i]) {
continue;
}
returnAmount = _swapFloor(
tokens[i - 1],
tokens[i],
returnAmount,
0,
flags[i - 1],
dataTx[i - 1]
);
}
if (destinationToken.isETH()) {
returnAmount = wnativeAddress.balanceOf(address(this));
wnativeAddress.withdraw(returnAmount);
}
if (recipient != address(this)) {
uint256 userBalanceOld = destinationToken.universalBalanceOf(
recipient
);
destinationToken.universalTransfer(recipient, returnAmount);
uint256 userBalanceNew = destinationToken.universalBalanceOf(
recipient
);
uint receivedTokens = userBalanceNew - userBalanceOld;
if (receivedTokens <= minReturn) {
revert AmountTooLow();
}
returnAmount = receivedTokens;
}
}
function _swapFloor(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
uint256 minReturn,
uint256 flags,
bytes memory _data
) internal returns (uint returnAmount) {
returnAmount = _swap(
fromToken,
destToken,
amount,
minReturn,
flags,
_data
);
}
function _swap(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
uint256 minReturn,
uint256 flags,
bytes memory _data
) internal returns (uint256 returnAmount) {
if (fromToken == destToken) {
return amount;
}
function(
IERC20Upgradeable,
IERC20Upgradeable,
uint256,
bytes memory,
uint256
) reserve = _getReserveExchange(flags);
uint256 remainingAmount = fromToken.universalBalanceOf(address(this));
reserve(fromToken, destToken, remainingAmount, _data, flags);
returnAmount = destToken.universalBalanceOf(address(this));
}
function _getReserveExchange(
uint256 flag
)
internal
pure
returns (
function(
IERC20Upgradeable,
IERC20Upgradeable,
uint256,
bytes memory,
uint256
)
)
{
if (flag < 0x03E9 && flag >= 0x0001) {
// 1 - 1000
return _swapOnUniswapV2;
} else if (flag == 0x07D2) {
return _swapOnParaswap; // 2002
} else {
return _swapOnGenericAggregator;
}
revert("RA: Exchange not found");
}
function _swapOnUniswapV2(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
bytes memory _data,
uint256 flags
) internal {
_swapOnExchangeInternal(fromToken, destToken, amount, flags);
}
function _swapOnGenericAggregator(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
bytes memory _data,
uint256 flagCode
) internal {
if (_data.length < 0) {
revert WrongDataLength();
}
address aggregatorFactoryAddress = flagToAddress[flagCode];
if (aggregatorFactoryAddress == address(0)) {
revert ZeroAddress();
}
if (fromToken.isETH()) {
wnativeAddress.deposit{value: amount}();
}
IERC20Upgradeable fromTokenReal = fromToken.isETH()
? wnativeAddress
: fromToken;
fromTokenReal.universalApprove(address(aggregatorFactoryAddress), amount);
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = address(aggregatorFactoryAddress).call(_data);
if (!success) revert ExcecutionFailed();
}
function _swapOnParaswap(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
bytes memory _data,
uint256 flagCode
) internal {
if (_data.length < 0) {
revert WrongDataLength();
}
address paraswap = flagToAddress[flagCode];
if (paraswap == address(0)) {
revert ZeroAddress();
}
if (fromToken.isETH()) {
wnativeAddress.deposit{value: amount}();
}
IERC20Upgradeable fromTokenReal = fromToken.isETH()
? wnativeAddress
: fromToken;
fromTokenReal.universalApprove(
IAugustusSwapper(paraswap).getTokenTransferProxy(),
amount
);
// solhint-disable-next-line avoid-low-level-calls
(bool success, ) = address(paraswap).call(_data);
if (!success) {
revert ExcecutionFailed();
}
}
function _swapOnExchangeInternal(
IERC20Upgradeable fromToken,
IERC20Upgradeable destToken,
uint256 amount,
uint256 flagCode
) internal returns (uint256 returnAmount) {
if (fromToken.isETH()) {
wnativeAddress.deposit{value: amount}();
}
address dexAddress = flagToAddress[flagCode];
require(dexAddress != address(0), "RA: Exchange not found");
IUniswapV2Factory factory = IUniswapV2Factory(address(dexAddress));
IERC20Upgradeable fromTokenReal = fromToken.isETH()
? wnativeAddress
: fromToken;
IERC20Upgradeable toTokenReal = destToken.isETH()
? wnativeAddress
: destToken;
if (fromTokenReal == toTokenReal) {
return amount;
}
IUniswapV2Exchange pool = factory.getPair(fromTokenReal, toTokenReal);
if (address(pool) == address(0)) revert InvalidPool();
bool needSync;
bool needSkim;
(returnAmount, needSync, needSkim) = pool.getReturn(
fromTokenReal,
toTokenReal,
amount
);
if (needSync) {
pool.sync();
} else if (needSkim) {
pool.skim(univ2SkimAddress);
}
fromTokenReal.universalTransfer(address(pool), amount);
if (
uint256(uint160(address(fromTokenReal))) <
uint256(uint160(address(toTokenReal)))
) {
pool.swap(0, returnAmount, address(this), "");
} else {
pool.swap(returnAmount, 0, address(this), "");
}
}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"inputs":[{"internalType":"address","name":"_assetForwarderAddress","type":"address"},{"internalType":"address","name":"_native","type":"address"},{"internalType":"address","name":"_wrappedNative","type":"address"},{"internalType":"address","name":"_univ2SkimAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyFactorySetter","type":"error"},{"inputs":[],"name":"AmountTooLow","type":"error"},{"inputs":[],"name":"ExcecutionFailed","type":"error"},{"inputs":[],"name":"InvalidCaller","type":"error"},{"inputs":[],"name":"InvalidDepositType","type":"error"},{"inputs":[],"name":"InvalidPool","type":"error"},{"inputs":[],"name":"RestrictNativeToken","type":"error"},{"inputs":[],"name":"WrongDataLength","type":"error"},{"inputs":[],"name":"WrongTokenSent","type":"error"},{"inputs":[],"name":"ZeroAddress","type":"error"},{"inputs":[],"name":"ZeroFlag","type":"error"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"ClaimOwnership","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"assetBridge","type":"address"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"SetAssetBridge","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"assetForwarder","type":"address"},{"indexed":false,"internalType":"address","name":"admin","type":"address"}],"name":"SetAssetForwarder","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"factorySetter","type":"address"}],"name":"SetFactorySetter","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"flag","type":"uint256"},{"indexed":false,"internalType":"address","name":"factoryAddress","type":"address"}],"name":"SetFlagToFactory","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"wrappedNative","type":"address"}],"name":"SetWNativeAddresses","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"funcName","type":"string"},{"indexed":false,"internalType":"contract IERC20Upgradeable[]","name":"tokenPath","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"finalAmt","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"flags","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"widgetID","type":"uint256"}],"name":"Swap","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"contract IERC20Upgradeable","name":"fromToken","type":"address"},{"indexed":false,"internalType":"contract IERC20Upgradeable","name":"destToken","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"_data","type":"bytes"},{"indexed":false,"internalType":"uint256","name":"flags","type":"uint256"}],"name":"SwapOnSameChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"string","name":"funcName","type":"string"},{"indexed":false,"internalType":"contract IERC20Upgradeable[]","name":"tokenPath","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"},{"indexed":true,"internalType":"address","name":"receiver","type":"address"},{"indexed":false,"internalType":"uint256","name":"finalAmt","type":"uint256"},{"indexed":false,"internalType":"uint256[]","name":"flags","type":"uint256[]"},{"indexed":false,"internalType":"uint256","name":"widgetID","type":"uint256"}],"name":"SwapWithRecipient","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newOwner","type":"address"}],"name":"TransferOwnership","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEXES_COUNT_UPDATED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FACTORY_SETTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetBridge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"assetForwarder","outputs":[{"internalType":"contract IAssetForwarder","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"claimOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"flagToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenSent","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"}],"name":"handleMessage","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes[]","name":"data","type":"bytes[]"}],"name":"multicall","outputs":[{"internalType":"bytes[]","name":"results","type":"bytes[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"nativeAddress","outputs":[{"internalType":"contract IERC20Upgradeable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newOwner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_assetBridge","type":"address"}],"name":"setAssetBridge","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_forwarder","type":"address"}],"name":"setAssetForwarder","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_factorySetter","type":"address"}],"name":"setFactorySetter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_flagCode","type":"uint256"},{"internalType":"address","name":"_factoryAddress","type":"address"}],"name":"setFlagToFactoryAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_native","type":"address"},{"internalType":"address","name":"_wrappedNative","type":"address"}],"name":"setWNativeAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"partnerId","type":"uint256"},{"internalType":"bytes32","name":"destChainIdBytes","type":"bytes32"},{"internalType":"bytes","name":"recipient","type":"bytes"},{"internalType":"uint8","name":"depositType","type":"uint8"},{"internalType":"uint256","name":"destAmount","type":"uint256"},{"internalType":"bytes","name":"message","type":"bytes"},{"components":[{"internalType":"contract IERC20Upgradeable[]","name":"tokens","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturn","type":"uint256"},{"internalType":"uint256[]","name":"flags","type":"uint256[]"},{"internalType":"bytes[]","name":"dataTx","type":"bytes[]"},{"internalType":"bool","name":"isWrapper","type":"bool"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"bytes","name":"destToken","type":"bytes"}],"internalType":"struct DexSpan.SwapParams","name":"swapData","type":"tuple"},{"internalType":"address","name":"refundRecipient","type":"address"}],"name":"swapAndDeposit","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable[]","name":"tokens","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturn","type":"uint256"},{"internalType":"uint256[]","name":"flags","type":"uint256[]"},{"internalType":"bytes[]","name":"dataTx","type":"bytes[]"},{"internalType":"bool","name":"isWrapper","type":"bool"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"widgetID","type":"uint256"}],"name":"swapInSameChain","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20Upgradeable[]","name":"tokens","type":"address[]"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint256","name":"minReturn","type":"uint256"},{"internalType":"uint256[]","name":"flags","type":"uint256[]"},{"internalType":"bytes[]","name":"dataTx","type":"bytes[]"},{"internalType":"bool","name":"isWrapper","type":"bool"},{"internalType":"address","name":"recipient","type":"address"}],"name":"swapMultiWithRecipient","outputs":[{"internalType":"uint256","name":"returnAmount","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"univ2SkimAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"wnativeAddress","outputs":[{"internalType":"contract IWETH","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]Contract Creation Code
60806040523480156200001157600080fd5b5060405162004e4638038062004e46833981016040819052620000349162000206565b6001600160a01b0384166200005c5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038316620000845760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038216620000ac5760405163d92e233d60e01b815260040160405180910390fd5b6001600160a01b038116620000d45760405163d92e233d60e01b815260040160405180910390fd5b620000e160003362000135565b600480546001600160a01b039586166001600160a01b031991821617909155600280549486169482169490941790935560018054928516928416929092179091556006805491909316911617905562000263565b62000141828262000145565b5050565b60008281526003602090815260408083206001600160a01b038516845290915290205460ff16620001415760008281526003602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620001a53390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b80516001600160a01b03811681146200020157600080fd5b919050565b600080600080608085870312156200021d57600080fd5b6200022885620001e9565b93506200023860208601620001e9565b92506200024860408601620001e9565b91506200025860608601620001e9565b905092959194509250565b614bd380620002736000396000f3fe6080604052600436106101bb5760003560e01c80639e99ec39116100ec578063d4ee1d901161008a578063e2a4ac2d11610064578063e2a4ac2d146105a9578063e738aa8d146105d6578063f2fde38b146105e9578063f9636f301461060957600080fd5b8063d4ee1d901461053c578063d547741f14610569578063da6689f01461058957600080fd5b8063ac9650d8116100c6578063ac9650d81461048c578063adb88982146104b9578063c75a57e4146104d9578063d00a2d5f1461051c57600080fd5b80639e99ec391461042a578063a217fddf1461044a578063a2625efc1461045f57600080fd5b8063285f94a01161015957806336568abe1161013357806336568abe146103755780634e71e0c8146103955780637fe68917146103aa57806391d14854146103d757600080fd5b8063285f94a0146102d65780632e476337146103285780632f2ff15d1461035557600080fd5b80631696516011610195578063169651601461025357806318137a4114610273578063183d9c9514610293578063248a9ca3146102a657600080fd5b806301ffc9a7146101c757806306135b7c146101fc578063086efdc41461021157600080fd5b366101c257005b600080fd5b3480156101d357600080fd5b506101e76101e236600461393c565b61061e565b60405190151581526020015b60405180910390f35b61020f61020a366004613dc5565b6106b7565b005b34801561021d57600080fd5b506102457fafffb39e42e2a1496bc4305c8783f904fa76641e3895205b6002a03336ee097581565b6040519081526020016101f3565b34801561025f57600080fd5b5061020f61026e366004613e94565b610a27565b34801561027f57600080fd5b5061020f61028e366004613ec4565b610b65565b6102456102a1366004613ee1565b610c3d565b3480156102b257600080fd5b506102456102c1366004613fa8565b60009081526003602052604090206001015490565b3480156102e257600080fd5b506005546103039073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b34801561033457600080fd5b506002546103039073ffffffffffffffffffffffffffffffffffffffff1681565b34801561036157600080fd5b5061020f610370366004613e94565b610ce7565b34801561038157600080fd5b5061020f610390366004613e94565b610d11565b3480156103a157600080fd5b5061020f610dc9565b3480156103b657600080fd5b506004546103039073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e357600080fd5b506101e76103f2366004613e94565b600091825260036020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561043657600080fd5b5061020f610445366004613ec4565b610e5a565b34801561045657600080fd5b50610245600081565b34801561046b57600080fd5b506006546103039073ffffffffffffffffffffffffffffffffffffffff1681565b34801561049857600080fd5b506104ac6104a7366004613fc1565b610f2a565b6040516101f391906140f9565b3480156104c557600080fd5b5061020f6104d4366004613ec4565b61101f565b3480156104e557600080fd5b506103036104f4366004613fa8565b60086020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b34801561052857600080fd5b5061020f61053736600461410c565b611166565b34801561054857600080fd5b506007546103039073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057557600080fd5b5061020f610584366004613e94565b6111e8565b34801561059557600080fd5b5061020f6105a4366004614165565b61120d565b3480156105b557600080fd5b506001546103039073ffffffffffffffffffffffffffffffffffffffff1681565b6102456105e4366004614193565b611335565b3480156105f557600080fd5b5061020f610604366004613ec4565b6113df565b34801561061557600080fd5b50610245600181565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806106b157507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6106de826000015183602001518460400151856060015186608001518760a00151306114aa565b5081518051600091906106f390600190614285565b8151811061070357610703614298565b602002602001015190508560ff1660000361085657600061073a73ffffffffffffffffffffffffffffffffffffffff8316306119c0565b6004549091506107649073ffffffffffffffffffffffffffffffffffffffff848116911683611a85565b60045473ffffffffffffffffffffffffffffffffffffffff9081169063f452ed4d90610791908516611aa9565b61079c57600061079e565b825b6040518060c001604052808f81526020018581526020018a81526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018e8152508760e001518d8d6040518663ffffffff1660e01b815260040161081d9493929190614310565b6000604051808303818588803b15801561083657600080fd5b505af115801561084a573d6000803e3d6000fd5b50505050505050610a1c565b8560ff166001036109ea57600061088373ffffffffffffffffffffffffffffffffffffffff8316306119c0565b60045460408601519192506108b29173ffffffffffffffffffffffffffffffffffffffff858116921690611a85565b60045473ffffffffffffffffffffffffffffffffffffffff90811690630421caf0906108df908516611aa9565b6108ea5760006108ec565b825b6040518060c001604052808f8152602001886040015181526020018a81526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018e8152508760e001518d8d8b6040518763ffffffff1660e01b8152600401610971959493929190614397565b6000604051808303818588803b15801561098a57600080fd5b505af115801561099e573d6000803e3d6000fd5b505050505083604001518111156109e3576109e1838560400151836109c39190614285565b73ffffffffffffffffffffffffffffffffffffffff85169190611afc565b505b5050610a1c565b6040517f26667fc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7fafffb39e42e2a1496bc4305c8783f904fa76641e3895205b6002a03336ee0975610a5181611bae565b82600003610a8b576040517f196de28b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216610ad8576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526008602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86169081179091558251868152918201527f11f5b5361c420666dc3452b8107601e1702f94b951f15bd93c26262c8147874e91015b60405180910390a1505050565b6000610b7081611bae565b73ffffffffffffffffffffffffffffffffffffffff8216610bbd576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155604080519182523360208301527f61b6fe2922f0180b98d305419bf3dcf432f5d8df894388c61c1f599c2194ec1d91015b60405180910390a15050565b6000610c4e89898989898989611335565b6040517f73776170496e53616d65436861696e0000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8416903390600f0160405180910390207fe3716b48e7d01d727d68472c873c69c2c4407365e4f68b2b6c8dd4569cd16dc78c8c868c89604051610cd39594939291906144c0565b60405180910390a498975050505050505050565b600082815260036020526040902060010154610d0281611bae565b610d0c8383611bbb565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610dbb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b610dc58282611caf565b5050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610e1a576040517f48f5c3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e25600033611d6a565b6040513381527f85a8c8100c1d48466310240af79644f50cdae7d09cb4820d60dfc5b2462f0fd09060200160405180910390a1565b6000610e6581611bae565b73ffffffffffffffffffffffffffffffffffffffff8216610eb2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155604080519182523360208301527f45085069ced50a4d2e82656a82ba8f5a1a28694489d8ea262252e40899a930a29101610c31565b60608167ffffffffffffffff811115610f4557610f456139dd565b604051908082528060200260200182016040528015610f7857816020015b6060815260200190600190039081610f635790505b50905060005b8281101561101857610fe830858584818110610f9c57610f9c614298565b9050602002810190610fae9190614504565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d7492505050565b828281518110610ffa57610ffa614298565b6020026020010181905250808061101090614569565b915050610f7e565b5092915050565b600061102a81611bae565b73ffffffffffffffffffffffffffffffffffffffff8216611077576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081527f3ab9add546f7e3b43565da9bc7e65e47b969d3856bb01a7dcac7bc8ff5080cbd602052604090205460ff16156110f6576040517fe4e970d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111207fafffb39e42e2a1496bc4305c8783f904fa76641e3895205b6002a03336ee097583611d6a565b60405173ffffffffffffffffffffffffffffffffffffffff831681527fd2b69bde5a989d23ef605a0dd4e0edf7662105058ab69f2559e482857b599ed890602001610c31565b60045473ffffffffffffffffffffffffffffffffffffffff1633148015906111a6575060055473ffffffffffffffffffffffffffffffffffffffff163314155b156111dd576040517f48f5c3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d0c838383611d99565b60008281526003602052604090206001015461120381611bae565b610d0c8383611caf565b600061121881611bae565b73ffffffffffffffffffffffffffffffffffffffff8316611265576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166112b2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556001805492851692909116821790556040519081527fcc4166d40cf68104cdf710f65ce022efd296742868a22b42e4695f89b886363690602001610b58565b6000611346888888888888886114aa565b6040517f737761704d756c746957697468526563697069656e7400000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff831690339060160160405180910390207fc40fae9d5f584875c393ac222c6f88b6c9dced1e9cc6251483648ac2e902c8b08b8b868b60006040516113cc9594939291906144c0565b60405180910390a4979650505050505050565b60006113ea81611bae565b73ffffffffffffffffffffffffffffffffffffffff8216611437576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040519081527fcfaaa26691e16e66e73290fc725eee1a6b4e0e693a1640484937aac25ffb55a490602001610c31565b600073ffffffffffffffffffffffffffffffffffffffff82166114f9576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451600189516115099190614285565b14611540576040517fcc513c7200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826116085761157e8860008151811061155b5761155b614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611aa9565b15801561158a57503415155b156115c1576040517f694b150300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116083330898b6000815181106115da576115da614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1661210c909392919063ffffffff16565b61164b308960008151811061161f5761161f614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166119c090919063ffffffff16565b905060008860018a5161165e9190614285565b8151811061166e5761166e614298565b602002602001015190506000600190505b89518110156117a45789818151811061169a5761169a614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168a6001836116c69190614285565b815181106116d6576116d6614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603156117925761178f8a611709600184614285565b8151811061171957611719614298565b60200260200101518b838151811061173357611733614298565b60200260200101518560008b60018761174c9190614285565b8151811061175c5761175c614298565b60200260200101518b6001886117729190614285565b8151811061178257611782614298565b60200260200101516122ec565b92505b8061179c81614569565b91505061167f565b506117c48173ffffffffffffffffffffffffffffffffffffffff16611aa9565b156118e1576001546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611837573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185b91906145a1565b6001546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810183905291935073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156118c857600080fd5b505af11580156118dc573d6000803e3d6000fd5b505050505b73ffffffffffffffffffffffffffffffffffffffff831630146119b457600061192073ffffffffffffffffffffffffffffffffffffffff8316856119c0565b905061194373ffffffffffffffffffffffffffffffffffffffff83168585611afc565b50600061196673ffffffffffffffffffffffffffffffffffffffff8416866119c0565b905060006119748383614285565b90508981116119af576040517f1fbaba3500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b935050505b50979650505050505050565b60006119cb83611aa9565b156119ee575073ffffffffffffffffffffffffffffffffffffffff8116316106b1565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906370a0823190602401602060405180830381865afa158015611a5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a7e91906145a1565b90506106b1565b611a8e83611aa9565b610d0c57611a9e83836000612307565b610d0c838383612307565b600073ffffffffffffffffffffffffffffffffffffffff821615806106b1575073ffffffffffffffffffffffffffffffffffffffff821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b600081600003611b0e57506001611ba7565b611b1784611aa9565b15611b985760008373ffffffffffffffffffffffffffffffffffffffff168360405160006040518083038185875af1925050503d8060008114611b76576040519150601f19603f3d011682016040523d82523d6000602084013e611b7b565b606091505b5090915050600181151514611b9257611b926145ba565b50611ba7565b611ba384848461249d565b5060015b9392505050565b611bb8813361262c565b50565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610dc557600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611c513390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610dc557600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b610dc58282611bbb565b6060611ba78383604051806060016040528060278152602001614b77602791396126e6565b600080600080600080600087806020019051810190611db89190614783565b965096509650965096509650965086600081518110611dd957611dd9614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1614611e45576040517f198b098900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606060003073ffffffffffffffffffffffffffffffffffffffff1663e738aa8d60e01b8a8d8b8a8c60018c604051602401611e86979695949392919061485b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611f0f91906148d2565b6000604051808303816000865af19150503d8060008114611f4c576040519150601f19603f3d011682016040523d82523d6000602084013e611f51565b606091505b509250905080611fa257611fa0858c8b600081518110611f7357611f73614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611afc9092919063ffffffff16565b505b83156120fe57600081611fb5578b611fbe565b611fbe836148ee565b9050600082611fcd578d611ff5565b8a60018c51611fdc9190614285565b81518110611fec57611fec614298565b60200260200101515b90508673ffffffffffffffffffffffffffffffffffffffff1663d00a2d5f60e01b82848860405160240161202b93929190614933565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516120b491906148d2565b6000604051808303816000865af19150503d80600081146120f1576040519150601f19603f3d011682016040523d82523d6000602084013e6120f6565b606091505b509450925050505b505050505050505050505050565b80156122e65761211b84611aa9565b156122da5773ffffffffffffffffffffffffffffffffffffffff8316331480156121455750803410155b6121d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f57726f6e67207573616765206f66204554482e756e6976657273616c5472616e60448201527f7366657246726f6d2829000000000000000000000000000000000000000000006064820152608401610db2565b73ffffffffffffffffffffffffffffffffffffffff821630146122665760008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114612248576040519150601f19603f3d011682016040523d82523d6000602084013e61224d565b606091505b5090915050600181151514612264576122646145ba565b505b803411156122d55760003361227b348461276b565b604051600081818185875af1925050503d80600081146122b7576040519150601f19603f3d011682016040523d82523d6000602084013e6122bc565b606091505b50909150506001811515146122d3576122d36145ba565b505b6122e6565b6122e684848484612777565b50505050565b60006122fc878787878787612916565b979650505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052915160009283929087169161239e91906148d2565b6000604051808303816000865af19150503d80600081146123db576040519150601f19603f3d011682016040523d82523d6000602084013e6123e0565b606091505b509150915081801561240a57508051158061240a57508080602001905181019061240a9190614971565b612496576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5472616e7366657248656c7065723a3a73616665417070726f76653a2061707060448201527f726f7665206661696c65640000000000000000000000000000000000000000006064820152608401610db2565b5050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161253491906148d2565b6000604051808303816000865af19150503d8060008114612571576040519150601f19603f3d011682016040523d82523d6000602084013e612576565b606091505b50915091508180156125a05750805115806125a05750808060200190518101906125a09190614971565b612496576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c6564000000000000000000000000000000000000006064820152608401610db2565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610dc55761266c816129c2565b6126778360206129e1565b60405160200161268892919061498e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610db291600401614a0f565b60606000808573ffffffffffffffffffffffffffffffffffffffff168560405161271091906148d2565b600060405180830381855af49150503d806000811461274b576040519150601f19603f3d011682016040523d82523d6000602084013e612750565b606091505b509150915061276186838387612c24565b9695505050505050565b6000611ba78284614285565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169161281691906148d2565b6000604051808303816000865af19150503d8060008114612853576040519150601f19603f3d011682016040523d82523d6000602084013e612858565b606091505b50915091508180156128825750805115806128825750808060200190518101906128829190614971565b61290e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a20747260448201527f616e7366657246726f6d206661696c65640000000000000000000000000000006064820152608401610db2565b505050505050565b60008573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1603612952575083612761565b61393261295e84612ccc565b9050600061298273ffffffffffffffffffffffffffffffffffffffff8a16306119c0565b905061299589898387898763ffffffff16565b6129b573ffffffffffffffffffffffffffffffffffffffff8916306119c0565b9998505050505050505050565b60606106b173ffffffffffffffffffffffffffffffffffffffff831660145b606060006129f0836002614a22565b6129fb906002614a39565b67ffffffffffffffff811115612a1357612a136139dd565b6040519080825280601f01601f191660200182016040528015612a3d576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612a7457612a74614298565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612ad757612ad7614298565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000612b13846002614a22565b612b1e906001614a39565b90505b6001811115612bbb577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110612b5f57612b5f614298565b1a60f81b828281518110612b7557612b75614298565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93612bb481614a4c565b9050612b21565b508315611ba7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610db2565b60608315612cba578251600003612cb35773ffffffffffffffffffffffffffffffffffffffff85163b612cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610db2565b5081612cc4565b612cc48383612d0a565b949350505050565b6139326103e982108015612ce1575060018210155b15612cef5750612d4e919050565b816107d203612d015750612d5a919050565b50612fe3919050565b815115612d1a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db29190614a0f565b61290e8585858461314f565b60008181526008602052604090205473ffffffffffffffffffffffffffffffffffffffff1680612db6576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612dd58673ffffffffffffffffffffffffffffffffffffffff16611aa9565b15612e5e57600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015612e4457600080fd5b505af1158015612e58573d6000803e3d6000fd5b50505050505b6000612e7f8773ffffffffffffffffffffffffffffffffffffffff16611aa9565b612e895786612ea3565b60015473ffffffffffffffffffffffffffffffffffffffff165b9050612f358273ffffffffffffffffffffffffffffffffffffffff1663d2c4b5986040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ef3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f179190614a81565b73ffffffffffffffffffffffffffffffffffffffff83169087611a85565b60008273ffffffffffffffffffffffffffffffffffffffff1685604051612f5c91906148d2565b6000604051808303816000865af19150503d8060008114612f99576040519150601f19603f3d011682016040523d82523d6000602084013e612f9e565b606091505b5050905080612fd9576040517f5987947500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60008181526008602052604090205473ffffffffffffffffffffffffffffffffffffffff168061303f576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61305e8673ffffffffffffffffffffffffffffffffffffffff16611aa9565b156130e757600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b1580156130cd57600080fd5b505af11580156130e1573d6000803e3d6000fd5b50505050505b60006131088773ffffffffffffffffffffffffffffffffffffffff16611aa9565b613112578661312c565b60015473ffffffffffffffffffffffffffffffffffffffff165b9050612f3573ffffffffffffffffffffffffffffffffffffffff82168387611a85565b60006131708573ffffffffffffffffffffffffffffffffffffffff16611aa9565b156131f957600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b1580156131df57600080fd5b505af11580156131f3573d6000803e3d6000fd5b50505050505b60008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff1680613285576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f52413a2045786368616e6765206e6f7420666f756e64000000000000000000006044820152606401610db2565b8060006132a773ffffffffffffffffffffffffffffffffffffffff8916611aa9565b6132b157876132cb565b60015473ffffffffffffffffffffffffffffffffffffffff165b905060006132ee8873ffffffffffffffffffffffffffffffffffffffff16611aa9565b6132f85787613312565b60015473ffffffffffffffffffffffffffffffffffffffff165b90508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036133535786945050505050612cc4565b6040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015282811660248301526000919085169063e6a4390590604401602060405180830381865afa1580156133cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ef9190614a81565b905073ffffffffffffffffffffffffffffffffffffffff811661343e576040517f2083cd4000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061346373ffffffffffffffffffffffffffffffffffffffff841686868d613702565b9199509250905081156134d5578273ffffffffffffffffffffffffffffffffffffffff1663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156134b857600080fd5b505af11580156134cc573d6000803e3d6000fd5b50505050613561565b8015613561576006546040517fbc25cf7700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201529084169063bc25cf7790602401600060405180830381600087803b15801561354857600080fd5b505af115801561355c573d6000803e3d6000fd5b505050505b61358273ffffffffffffffffffffffffffffffffffffffff8616848c611afc565b508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161015613657576040517f022c0d9f000000000000000000000000000000000000000000000000000000008152600060048201819052602482018a905230604483015260806064830152608482015273ffffffffffffffffffffffffffffffffffffffff84169063022c0d9f9060a401600060405180830381600087803b15801561363a57600080fd5b505af115801561364e573d6000803e3d6000fd5b505050506136f3565b6040517f022c0d9f0000000000000000000000000000000000000000000000000000000081526004810189905260006024820181905230604483015260806064830152608482015273ffffffffffffffffffffffffffffffffffffffff84169063022c0d9f9060a401600060405180830381600087803b1580156136da57600080fd5b505af11580156136ee573d6000803e3d6000fd5b505050505b50505050505050949350505050565b600080808061372773ffffffffffffffffffffffffffffffffffffffff8816896119c0565b9050600061374b73ffffffffffffffffffffffffffffffffffffffff88168a6119c0565b90506000808a73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561379b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bf9190614abc565b50915091508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1611156137fa57905b816dffffffffffffffffffffffffffff168410806138275750806dffffffffffffffffffffffffffff1683105b95508515801561385f5750816dffffffffffffffffffffffffffff1684118061385f5750806dffffffffffffffffffffffffffff1683115b9450600061386f896103e56138f8565b9050600061389761389086856dffffffffffffffffffffffffffff16613904565b83906138f8565b905060006138cb836138c56103e86138bf8b8a6dffffffffffffffffffffffffffff16613904565b906138f8565b9061391a565b905080156138e2576138dd8282613926565b6138e5565b60005b9950505050505050509450945094915050565b6000611ba78284614a22565b60008183106139135781611ba7565b5090919050565b6000611ba78284614a39565b6000611ba78284614b0c565b61393a614b47565b565b60006020828403121561394e57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611ba757600080fd5b60008083601f84011261399057600080fd5b50813567ffffffffffffffff8111156139a857600080fd5b6020830191508360208285010111156139c057600080fd5b9250929050565b803560ff811681146139d857600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613a3057613a306139dd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613a7d57613a7d6139dd565b604052919050565b600067ffffffffffffffff821115613a9f57613a9f6139dd565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613adc57600080fd5b8135613aef613aea82613a85565b613a36565b818152846020838601011115613b0457600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115613b3b57613b3b6139dd565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611bb857600080fd5b600082601f830112613b7857600080fd5b81356020613b88613aea83613b21565b82815260059290921b84018101918181019086841115613ba757600080fd5b8286015b84811015613bcb578035613bbe81613b45565b8352918301918301613bab565b509695505050505050565b600082601f830112613be757600080fd5b81356020613bf7613aea83613b21565b82815260059290921b84018101918181019086841115613c1657600080fd5b8286015b84811015613bcb5780358352918301918301613c1a565b600082601f830112613c4257600080fd5b81356020613c52613aea83613b21565b82815260059290921b84018101918181019086841115613c7157600080fd5b8286015b84811015613bcb57803567ffffffffffffffff811115613c955760008081fd5b613ca38986838b0101613acb565b845250918301918301613c75565b8015158114611bb857600080fd5b80356139d881613cb1565b80356139d881613b45565b60006101008284031215613ce857600080fd5b613cf0613a0c565b9050813567ffffffffffffffff80821115613d0a57600080fd5b613d1685838601613b67565b835260208401356020840152604084013560408401526060840135915080821115613d4057600080fd5b613d4c85838601613bd6565b60608401526080840135915080821115613d6557600080fd5b613d7185838601613c31565b6080840152613d8260a08501613cbf565b60a0840152613d9360c08501613cca565b60c084015260e0840135915080821115613dac57600080fd5b50613db984828501613acb565b60e08301525092915050565b60008060008060008060008060006101008a8c031215613de457600080fd5b8935985060208a0135975060408a013567ffffffffffffffff80821115613e0a57600080fd5b613e168d838e0161397e565b9099509750879150613e2a60608d016139c7565b965060808c0135955060a08c0135915080821115613e4757600080fd5b613e538d838e01613acb565b945060c08c0135915080821115613e6957600080fd5b50613e768c828d01613cd5565b925050613e8560e08b01613cca565b90509295985092959850929598565b60008060408385031215613ea757600080fd5b823591506020830135613eb981613b45565b809150509250929050565b600060208284031215613ed657600080fd5b8135611ba781613b45565b600080600080600080600080610100898b031215613efe57600080fd5b883567ffffffffffffffff80821115613f1657600080fd5b613f228c838d01613b67565b995060208b0135985060408b0135975060608b0135915080821115613f4657600080fd5b613f528c838d01613bd6565b965060808b0135915080821115613f6857600080fd5b50613f758b828c01613c31565b945050613f8460a08a01613cbf565b9250613f9260c08a01613cca565b915060e089013590509295985092959890939650565b600060208284031215613fba57600080fd5b5035919050565b60008060208385031215613fd457600080fd5b823567ffffffffffffffff80821115613fec57600080fd5b818501915085601f83011261400057600080fd5b81358181111561400f57600080fd5b8660208260051b850101111561402457600080fd5b60209290920196919550909350505050565b60005b83811015614051578181015183820152602001614039565b50506000910152565b60008151808452614072816020860160208601614036565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b858110156140ec5782840389526140da84835161405a565b988501989350908401906001016140c2565b5091979650505050505050565b602081526000611ba760208301846140a4565b60008060006060848603121561412157600080fd5b833561412c81613b45565b925060208401359150604084013567ffffffffffffffff81111561414f57600080fd5b61415b86828701613acb565b9150509250925092565b6000806040838503121561417857600080fd5b823561418381613b45565b91506020830135613eb981613b45565b600080600080600080600060e0888a0312156141ae57600080fd5b873567ffffffffffffffff808211156141c657600080fd5b6141d28b838c01613b67565b985060208a0135975060408a0135965060608a01359150808211156141f657600080fd5b6142028b838c01613bd6565b955060808a013591508082111561421857600080fd5b506142258a828b01613c31565b93505060a088013561423681613cb1565b915060c088013561424681613b45565b8091505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106b1576106b1614256565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60006101006143708388805182526020810151602083015260408101516040830152606081015173ffffffffffffffffffffffffffffffffffffffff8082166060850152806080840151166080850152505060a081015160a08301525050565b8060c08401526143828184018761405a565b905082810360e08401526122fc8185876142c7565b60006101206143f78389805182526020810151602083015260408101516040830152606081015173ffffffffffffffffffffffffffffffffffffffff8082166060850152806080840151166080850152505060a081015160a08301525050565b8060c08401526144098184018861405a565b905082810360e084015261441e8186886142c7565b9050828103610100840152614433818561405a565b98975050505050505050565b600081518084526020808501945080840160005b8381101561448557815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614453565b509495945050505050565b600081518084526020808501945080840160005b83811015614485578151875295820195908201906001016144a4565b60a0815260006144d360a083018861443f565b86602084015285604084015282810360608401526144f18186614490565b9150508260808301529695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261453957600080fd5b83018035915067ffffffffffffffff82111561455457600080fd5b6020019150368190038213156139c057600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361459a5761459a614256565b5060010190565b6000602082840312156145b357600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082601f8301126145fa57600080fd5b8151602061460a613aea83613b21565b82815260059290921b8401810191818101908684111561462957600080fd5b8286015b84811015613bcb57805161464081613b45565b835291830191830161462d565b600082601f83011261465e57600080fd5b815161466c613aea82613a85565b81815284602083860101111561468157600080fd5b612cc4826020830160208701614036565b600082601f8301126146a357600080fd5b815160206146b3613aea83613b21565b82815260059290921b840181019181810190868411156146d257600080fd5b8286015b84811015613bcb57805167ffffffffffffffff8111156146f65760008081fd5b6147048986838b010161464d565b8452509183019183016146d6565b600082601f83011261472357600080fd5b81516020614733613aea83613b21565b82815260059290921b8401810191818101908684111561475257600080fd5b8286015b84811015613bcb5780518352918301918301614756565b80516139d881613b45565b80516139d881613cb1565b600080600080600080600060e0888a03121561479e57600080fd5b875167ffffffffffffffff808211156147b657600080fd5b6147c28b838c016145e9565b985060208a0151975060408a01519150808211156147df57600080fd5b6147eb8b838c01614692565b965060608a015191508082111561480157600080fd5b61480d8b838c01614712565b955061481b60808b0161476d565b945061482960a08b01614778565b935060c08a015191508082111561483f57600080fd5b5061484c8a828b0161464d565b91505092959891949750929550565b60e08152600061486e60e083018a61443f565b886020840152876040840152828103606084015261488c8188614490565b905082810360808401526148a081876140a4565b94151560a0840152505073ffffffffffffffffffffffffffffffffffffffff9190911660c09091015295945050505050565b600082516148e4818460208701614036565b9190910192915050565b8051602080830151919081101561492d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000614968606083018461405a565b95945050505050565b60006020828403121561498357600080fd5b8151611ba781613cb1565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516149c6816017850160208801614036565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614a03816028840160208801614036565b01602801949350505050565b602081526000611ba7602083018461405a565b80820281158282048414176106b1576106b1614256565b808201808211156106b1576106b1614256565b600081614a5b57614a5b614256565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b600060208284031215614a9357600080fd5b8151611ba781613b45565b80516dffffffffffffffffffffffffffff811681146139d857600080fd5b600080600060608486031215614ad157600080fd5b614ada84614a9e565b9250614ae860208501614a9e565b9150604084015163ffffffff81168114614b0157600080fd5b809150509250925092565b600082614b42577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052605160045260246000fdfe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220f057570c576617372fc0a0f3470114b114723b85fcdba6d43afc0d25377818ec64736f6c6343000815003300000000000000000000000001b4ce0d48ce91eb6bcaf5db33870c65d641b894000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000005300000000000000000000000000000000000004000000000000000000000000b1b64005b11350a94c4d069eff4215592d98f2e2
Deployed Bytecode
0x6080604052600436106101bb5760003560e01c80639e99ec39116100ec578063d4ee1d901161008a578063e2a4ac2d11610064578063e2a4ac2d146105a9578063e738aa8d146105d6578063f2fde38b146105e9578063f9636f301461060957600080fd5b8063d4ee1d901461053c578063d547741f14610569578063da6689f01461058957600080fd5b8063ac9650d8116100c6578063ac9650d81461048c578063adb88982146104b9578063c75a57e4146104d9578063d00a2d5f1461051c57600080fd5b80639e99ec391461042a578063a217fddf1461044a578063a2625efc1461045f57600080fd5b8063285f94a01161015957806336568abe1161013357806336568abe146103755780634e71e0c8146103955780637fe68917146103aa57806391d14854146103d757600080fd5b8063285f94a0146102d65780632e476337146103285780632f2ff15d1461035557600080fd5b80631696516011610195578063169651601461025357806318137a4114610273578063183d9c9514610293578063248a9ca3146102a657600080fd5b806301ffc9a7146101c757806306135b7c146101fc578063086efdc41461021157600080fd5b366101c257005b600080fd5b3480156101d357600080fd5b506101e76101e236600461393c565b61061e565b60405190151581526020015b60405180910390f35b61020f61020a366004613dc5565b6106b7565b005b34801561021d57600080fd5b506102457fafffb39e42e2a1496bc4305c8783f904fa76641e3895205b6002a03336ee097581565b6040519081526020016101f3565b34801561025f57600080fd5b5061020f61026e366004613e94565b610a27565b34801561027f57600080fd5b5061020f61028e366004613ec4565b610b65565b6102456102a1366004613ee1565b610c3d565b3480156102b257600080fd5b506102456102c1366004613fa8565b60009081526003602052604090206001015490565b3480156102e257600080fd5b506005546103039073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016101f3565b34801561033457600080fd5b506002546103039073ffffffffffffffffffffffffffffffffffffffff1681565b34801561036157600080fd5b5061020f610370366004613e94565b610ce7565b34801561038157600080fd5b5061020f610390366004613e94565b610d11565b3480156103a157600080fd5b5061020f610dc9565b3480156103b657600080fd5b506004546103039073ffffffffffffffffffffffffffffffffffffffff1681565b3480156103e357600080fd5b506101e76103f2366004613e94565b600091825260036020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561043657600080fd5b5061020f610445366004613ec4565b610e5a565b34801561045657600080fd5b50610245600081565b34801561046b57600080fd5b506006546103039073ffffffffffffffffffffffffffffffffffffffff1681565b34801561049857600080fd5b506104ac6104a7366004613fc1565b610f2a565b6040516101f391906140f9565b3480156104c557600080fd5b5061020f6104d4366004613ec4565b61101f565b3480156104e557600080fd5b506103036104f4366004613fa8565b60086020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b34801561052857600080fd5b5061020f61053736600461410c565b611166565b34801561054857600080fd5b506007546103039073ffffffffffffffffffffffffffffffffffffffff1681565b34801561057557600080fd5b5061020f610584366004613e94565b6111e8565b34801561059557600080fd5b5061020f6105a4366004614165565b61120d565b3480156105b557600080fd5b506001546103039073ffffffffffffffffffffffffffffffffffffffff1681565b6102456105e4366004614193565b611335565b3480156105f557600080fd5b5061020f610604366004613ec4565b6113df565b34801561061557600080fd5b50610245600181565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806106b157507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6106de826000015183602001518460400151856060015186608001518760a00151306114aa565b5081518051600091906106f390600190614285565b8151811061070357610703614298565b602002602001015190508560ff1660000361085657600061073a73ffffffffffffffffffffffffffffffffffffffff8316306119c0565b6004549091506107649073ffffffffffffffffffffffffffffffffffffffff848116911683611a85565b60045473ffffffffffffffffffffffffffffffffffffffff9081169063f452ed4d90610791908516611aa9565b61079c57600061079e565b825b6040518060c001604052808f81526020018581526020018a81526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018e8152508760e001518d8d6040518663ffffffff1660e01b815260040161081d9493929190614310565b6000604051808303818588803b15801561083657600080fd5b505af115801561084a573d6000803e3d6000fd5b50505050505050610a1c565b8560ff166001036109ea57600061088373ffffffffffffffffffffffffffffffffffffffff8316306119c0565b60045460408601519192506108b29173ffffffffffffffffffffffffffffffffffffffff858116921690611a85565b60045473ffffffffffffffffffffffffffffffffffffffff90811690630421caf0906108df908516611aa9565b6108ea5760006108ec565b825b6040518060c001604052808f8152602001886040015181526020018a81526020018673ffffffffffffffffffffffffffffffffffffffff1681526020018773ffffffffffffffffffffffffffffffffffffffff1681526020018e8152508760e001518d8d8b6040518763ffffffff1660e01b8152600401610971959493929190614397565b6000604051808303818588803b15801561098a57600080fd5b505af115801561099e573d6000803e3d6000fd5b505050505083604001518111156109e3576109e1838560400151836109c39190614285565b73ffffffffffffffffffffffffffffffffffffffff85169190611afc565b505b5050610a1c565b6040517f26667fc400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050505050505050565b7fafffb39e42e2a1496bc4305c8783f904fa76641e3895205b6002a03336ee0975610a5181611bae565b82600003610a8b576040517f196de28b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8216610ad8576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526008602090815260409182902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86169081179091558251868152918201527f11f5b5361c420666dc3452b8107601e1702f94b951f15bd93c26262c8147874e91015b60405180910390a1505050565b6000610b7081611bae565b73ffffffffffffffffffffffffffffffffffffffff8216610bbd576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600480547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155604080519182523360208301527f61b6fe2922f0180b98d305419bf3dcf432f5d8df894388c61c1f599c2194ec1d91015b60405180910390a15050565b6000610c4e89898989898989611335565b6040517f73776170496e53616d65436861696e0000000000000000000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff8416903390600f0160405180910390207fe3716b48e7d01d727d68472c873c69c2c4407365e4f68b2b6c8dd4569cd16dc78c8c868c89604051610cd39594939291906144c0565b60405180910390a498975050505050505050565b600082815260036020526040902060010154610d0281611bae565b610d0c8383611bbb565b505050565b73ffffffffffffffffffffffffffffffffffffffff81163314610dbb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b610dc58282611caf565b5050565b60075473ffffffffffffffffffffffffffffffffffffffff163314610e1a576040517f48f5c3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610e25600033611d6a565b6040513381527f85a8c8100c1d48466310240af79644f50cdae7d09cb4820d60dfc5b2462f0fd09060200160405180910390a1565b6000610e6581611bae565b73ffffffffffffffffffffffffffffffffffffffff8216610eb2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600580547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155604080519182523360208301527f45085069ced50a4d2e82656a82ba8f5a1a28694489d8ea262252e40899a930a29101610c31565b60608167ffffffffffffffff811115610f4557610f456139dd565b604051908082528060200260200182016040528015610f7857816020015b6060815260200190600190039081610f635790505b50905060005b8281101561101857610fe830858584818110610f9c57610f9c614298565b9050602002810190610fae9190614504565b8080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250611d7492505050565b828281518110610ffa57610ffa614298565b6020026020010181905250808061101090614569565b915050610f7e565b5092915050565b600061102a81611bae565b73ffffffffffffffffffffffffffffffffffffffff8216611077576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff821660009081527f3ab9add546f7e3b43565da9bc7e65e47b969d3856bb01a7dcac7bc8ff5080cbd602052604090205460ff16156110f6576040517fe4e970d000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6111207fafffb39e42e2a1496bc4305c8783f904fa76641e3895205b6002a03336ee097583611d6a565b60405173ffffffffffffffffffffffffffffffffffffffff831681527fd2b69bde5a989d23ef605a0dd4e0edf7662105058ab69f2559e482857b599ed890602001610c31565b60045473ffffffffffffffffffffffffffffffffffffffff1633148015906111a6575060055473ffffffffffffffffffffffffffffffffffffffff163314155b156111dd576040517f48f5c3ed00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610d0c838383611d99565b60008281526003602052604090206001015461120381611bae565b610d0c8383611caf565b600061121881611bae565b73ffffffffffffffffffffffffffffffffffffffff8316611265576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff82166112b2576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6002805473ffffffffffffffffffffffffffffffffffffffff8581167fffffffffffffffffffffffff0000000000000000000000000000000000000000928316179092556001805492851692909116821790556040519081527fcc4166d40cf68104cdf710f65ce022efd296742868a22b42e4695f89b886363690602001610b58565b6000611346888888888888886114aa565b6040517f737761704d756c746957697468526563697069656e7400000000000000000000815290915073ffffffffffffffffffffffffffffffffffffffff831690339060160160405180910390207fc40fae9d5f584875c393ac222c6f88b6c9dced1e9cc6251483648ac2e902c8b08b8b868b60006040516113cc9594939291906144c0565b60405180910390a4979650505050505050565b60006113ea81611bae565b73ffffffffffffffffffffffffffffffffffffffff8216611437576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff84169081179091556040519081527fcfaaa26691e16e66e73290fc725eee1a6b4e0e693a1640484937aac25ffb55a490602001610c31565b600073ffffffffffffffffffffffffffffffffffffffff82166114f9576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8451600189516115099190614285565b14611540576040517fcc513c7200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b826116085761157e8860008151811061155b5761155b614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611aa9565b15801561158a57503415155b156115c1576040517f694b150300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6116083330898b6000815181106115da576115da614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1661210c909392919063ffffffff16565b61164b308960008151811061161f5761161f614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff166119c090919063ffffffff16565b905060008860018a5161165e9190614285565b8151811061166e5761166e614298565b602002602001015190506000600190505b89518110156117a45789818151811061169a5761169a614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168a6001836116c69190614285565b815181106116d6576116d6614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff1603156117925761178f8a611709600184614285565b8151811061171957611719614298565b60200260200101518b838151811061173357611733614298565b60200260200101518560008b60018761174c9190614285565b8151811061175c5761175c614298565b60200260200101518b6001886117729190614285565b8151811061178257611782614298565b60200260200101516122ec565b92505b8061179c81614569565b91505061167f565b506117c48173ffffffffffffffffffffffffffffffffffffffff16611aa9565b156118e1576001546040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff909116906370a0823190602401602060405180830381865afa158015611837573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061185b91906145a1565b6001546040517f2e1a7d4d0000000000000000000000000000000000000000000000000000000081526004810183905291935073ffffffffffffffffffffffffffffffffffffffff1690632e1a7d4d90602401600060405180830381600087803b1580156118c857600080fd5b505af11580156118dc573d6000803e3d6000fd5b505050505b73ffffffffffffffffffffffffffffffffffffffff831630146119b457600061192073ffffffffffffffffffffffffffffffffffffffff8316856119c0565b905061194373ffffffffffffffffffffffffffffffffffffffff83168585611afc565b50600061196673ffffffffffffffffffffffffffffffffffffffff8416866119c0565b905060006119748383614285565b90508981116119af576040517f1fbaba3500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b935050505b50979650505050505050565b60006119cb83611aa9565b156119ee575073ffffffffffffffffffffffffffffffffffffffff8116316106b1565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff83811660048301528416906370a0823190602401602060405180830381865afa158015611a5a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a7e91906145a1565b90506106b1565b611a8e83611aa9565b610d0c57611a9e83836000612307565b610d0c838383612307565b600073ffffffffffffffffffffffffffffffffffffffff821615806106b1575073ffffffffffffffffffffffffffffffffffffffff821673eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee1492915050565b600081600003611b0e57506001611ba7565b611b1784611aa9565b15611b985760008373ffffffffffffffffffffffffffffffffffffffff168360405160006040518083038185875af1925050503d8060008114611b76576040519150601f19603f3d011682016040523d82523d6000602084013e611b7b565b606091505b5090915050600181151514611b9257611b926145ba565b50611ba7565b611ba384848461249d565b5060015b9392505050565b611bb8813361262c565b50565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610dc557600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055611c513390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff1615610dc557600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b610dc58282611bbb565b6060611ba78383604051806060016040528060278152602001614b77602791396126e6565b600080600080600080600087806020019051810190611db89190614783565b965096509650965096509650965086600081518110611dd957611dd9614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1614611e45576040517f198b098900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606060003073ffffffffffffffffffffffffffffffffffffffff1663e738aa8d60e01b8a8d8b8a8c60018c604051602401611e86979695949392919061485b565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051611f0f91906148d2565b6000604051808303816000865af19150503d8060008114611f4c576040519150601f19603f3d011682016040523d82523d6000602084013e611f51565b606091505b509250905080611fa257611fa0858c8b600081518110611f7357611f73614298565b602002602001015173ffffffffffffffffffffffffffffffffffffffff16611afc9092919063ffffffff16565b505b83156120fe57600081611fb5578b611fbe565b611fbe836148ee565b9050600082611fcd578d611ff5565b8a60018c51611fdc9190614285565b81518110611fec57611fec614298565b60200260200101515b90508673ffffffffffffffffffffffffffffffffffffffff1663d00a2d5f60e01b82848860405160240161202b93929190614933565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516120b491906148d2565b6000604051808303816000865af19150503d80600081146120f1576040519150601f19603f3d011682016040523d82523d6000602084013e6120f6565b606091505b509450925050505b505050505050505050505050565b80156122e65761211b84611aa9565b156122da5773ffffffffffffffffffffffffffffffffffffffff8316331480156121455750803410155b6121d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f57726f6e67207573616765206f66204554482e756e6976657273616c5472616e60448201527f7366657246726f6d2829000000000000000000000000000000000000000000006064820152608401610db2565b73ffffffffffffffffffffffffffffffffffffffff821630146122665760008273ffffffffffffffffffffffffffffffffffffffff168260405160006040518083038185875af1925050503d8060008114612248576040519150601f19603f3d011682016040523d82523d6000602084013e61224d565b606091505b5090915050600181151514612264576122646145ba565b505b803411156122d55760003361227b348461276b565b604051600081818185875af1925050503d80600081146122b7576040519150601f19603f3d011682016040523d82523d6000602084013e6122bc565b606091505b50909150506001811515146122d3576122d36145ba565b505b6122e6565b6122e684848484612777565b50505050565b60006122fc878787878787612916565b979650505050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f095ea7b300000000000000000000000000000000000000000000000000000000179052915160009283929087169161239e91906148d2565b6000604051808303816000865af19150503d80600081146123db576040519150601f19603f3d011682016040523d82523d6000602084013e6123e0565b606091505b509150915081801561240a57508051158061240a57508080602001905181019061240a9190614971565b612496576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f5472616e7366657248656c7065723a3a73616665417070726f76653a2061707060448201527f726f7665206661696c65640000000000000000000000000000000000000000006064820152608401610db2565b5050505050565b6040805173ffffffffffffffffffffffffffffffffffffffff8481166024830152604480830185905283518084039091018152606490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fa9059cbb00000000000000000000000000000000000000000000000000000000179052915160009283929087169161253491906148d2565b6000604051808303816000865af19150503d8060008114612571576040519150601f19603f3d011682016040523d82523d6000602084013e612576565b606091505b50915091508180156125a05750805115806125a05750808060200190518101906125a09190614971565b612496576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f5472616e7366657248656c7065723a3a736166655472616e736665723a20747260448201527f616e73666572206661696c6564000000000000000000000000000000000000006064820152608401610db2565b600082815260036020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16610dc55761266c816129c2565b6126778360206129e1565b60405160200161268892919061498e565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610db291600401614a0f565b60606000808573ffffffffffffffffffffffffffffffffffffffff168560405161271091906148d2565b600060405180830381855af49150503d806000811461274b576040519150601f19603f3d011682016040523d82523d6000602084013e612750565b606091505b509150915061276186838387612c24565b9695505050505050565b6000611ba78284614285565b6040805173ffffffffffffffffffffffffffffffffffffffff85811660248301528481166044830152606480830185905283518084039091018152608490920183526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167f23b872dd00000000000000000000000000000000000000000000000000000000179052915160009283929088169161281691906148d2565b6000604051808303816000865af19150503d8060008114612853576040519150601f19603f3d011682016040523d82523d6000602084013e612858565b606091505b50915091508180156128825750805115806128825750808060200190518101906128829190614971565b61290e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f5472616e7366657248656c7065723a3a7472616e7366657246726f6d3a20747260448201527f616e7366657246726f6d206661696c65640000000000000000000000000000006064820152608401610db2565b505050505050565b60008573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff1603612952575083612761565b61393261295e84612ccc565b9050600061298273ffffffffffffffffffffffffffffffffffffffff8a16306119c0565b905061299589898387898763ffffffff16565b6129b573ffffffffffffffffffffffffffffffffffffffff8916306119c0565b9998505050505050505050565b60606106b173ffffffffffffffffffffffffffffffffffffffff831660145b606060006129f0836002614a22565b6129fb906002614a39565b67ffffffffffffffff811115612a1357612a136139dd565b6040519080825280601f01601f191660200182016040528015612a3d576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612a7457612a74614298565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612ad757612ad7614298565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000612b13846002614a22565b612b1e906001614a39565b90505b6001811115612bbb577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110612b5f57612b5f614298565b1a60f81b828281518110612b7557612b75614298565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93612bb481614a4c565b9050612b21565b508315611ba7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610db2565b60608315612cba578251600003612cb35773ffffffffffffffffffffffffffffffffffffffff85163b612cb3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610db2565b5081612cc4565b612cc48383612d0a565b949350505050565b6139326103e982108015612ce1575060018210155b15612cef5750612d4e919050565b816107d203612d015750612d5a919050565b50612fe3919050565b815115612d1a5781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610db29190614a0f565b61290e8585858461314f565b60008181526008602052604090205473ffffffffffffffffffffffffffffffffffffffff1680612db6576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612dd58673ffffffffffffffffffffffffffffffffffffffff16611aa9565b15612e5e57600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b158015612e4457600080fd5b505af1158015612e58573d6000803e3d6000fd5b50505050505b6000612e7f8773ffffffffffffffffffffffffffffffffffffffff16611aa9565b612e895786612ea3565b60015473ffffffffffffffffffffffffffffffffffffffff165b9050612f358273ffffffffffffffffffffffffffffffffffffffff1663d2c4b5986040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ef3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f179190614a81565b73ffffffffffffffffffffffffffffffffffffffff83169087611a85565b60008273ffffffffffffffffffffffffffffffffffffffff1685604051612f5c91906148d2565b6000604051808303816000865af19150503d8060008114612f99576040519150601f19603f3d011682016040523d82523d6000602084013e612f9e565b606091505b5050905080612fd9576040517f5987947500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5050505050505050565b60008181526008602052604090205473ffffffffffffffffffffffffffffffffffffffff168061303f576040517fd92e233d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b61305e8673ffffffffffffffffffffffffffffffffffffffff16611aa9565b156130e757600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0856040518263ffffffff1660e01b81526004016000604051808303818588803b1580156130cd57600080fd5b505af11580156130e1573d6000803e3d6000fd5b50505050505b60006131088773ffffffffffffffffffffffffffffffffffffffff16611aa9565b613112578661312c565b60015473ffffffffffffffffffffffffffffffffffffffff165b9050612f3573ffffffffffffffffffffffffffffffffffffffff82168387611a85565b60006131708573ffffffffffffffffffffffffffffffffffffffff16611aa9565b156131f957600160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1663d0e30db0846040518263ffffffff1660e01b81526004016000604051808303818588803b1580156131df57600080fd5b505af11580156131f3573d6000803e3d6000fd5b50505050505b60008281526008602052604090205473ffffffffffffffffffffffffffffffffffffffff1680613285576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f52413a2045786368616e6765206e6f7420666f756e64000000000000000000006044820152606401610db2565b8060006132a773ffffffffffffffffffffffffffffffffffffffff8916611aa9565b6132b157876132cb565b60015473ffffffffffffffffffffffffffffffffffffffff165b905060006132ee8873ffffffffffffffffffffffffffffffffffffffff16611aa9565b6132f85787613312565b60015473ffffffffffffffffffffffffffffffffffffffff165b90508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036133535786945050505050612cc4565b6040517fe6a4390500000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff838116600483015282811660248301526000919085169063e6a4390590604401602060405180830381865afa1580156133cb573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133ef9190614a81565b905073ffffffffffffffffffffffffffffffffffffffff811661343e576040517f2083cd4000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008061346373ffffffffffffffffffffffffffffffffffffffff841686868d613702565b9199509250905081156134d5578273ffffffffffffffffffffffffffffffffffffffff1663fff6cae96040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156134b857600080fd5b505af11580156134cc573d6000803e3d6000fd5b50505050613561565b8015613561576006546040517fbc25cf7700000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff91821660048201529084169063bc25cf7790602401600060405180830381600087803b15801561354857600080fd5b505af115801561355c573d6000803e3d6000fd5b505050505b61358273ffffffffffffffffffffffffffffffffffffffff8616848c611afc565b508373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff161015613657576040517f022c0d9f000000000000000000000000000000000000000000000000000000008152600060048201819052602482018a905230604483015260806064830152608482015273ffffffffffffffffffffffffffffffffffffffff84169063022c0d9f9060a401600060405180830381600087803b15801561363a57600080fd5b505af115801561364e573d6000803e3d6000fd5b505050506136f3565b6040517f022c0d9f0000000000000000000000000000000000000000000000000000000081526004810189905260006024820181905230604483015260806064830152608482015273ffffffffffffffffffffffffffffffffffffffff84169063022c0d9f9060a401600060405180830381600087803b1580156136da57600080fd5b505af11580156136ee573d6000803e3d6000fd5b505050505b50505050505050949350505050565b600080808061372773ffffffffffffffffffffffffffffffffffffffff8816896119c0565b9050600061374b73ffffffffffffffffffffffffffffffffffffffff88168a6119c0565b90506000808a73ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b8152600401606060405180830381865afa15801561379b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137bf9190614abc565b50915091508873ffffffffffffffffffffffffffffffffffffffff168a73ffffffffffffffffffffffffffffffffffffffff1611156137fa57905b816dffffffffffffffffffffffffffff168410806138275750806dffffffffffffffffffffffffffff1683105b95508515801561385f5750816dffffffffffffffffffffffffffff1684118061385f5750806dffffffffffffffffffffffffffff1683115b9450600061386f896103e56138f8565b9050600061389761389086856dffffffffffffffffffffffffffff16613904565b83906138f8565b905060006138cb836138c56103e86138bf8b8a6dffffffffffffffffffffffffffff16613904565b906138f8565b9061391a565b905080156138e2576138dd8282613926565b6138e5565b60005b9950505050505050509450945094915050565b6000611ba78284614a22565b60008183106139135781611ba7565b5090919050565b6000611ba78284614a39565b6000611ba78284614b0c565b61393a614b47565b565b60006020828403121561394e57600080fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114611ba757600080fd5b60008083601f84011261399057600080fd5b50813567ffffffffffffffff8111156139a857600080fd5b6020830191508360208285010111156139c057600080fd5b9250929050565b803560ff811681146139d857600080fd5b919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051610100810167ffffffffffffffff81118282101715613a3057613a306139dd565b60405290565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613a7d57613a7d6139dd565b604052919050565b600067ffffffffffffffff821115613a9f57613a9f6139dd565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613adc57600080fd5b8135613aef613aea82613a85565b613a36565b818152846020838601011115613b0457600080fd5b816020850160208301376000918101602001919091529392505050565b600067ffffffffffffffff821115613b3b57613b3b6139dd565b5060051b60200190565b73ffffffffffffffffffffffffffffffffffffffff81168114611bb857600080fd5b600082601f830112613b7857600080fd5b81356020613b88613aea83613b21565b82815260059290921b84018101918181019086841115613ba757600080fd5b8286015b84811015613bcb578035613bbe81613b45565b8352918301918301613bab565b509695505050505050565b600082601f830112613be757600080fd5b81356020613bf7613aea83613b21565b82815260059290921b84018101918181019086841115613c1657600080fd5b8286015b84811015613bcb5780358352918301918301613c1a565b600082601f830112613c4257600080fd5b81356020613c52613aea83613b21565b82815260059290921b84018101918181019086841115613c7157600080fd5b8286015b84811015613bcb57803567ffffffffffffffff811115613c955760008081fd5b613ca38986838b0101613acb565b845250918301918301613c75565b8015158114611bb857600080fd5b80356139d881613cb1565b80356139d881613b45565b60006101008284031215613ce857600080fd5b613cf0613a0c565b9050813567ffffffffffffffff80821115613d0a57600080fd5b613d1685838601613b67565b835260208401356020840152604084013560408401526060840135915080821115613d4057600080fd5b613d4c85838601613bd6565b60608401526080840135915080821115613d6557600080fd5b613d7185838601613c31565b6080840152613d8260a08501613cbf565b60a0840152613d9360c08501613cca565b60c084015260e0840135915080821115613dac57600080fd5b50613db984828501613acb565b60e08301525092915050565b60008060008060008060008060006101008a8c031215613de457600080fd5b8935985060208a0135975060408a013567ffffffffffffffff80821115613e0a57600080fd5b613e168d838e0161397e565b9099509750879150613e2a60608d016139c7565b965060808c0135955060a08c0135915080821115613e4757600080fd5b613e538d838e01613acb565b945060c08c0135915080821115613e6957600080fd5b50613e768c828d01613cd5565b925050613e8560e08b01613cca565b90509295985092959850929598565b60008060408385031215613ea757600080fd5b823591506020830135613eb981613b45565b809150509250929050565b600060208284031215613ed657600080fd5b8135611ba781613b45565b600080600080600080600080610100898b031215613efe57600080fd5b883567ffffffffffffffff80821115613f1657600080fd5b613f228c838d01613b67565b995060208b0135985060408b0135975060608b0135915080821115613f4657600080fd5b613f528c838d01613bd6565b965060808b0135915080821115613f6857600080fd5b50613f758b828c01613c31565b945050613f8460a08a01613cbf565b9250613f9260c08a01613cca565b915060e089013590509295985092959890939650565b600060208284031215613fba57600080fd5b5035919050565b60008060208385031215613fd457600080fd5b823567ffffffffffffffff80821115613fec57600080fd5b818501915085601f83011261400057600080fd5b81358181111561400f57600080fd5b8660208260051b850101111561402457600080fd5b60209290920196919550909350505050565b60005b83811015614051578181015183820152602001614039565b50506000910152565b60008151808452614072816020860160208601614036565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600081518084526020808501808196508360051b8101915082860160005b858110156140ec5782840389526140da84835161405a565b988501989350908401906001016140c2565b5091979650505050505050565b602081526000611ba760208301846140a4565b60008060006060848603121561412157600080fd5b833561412c81613b45565b925060208401359150604084013567ffffffffffffffff81111561414f57600080fd5b61415b86828701613acb565b9150509250925092565b6000806040838503121561417857600080fd5b823561418381613b45565b91506020830135613eb981613b45565b600080600080600080600060e0888a0312156141ae57600080fd5b873567ffffffffffffffff808211156141c657600080fd5b6141d28b838c01613b67565b985060208a0135975060408a0135965060608a01359150808211156141f657600080fd5b6142028b838c01613bd6565b955060808a013591508082111561421857600080fd5b506142258a828b01613c31565b93505060a088013561423681613cb1565b915060c088013561424681613b45565b8091505092959891949750929550565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b818103818111156106b1576106b1614256565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b60006101006143708388805182526020810151602083015260408101516040830152606081015173ffffffffffffffffffffffffffffffffffffffff8082166060850152806080840151166080850152505060a081015160a08301525050565b8060c08401526143828184018761405a565b905082810360e08401526122fc8185876142c7565b60006101206143f78389805182526020810151602083015260408101516040830152606081015173ffffffffffffffffffffffffffffffffffffffff8082166060850152806080840151166080850152505060a081015160a08301525050565b8060c08401526144098184018861405a565b905082810360e084015261441e8186886142c7565b9050828103610100840152614433818561405a565b98975050505050505050565b600081518084526020808501945080840160005b8381101561448557815173ffffffffffffffffffffffffffffffffffffffff1687529582019590820190600101614453565b509495945050505050565b600081518084526020808501945080840160005b83811015614485578151875295820195908201906001016144a4565b60a0815260006144d360a083018861443f565b86602084015285604084015282810360608401526144f18186614490565b9150508260808301529695505050505050565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe184360301811261453957600080fd5b83018035915067ffffffffffffffff82111561455457600080fd5b6020019150368190038213156139c057600080fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361459a5761459a614256565b5060010190565b6000602082840312156145b357600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052600160045260246000fd5b600082601f8301126145fa57600080fd5b8151602061460a613aea83613b21565b82815260059290921b8401810191818101908684111561462957600080fd5b8286015b84811015613bcb57805161464081613b45565b835291830191830161462d565b600082601f83011261465e57600080fd5b815161466c613aea82613a85565b81815284602083860101111561468157600080fd5b612cc4826020830160208701614036565b600082601f8301126146a357600080fd5b815160206146b3613aea83613b21565b82815260059290921b840181019181810190868411156146d257600080fd5b8286015b84811015613bcb57805167ffffffffffffffff8111156146f65760008081fd5b6147048986838b010161464d565b8452509183019183016146d6565b600082601f83011261472357600080fd5b81516020614733613aea83613b21565b82815260059290921b8401810191818101908684111561475257600080fd5b8286015b84811015613bcb5780518352918301918301614756565b80516139d881613b45565b80516139d881613cb1565b600080600080600080600060e0888a03121561479e57600080fd5b875167ffffffffffffffff808211156147b657600080fd5b6147c28b838c016145e9565b985060208a0151975060408a01519150808211156147df57600080fd5b6147eb8b838c01614692565b965060608a015191508082111561480157600080fd5b61480d8b838c01614712565b955061481b60808b0161476d565b945061482960a08b01614778565b935060c08a015191508082111561483f57600080fd5b5061484c8a828b0161464d565b91505092959891949750929550565b60e08152600061486e60e083018a61443f565b886020840152876040840152828103606084015261488c8188614490565b905082810360808401526148a081876140a4565b94151560a0840152505073ffffffffffffffffffffffffffffffffffffffff9190911660c09091015295945050505050565b600082516148e4818460208701614036565b9190910192915050565b8051602080830151919081101561492d577fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8160200360031b1b821691505b50919050565b73ffffffffffffffffffffffffffffffffffffffff84168152826020820152606060408201526000614968606083018461405a565b95945050505050565b60006020828403121561498357600080fd5b8151611ba781613cb1565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516149c6816017850160208801614036565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351614a03816028840160208801614036565b01602801949350505050565b602081526000611ba7602083018461405a565b80820281158282048414176106b1576106b1614256565b808201808211156106b1576106b1614256565b600081614a5b57614a5b614256565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b600060208284031215614a9357600080fd5b8151611ba781613b45565b80516dffffffffffffffffffffffffffff811681146139d857600080fd5b600080600060608486031215614ad157600080fd5b614ada84614a9e565b9250614ae860208501614a9e565b9150604084015163ffffffff81168114614b0157600080fd5b809150509250925092565b600082614b42577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052605160045260246000fdfe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220f057570c576617372fc0a0f3470114b114723b85fcdba6d43afc0d25377818ec64736f6c63430008150033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
00000000000000000000000001b4ce0d48ce91eb6bcaf5db33870c65d641b894000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee0000000000000000000000005300000000000000000000000000000000000004000000000000000000000000b1b64005b11350a94c4d069eff4215592d98f2e2
-----Decoded View---------------
Arg [0] : _assetForwarderAddress (address): 0x01B4CE0d48Ce91eB6bcaf5dB33870C65d641b894
Arg [1] : _native (address): 0xEeeeeEeeeEeEeeEeEeEeeEEEeeeeEeeeeeeeEEeE
Arg [2] : _wrappedNative (address): 0x5300000000000000000000000000000000000004
Arg [3] : _univ2SkimAddress (address): 0xB1b64005B11350a94c4D069eff4215592d98F2E2
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000001b4ce0d48ce91eb6bcaf5db33870c65d641b894
Arg [1] : 000000000000000000000000eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee
Arg [2] : 0000000000000000000000005300000000000000000000000000000000000004
Arg [3] : 000000000000000000000000b1b64005b11350a94c4d069eff4215592d98f2e2
Deployed Bytecode Sourcemap
142983:19464:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123033:204;;;;;;;;;;-1:-1:-1;123033:204:0;;;;;:::i;:::-;;:::i;:::-;;;516:14:1;;509:22;491:41;;479:2;464:18;123033:204:0;;;;;;;;150356:2459;;;;;;:::i;:::-;;:::i;:::-;;145298:87;;;;;;;;;;;;145353:32;145298:87;;;;;8367:25:1;;;8355:2;8340:18;145298:87:0;8221:177:1;147260:385:0;;;;;;;;;;-1:-1:-1;147260:385:0;;;;;:::i;:::-;;:::i;146698:282::-;;;;;;;;;;-1:-1:-1;146698:282:0;;;;;:::i;:::-;;:::i;148819:766::-;;;;;;:::i;:::-;;:::i;124856:131::-;;;;;;;;;;-1:-1:-1;124856:131:0;;;;;:::i;:::-;124930:7;124957:12;;;:6;:12;;;;;:22;;;;124856:131;143283:26;;;;;;;;;;-1:-1:-1;143283:26:0;;;;;;;;;;;10785:42:1;10773:55;;;10755:74;;10743:2;10728:18;143283:26:0;10609:226:1;131479:38:0;;;;;;;;;;-1:-1:-1;131479:38:0;;;;;;;;125297:147;;;;;;;;;;-1:-1:-1;125297:147:0;;;;;:::i;:::-;;:::i;126441:218::-;;;;;;;;;;-1:-1:-1;126441:218:0;;;;;:::i;:::-;;:::i;146465:225::-;;;;;;;;;;;;;:::i;143239:37::-;;;;;;;;;;-1:-1:-1;143239:37:0;;;;;;;;123329:147;;;;;;;;;;-1:-1:-1;123329:147:0;;;;;:::i;:::-;123415:4;123439:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;;;;123329:147;146988:264;;;;;;;;;;-1:-1:-1;146988:264:0;;;;;:::i;:::-;;:::i;122434:49::-;;;;;;;;;;-1:-1:-1;122434:49:0;122479:4;122434:49;;143316:31;;;;;;;;;;-1:-1:-1;143316:31:0;;;;;;;;89659:314;;;;;;;;;;-1:-1:-1;89659:314:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;147653:386::-;;;;;;;;;;-1:-1:-1;147653:386:0;;;;;:::i;:::-;;:::i;143425:48::-;;;;;;;;;;-1:-1:-1;143425:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;148472:339;;;;;;;;;;-1:-1:-1;148472:339:0;;;;;:::i;:::-;;:::i;143354:23::-;;;;;;;;;;-1:-1:-1;143354:23:0;;;;;;;;125737:149;;;;;;;;;;-1:-1:-1;125737:149:0;;;;;:::i;:::-;;:::i;148047:417::-;;;;;;;;;;-1:-1:-1;148047:417:0;;;;;:::i;:::-;;:::i;131445:27::-;;;;;;;;;;-1:-1:-1;131445:27:0;;;;;;;;149593:755;;;;;;:::i;:::-;;:::i;146214:243::-;;;;;;;;;;-1:-1:-1;146214:243:0;;;;;:::i;:::-;;:::i;131282:47::-;;;;;;;;;;;;131328:1;131282:47;;123033:204;123118:4;123142:47;;;123157:32;123142:47;;:87;;-1:-1:-1;90945:25:0;90930:40;;;;123193:36;123135:94;123033:204;-1:-1:-1;;123033:204:0:o;150356:2459::-;150670:242;150703:8;:15;;;150733:8;:15;;;150763:8;:18;;;150796:8;:14;;;150825:8;:15;;;150855:8;:18;;;150896:4;150670:18;:242::i;:::-;-1:-1:-1;150956:15:0;;150986:22;;150923:30;;150956:15;150986:26;;151011:1;;150986:26;:::i;:::-;150956:67;;;;;;;;:::i;:::-;;;;;;;150923:100;;151067:11;:16;;151082:1;151067:16;151063:650;;151100:14;151117:46;:31;;;151157:4;151117:31;:46::i;:::-;151216:14;;151100:63;;-1:-1:-1;151178:62:0;;151216:14;151178:29;;;;151216:14;151100:63;151178:29;:62::i;:::-;151255:14;;;;;;;:23;;151286:20;;:18;;;:20::i;:::-;:33;;151318:1;151286:33;;;151309:6;151286:33;151339:261;;;;;;;;151389:9;151339:261;;;;151421:6;151339:261;;;;151450:10;151339:261;;;;151491:12;151339:261;;;;;;151527:15;151339:261;;;;;;151565:16;151339:261;;;151619:8;:18;;;151656:9;;151255:425;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;151695:7;;;;151063:650;151767:11;:16;;151782:1;151767:16;151763:1007;;151800:14;151817:46;:31;;;151857:4;151817:31;:46::i;:::-;151934:14;;151968:18;;;;151800:63;;-1:-1:-1;151878:123:0;;151934:14;151878:29;;;;151934:14;;151878:29;:123::i;:::-;152016:14;;;;;;;:30;;152072:20;;:18;;;:20::i;:::-;:33;;152104:1;152072:33;;;152095:6;152072:33;152139:273;;;;;;;;152189:9;152139:273;;;;152221:8;:18;;;152139:273;;;;152262:10;152139:273;;;;152303:12;152139:273;;;;;;152339:15;152139:273;;;;;;152377:16;152139:273;;;152431:8;:18;;;152468:9;;152496:7;152016:502;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;152546:8;:18;;;152537:6;:27;152533:205;;;152585:137;152638:15;152685:8;:18;;;152676:6;:27;;;;:::i;:::-;152585:30;;;;:137;:30;:137::i;:::-;;152533:205;152752:7;;;;151763:1007;152787:20;;;;;;;;;;;;;;150356:2459;;;;;;;;;;:::o;147260:385::-;145353:32;122925:16;122936:4;122925:10;:16::i;:::-;147416:9:::1;147429:1;147416:14:::0;147412:37:::1;;147439:10;;;;;;;;;;;;;;147412:37;147464:29;::::0;::::1;147460:55;;147502:13;;;;;;;;;;;;;;147460:55;147526:24;::::0;;;:13:::1;:24;::::0;;;;;;;;:51;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;147593:44;;19369:25:1;;;19410:18;;;19403:83;147593:44:0::1;::::0;19342:18:1;147593:44:0::1;;;;;;;;147260:385:::0;;;:::o;146698:282::-;122479:4;122925:16;122479:4;122925:10;:16::i;:::-;146814:24:::1;::::0;::::1;146810:50;;146847:13;;;;;;;;;;;;;;146810:50;146871:14;:44:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;146931:41:::1;::::0;;19732:34:1;;;146961:10:0::1;19797:2:1::0;19782:18;;19775:43;146931:41:0::1;::::0;19644:18:1;146931:41:0::1;;;;;;;;146698:282:::0;;:::o;148819:766::-;149117:20;149165:188;149202:6;149223;149244:9;149268:5;149288:6;149309:9;149333;149165:22;:188::i;:::-;149369:208;;20043:17:1;20031:30;;149150:203:0;;-1:-1:-1;149369:208:0;;;;149462:10;;20086:2:1;20077:12;149369:208:0;;;;;;;;149420:6;149441;149511:12;149538:5;149558:8;149369:208;;;;;;;;;;:::i;:::-;;;;;;;;148819:766;;;;;;;;;;:::o;125297:147::-;124930:7;124957:12;;;:6;:12;;;;;:22;;;122925:16;122936:4;122925:10;:16::i;:::-;125411:25:::1;125422:4;125428:7;125411:10;:25::i;:::-;125297:147:::0;;;:::o;126441:218::-;126537:23;;;23676:10;126537:23;126529:83;;;;;;;21981:2:1;126529:83:0;;;21963:21:1;22020:2;22000:18;;;21993:30;22059:34;22039:18;;;22032:62;22130:17;22110:18;;;22103:45;22165:19;;126529:83:0;;;;;;;;;126625:26;126637:4;126643:7;126625:11;:26::i;:::-;126441:218;;:::o;146465:225::-;146515:8;;:22;:8;146527:10;146515:22;146511:77;;146561:15;;;;;;;;;;;;;;146511:77;146598:42;122479:4;146629:10;146598;:42::i;:::-;146656:26;;146671:10;10755:74:1;;146656:26:0;;10743:2:1;10728:18;146656:26:0;;;;;;;146465:225::o;146988:264::-;122479:4;122925:16;122479:4;122925:10;:16::i;:::-;147103:26:::1;::::0;::::1;147099:52;;147138:13;;;;;;;;;;;;;;147099:52;147162:11;:26:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;147204:40:::1;::::0;;19732:34:1;;;147233:10:0::1;19797:2:1::0;19782:18;;19775:43;147204:40:0::1;::::0;19644:18:1;147204:40:0::1;19497:327:1::0;89659:314:0;89727:22;89784:4;89772:24;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;89762:34;;89812:9;89807:134;89827:15;;;89807:134;;;89877:52;89914:4;89921;;89926:1;89921:7;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;89877:52;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;89877:28:0;;-1:-1:-1;;;89877:52:0:i;:::-;89864:7;89872:1;89864:10;;;;;;;;:::i;:::-;;;;;;:65;;;;89844:3;;;;;:::i;:::-;;;;89807:134;;;;89659:314;;;;:::o;147653:386::-;122479:4;122925:16;122479:4;122925:10;:16::i;:::-;147772:28:::1;::::0;::::1;147768:54;;147809:13;;;;;;;;;;;;;;147768:54;123439:29:::0;;;123415:4;123439:29;;;:12;;:29;:12;:29;;;;;147833:92:::1;;;147903:22;;;;;;;;;;;;;;147833:92;147936:47;145353:32;147968:14;147936:10;:47::i;:::-;147999:32;::::0;10785:42:1;10773:55;;10755:74;;147999:32:0::1;::::0;10743:2:1;10728:18;147999:32:0::1;10609:226:1::0;148472:339:0;148648:14;;;;148626:10;:37;;;;:88;;-1:-1:-1;148702:11:0;;;;148680:10;:34;;148626:88;148608:140;;;148733:15;;;;;;;;;;;;;;148608:140;148759:44;148774:10;148786:7;148795;148759:14;:44::i;125737:149::-;124930:7;124957:12;;;:6;:12;;;;;:22;;;122925:16;122936:4;122925:10;:16::i;:::-;125852:26:::1;125864:4;125870:7;125852:11;:26::i;148047:417::-:0;122479:4;122925:16;122479:4;122925:10;:16::i;:::-;148195:21:::1;::::0;::::1;148191:47;;148225:13;;;;;;;;;;;;;;148191:47;148253:28;::::0;::::1;148249:54;;148290:13;;;;;;;;;;;;;;148249:54;148314:13;:42:::0;;::::1;::::0;;::::1;::::0;;;::::1;;::::0;;;-1:-1:-1;148367:38:0;;;;::::1;::::0;;;::::1;::::0;::::1;::::0;;148421:35:::1;::::0;10755:74:1;;;148421:35:0::1;::::0;10743:2:1;10728:18;148421:35:0::1;10609:226:1::0;149593:755:0;149871:20;149919:184;149952:6;149973;149994:9;150018:5;150038:6;150059:9;150083;149919:18;:184::i;:::-;150119:221;;23194:24:1;23182:37;;149904:199:0;;-1:-1:-1;150119:221:0;;;;150232:10;;23244:2:1;23235:12;150119:221:0;;;;;;;;150190:6;150211;150281:12;150308:5;150328:1;150119:221;;;;;;;;;;:::i;:::-;;;;;;;;149593:755;;;;;;;;;:::o;146214:243::-;122479:4;122925:16;122479:4;122925:10;:16::i;:::-;146329:23:::1;::::0;::::1;146325:49;;146361:13;;;;;;;;;;;;;;146325:49;146385:8;:20:::0;;;::::1;;::::0;::::1;::::0;;::::1;::::0;;;146421:28:::1;::::0;10755:74:1;;;146421:28:0::1;::::0;10743:2:1;10728:18;146421:28:0::1;10609:226:1::0;154709:1980:0;154977:20;155014:23;;;155010:49;;155046:13;;;;;;;;;;;;;;155010:49;155095:5;:12;155090:1;155074:6;:13;:17;;;;:::i;:::-;:33;155070:90;;155131:17;;;;;;;;;;;;;;155070:90;155175:9;155170:228;;155206:17;:6;155213:1;155206:9;;;;;;;;:::i;:::-;;;;;;;:15;;;:17::i;:::-;155205:18;:36;;;;-1:-1:-1;155227:9:0;:14;;155205:36;155201:105;;;155269:21;;;;;;;;;;;;;;155201:105;155320:66;155352:10;155372:4;155379:6;155320;155327:1;155320:9;;;;;;;;:::i;:::-;;;;;;;:31;;;;:66;;;;;;:::i;:::-;155423:43;155460:4;155423:6;155430:1;155423:9;;;;;;;;:::i;:::-;;;;;;;:28;;;;:43;;;;:::i;:::-;155408:58;;155477:34;155514:6;155537:1;155521:6;:13;:17;;;;:::i;:::-;155514:25;;;;;;;;:::i;:::-;;;;;;;155477:62;;155555:9;155567:1;155555:13;;155550:374;155574:6;:13;155570:1;:17;155550:374;;;155630:6;155637:1;155630:9;;;;;;;;:::i;:::-;;;;;;;155613:26;;:6;155624:1;155620;:5;;;;:::i;:::-;155613:13;;;;;;;;:::i;:::-;;;;;;;:26;;;155609:75;155660:8;155609:75;155713:199;155742:6;155749:5;155753:1;155749;:5;:::i;:::-;155742:13;;;;;;;;:::i;:::-;;;;;;;155774:6;155781:1;155774:9;;;;;;;;:::i;:::-;;;;;;;155802:12;155833:1;155853:5;155863:1;155859;:5;;;;:::i;:::-;155853:12;;;;;;;;:::i;:::-;;;;;;;155884:6;155895:1;155891;:5;;;;:::i;:::-;155884:13;;;;;;;;:::i;:::-;;;;;;;155713:10;:199::i;:::-;155698:214;;155550:374;155589:3;;;;:::i;:::-;;;;155550:374;;;;155940:24;:16;:22;;;:24::i;:::-;155936:163;;;155996:14;;:39;;;;;156029:4;155996:39;;;10755:74:1;155996:14:0;;;;;:24;;10728:18:1;;155996:39:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;156050:14;;:37;;;;;;;;8367:25:1;;;155981:54:0;;-1:-1:-1;156050:14:0;;;:23;;8340:18:1;;156050:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;155936:163;156115:26;;;156136:4;156115:26;156111:571;;156158:22;156183:78;:35;;;156237:9;156183:35;:78::i;:::-;156158:103;-1:-1:-1;156276:59:0;:34;;;156311:9;156322:12;156276:34;:59::i;:::-;-1:-1:-1;156350:22:0;156375:78;:35;;;156429:9;156375:35;:78::i;:::-;156350:103;-1:-1:-1;156470:19:0;156492:31;156509:14;156350:103;156492:31;:::i;:::-;156470:53;;156560:9;156542:14;:27;156538:89;;156597:14;;;;;;;;;;;;;;156538:89;156656:14;-1:-1:-1;;;156111:571:0;154999:1690;154709:1980;;;;;;;;;:::o;119715:264::-;119829:7;119853:12;119859:5;119853;:12::i;:::-;119849:123;;;-1:-1:-1;119889:11:0;;;;119882:18;;119849:123;119940:20;;;;;:15;10773:55:1;;;119940:20:0;;;10755:74:1;119940:15:0;;;;;10728:18:1;;119940:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;119933:27;;;;118903:804;119041:12;119047:5;119041;:12::i;:::-;119036:664;;119570:49;119605:5;119613:2;119617:1;119570:26;:49::i;:::-;119634:54;119669:5;119677:2;119681:6;119634:26;:54::i;119987:191::-;120050:4;120075:39;;;;;:94;;-1:-1:-1;120131:38:0;;;116621:42;120131:38;120067:103;119987:191;-1:-1:-1;;119987:191:0:o;116673:524::-;116805:4;116826:6;116836:1;116826:11;116822:55;;-1:-1:-1;116861:4:0;116854:11;;116822:55;116893:12;116899:5;116893;:12::i;:::-;116889:301;;;116923:12;116965:2;116941:34;;117001:6;116941:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;116922:104:0;;-1:-1:-1;;117059:4:0;117048:15;;;;117041:23;;;;:::i;:::-;116907:169;116889:301;;;117097:55;117133:5;117141:2;117145:6;117097:27;:55::i;:::-;-1:-1:-1;117174:4:0;116889:301;116673:524;;;;;:::o;123780:105::-;123847:30;123858:4;23676:10;123847;:30::i;:::-;123780:105;:::o;128038:238::-;123415:4;123439:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;128117:152;;128161:12;;;;:6;:12;;;;;;;;:29;;;;;;;;;;:36;;;;128193:4;128161:36;;;128244:12;23676:10;;23596:98;128244:12;128217:40;;128235:7;128217:40;;128229:4;128217:40;;;;;;;;;;128038:238;;:::o;128456:239::-;123415:4;123439:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;128536:152;;;128611:5;128579:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;:37;;;;;;128636:40;23676:10;;128579:12;;128636:40;;128611:5;128636:40;128456:239;;:::o;127366:112::-;127445:25;127456:4;127462:7;127445:10;:25::i;20172:200::-;20255:12;20287:77;20308:6;20316:4;20287:77;;;;;;;;;;;;;;;;;:20;:77::i;152823:1878::-;152975:33;153023:17;153055:21;153091:22;153128:17;153160:18;153193:24;153260:7;153231:308;;;;;;;;;;;;:::i;:::-;152960:579;;;;;;;;;;;;;;153576:6;153583:1;153576:9;;;;;;;;:::i;:::-;;;;;;;153554:32;;:10;:32;;;153550:61;;153595:16;;;;;;;;;;;;;;153550:61;153622:21;153654:13;153709:4;153701:18;;145454:10;153775:34;;153828:6;153853:7;153879:9;153907:5;153931:6;153956:4;153979:9;153734:269;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;153701:313;;;;153734:269;153701:313;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;153678:336:0;-1:-1:-1;153678:336:0;-1:-1:-1;153678:336:0;154027:89;;154057:47;154085:9;154096:7;154057:6;154064:1;154057:9;;;;;;;;:::i;:::-;;;;;;;:27;;;;:47;;;;;:::i;:::-;;154027:89;154132:13;154128:566;;;154162:19;154184:8;:81;;154258:7;154184:81;;;154220:17;154228:8;154220:17;:::i;:::-;154162:103;;154280:18;154301:8;:92;;154383:10;154301:92;;;154337:6;154360:1;154344:6;:13;:17;;;;:::i;:::-;154337:25;;;;;;;;:::i;:::-;;;;;;;154301:92;154280:113;;154431:9;:14;;154509:38;;;154570:10;154603:11;154637;154464:203;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;154431:251;;;;154464:203;154431:251;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;154408:274:0;-1:-1:-1;154408:274:0;-1:-1:-1;;;154128:566:0;152949:1752;;;;;;;;;152823:1878;;;:::o;117205:978::-;117366:50;;117398:7;117366:50;117432:12;117438:5;117432;:12::i;:::-;117428:748;;;117487:18;;;117495:10;117487:18;:41;;;;;117522:6;117509:9;:19;;117487:41;117461:145;;;;;;;31435:2:1;117461:145:0;;;31417:21:1;31474:2;31454:18;;;31447:30;31513:34;31493:18;;;31486:62;31584:12;31564:18;;;31557:40;31614:19;;117461:145:0;31233:406:1;117461:145:0;117625:19;;;117639:4;117625:19;117621:214;;117666:12;117708:2;117684:34;;117748:6;117684:93;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;117665:112:0;;-1:-1:-1;;117814:4:0;117803:15;;;;117796:23;;;;:::i;:::-;117646:189;117621:214;117865:6;117853:9;:18;117849:218;;;117893:12;117919:10;117965:21;:9;117979:6;117965:13;:21::i;:::-;117911:98;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;117892:117:0;;-1:-1:-1;;118046:4:0;118035:15;;;;118028:23;;;;:::i;:::-;117873:194;117849:218;117428:748;;;118099:65;118139:5;118147:4;118153:2;118157:6;118099:31;:65::i;:::-;117205:978;;;;:::o;156697:429::-;156924:17;156969:149;156989:9;157013;157037:6;157058:9;157082:5;157102;156969;:149::i;:::-;156954:164;156697:429;-1:-1:-1;;;;;;;156697:429:0:o;806:435::-;1016:45;;;991:10;31836:55:1;;;1016:45:0;;;31818:74:1;31908:18;;;;31901:34;;;1016:45:0;;;;;;;;;;31791:18:1;;;;1016:45:0;;;;;;;;;;;;;991:81;;-1:-1:-1;;;;991:10:0;;;;:81;;1016:45;991:81;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;955:117;;;;1105:7;:57;;;;-1:-1:-1;1117:11:0;;:16;;:44;;;1148:4;1137:24;;;;;;;;;;;;:::i;:::-;1083:150;;;;;;;32398:2:1;1083:150:0;;;32380:21:1;32437:2;32417:18;;;32410:30;32476:34;32456:18;;;32449:62;32547:13;32527:18;;;32520:41;32578:19;;1083:150:0;32196:407:1;1083:150:0;878:363;;806:435;;;:::o;1249:439::-;1461:45;;;1436:10;31836:55:1;;;1461:45:0;;;31818:74:1;31908:18;;;;31901:34;;;1461:45:0;;;;;;;;;;31791:18:1;;;;1461:45:0;;;;;;;;;;;;;1436:81;;-1:-1:-1;;;;1436:10:0;;;;:81;;1461:45;1436:81;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1400:117;;;;1550:7;:57;;;;-1:-1:-1;1562:11:0;;:16;;:44;;;1593:4;1582:24;;;;;;;;;;;;:::i;:::-;1528:152;;;;;;;32810:2:1;1528:152:0;;;32792:21:1;32849:2;32829:18;;;32822:30;32888:34;32868:18;;;32861:62;32959:15;32939:18;;;32932:43;32992:19;;1528:152:0;32608:409:1;124175:492:0;123415:4;123439:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;124259:401;;124452:28;124472:7;124452:19;:28::i;:::-;124553:38;124581:4;124588:2;124553:19;:38::i;:::-;124357:257;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;124303:345;;;;;;;;:::i;20566:332::-;20711:12;20737;20751:23;20778:6;:19;;20798:4;20778:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20736:67;;;;20821:69;20848:6;20856:7;20865:10;20877:12;20821:26;:69::i;:::-;20814:76;20566:332;-1:-1:-1;;;;;;20566:332:0:o;77382:98::-;77440:7;77467:5;77471:1;77467;:5;:::i;1696:522::-;1981:51;;;1956:10;34344:15:1;;;1981:51:0;;;34326:34:1;34396:15;;;34376:18;;;34369:43;34428:18;;;;34421:34;;;1981:51:0;;;;;;;;;;34238:18:1;;;;1981:51:0;;;;;;;;;;;;;1956:87;;-1:-1:-1;;;;1956:10:0;;;;:87;;1981:51;1956:87;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1920:123;;;;2076:7;:57;;;;-1:-1:-1;2088:11:0;;:16;;:44;;;2119:4;2108:24;;;;;;;;;;;;:::i;:::-;2054:156;;;;;;;34668:2:1;2054:156:0;;;34650:21:1;34707:2;34687:18;;;34680:30;34746:34;34726:18;;;34719:62;34817:19;34797:18;;;34790:47;34854:19;;2054:156:0;34466:413:1;2054:156:0;1830:388;;1696:522;;;;:::o;157134:754::-;157356:20;157406:9;157393:22;;:9;:22;;;157389:68;;-1:-1:-1;157439:6:0;157432:13;;157389:68;157467:162;157632:26;157652:5;157632:19;:26::i;:::-;157467:191;-1:-1:-1;157671:23:0;157697:43;:28;;;157734:4;157697:28;:43::i;:::-;157671:69;;157751:60;157759:9;157770;157781:15;157798:5;157805;157751:7;:60;;:::i;:::-;157837:43;:28;;;157874:4;157837:28;:43::i;:::-;157822:58;157134:754;-1:-1:-1;;;;;;;;;157134:754:0:o;101725:151::-;101783:13;101816:52;101828:22;;;99600:2;101121:447;101196:13;101222:19;101254:10;101258:6;101254:1;:10;:::i;:::-;:14;;101267:1;101254:14;:::i;:::-;101244:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;101244:25:0;;101222:47;;101280:15;:6;101287:1;101280:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;;101306;:6;101313:1;101306:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;-1:-1:-1;101337:9:0;101349:10;101353:6;101349:1;:10;:::i;:::-;:14;;101362:1;101349:14;:::i;:::-;101337:26;;101332:131;101369:1;101365;:5;101332:131;;;101404:8;101413:5;101421:3;101413:11;101404:21;;;;;;;:::i;:::-;;;;101392:6;101399:1;101392:9;;;;;;;;:::i;:::-;;;;:33;;;;;;;;;;-1:-1:-1;101450:1:0;101440:11;;;;;101372:3;;;:::i;:::-;;;101332:131;;;-1:-1:-1;101481:10:0;;101473:55;;;;;;;35590:2:1;101473:55:0;;;35572:21:1;;;35609:18;;;35602:30;35668:34;35648:18;;;35641:62;35720:18;;101473:55:0;35388:356:1;21194:644:0;21379:12;21408:7;21404:427;;;21436:10;:17;21457:1;21436:22;21432:290;;15075:19;;;;21646:60;;;;;;;35951:2:1;21646:60:0;;;35933:21:1;35990:2;35970:18;;;35963:30;36029:31;36009:18;;;36002:59;36078:18;;21646:60:0;35749:353:1;21646:60:0;-1:-1:-1;21743:10:0;21736:17;;21404:427;21786:33;21794:10;21806:12;21786:7;:33::i;:::-;21194:644;;;;;;:::o;157896:638::-;158019:189;158236:6;158229:4;:13;:31;;;;;158254:6;158246:4;:14;;158229:31;158225:259;;;-1:-1:-1;158309:16:0;;157896:638;-1:-1:-1;157896:638:0:o;158225:259::-;158347:4;158355:6;158347:14;158343:141;;-1:-1:-1;158385:15:0;;157896:638;-1:-1:-1;157896:638:0:o;158343:141::-;-1:-1:-1;158448:24:0;;157896:638;-1:-1:-1;157896:638:0:o;22380:552::-;22541:17;;:21;22537:388;;22773:10;22767:17;22830:15;22817:10;22813:2;22809:19;22802:44;22537:388;22900:12;22893:20;;;;;;;;;;;:::i;158542:275::-;158749:60;158773:9;158784;158795:6;158803:5;158749:23;:60::i;159790:980::-;160082:16;160101:23;;;:13;:23;;;;;;;;;160135:75;;160185:13;;;;;;;;;;;;;;160135:75;160226:17;:9;:15;;;:17::i;:::-;160222:89;;;160260:14;;;;;;;;;;;:22;;;160290:6;160260:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;160222:89;160321:31;160355:17;:9;:15;;;:17::i;:::-;:72;;160418:9;160355:72;;;160388:14;;;;160355:72;160321:106;;160440:127;160502:8;160485:48;;;:50;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;160440:30;;;;160550:6;160440:30;:127::i;:::-;160639:12;160665:8;160657:22;;160680:5;160657:29;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;160638:48;;;160702:7;160697:66;;160733:18;;;;;;;;;;;;;;160697:66;159988:782;;;159790:980;;;;;:::o;158825:957::-;159126:32;159161:23;;;:13;:23;;;;;;;;;159195:91;;159261:13;;;;;;;;;;;;;;159195:91;159300:17;:9;:15;;;:17::i;:::-;159296:89;;;159334:14;;;;;;;;;;;:22;;;159364:6;159334:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;159296:89;159397:31;159431:17;:9;:15;;;:17::i;:::-;:72;;159494:9;159431:72;;;159464:14;;;;159431:72;159397:106;-1:-1:-1;159516:73:0;:30;;;159555:24;159582:6;159516:30;:73::i;160778:1666::-;160964:20;161001:17;:9;:15;;;:17::i;:::-;160997:89;;;161035:14;;;;;;;;;;;:22;;;161065:6;161035:39;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;160997:89;161098:18;161119:23;;;:13;:23;;;;;;;;;161153:59;;;;;;;36309:2:1;161153:59:0;;;36291:21:1;36348:2;36328:18;;;36321:30;36387:24;36367:18;;;36360:52;36429:18;;161153:59:0;36107:346:1;161153:59:0;161277:10;161223:25;161336:17;:15;;;;:17::i;:::-;:72;;161399:9;161336:72;;;161369:14;;;;161336:72;161302:106;;161419:29;161451:17;:9;:15;;;:17::i;:::-;:72;;161514:9;161451:72;;;161484:14;;;;161451:72;161419:104;;161557:11;161540:28;;:13;:28;;;161536:74;;161592:6;161585:13;;;;;;;;161536:74;161646:43;;;;;:15;19750::1;;;161646:43:0;;;19732:34:1;19802:15;;;19782:18;;;19775:43;161620:23:0;;161646:15;;;;;;19644:18:1;;161646:43:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;161620:69;-1:-1:-1;161704:27:0;;;161700:53;;161740:13;;;;;;;;;;;;;;161700:53;161764:13;;161849:100;:14;;;161878:13;161906:11;161932:6;161849:14;:100::i;:::-;161812:137;;-1:-1:-1;161812:137:0;-1:-1:-1;161812:137:0;-1:-1:-1;161960:126:0;;;;161989:4;:9;;;:11;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;161960:126;;;162022:8;162018:68;;;162057:16;;162047:27;;;;;:9;162057:16;;;162047:27;;;10755:74:1;162047:9:0;;;;;;10728:18:1;;162047:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;162018:68;162098:54;:31;;;162138:4;162145:6;162098:31;:54::i;:::-;;162261:11;162237:38;;162205:13;162181:40;;:94;162163:274;;;162302:45;;;;;162312:1;162302:45;;;37694:25:1;;;37735:18;;;37728:34;;;162337:4:0;37778:18:1;;;37771:83;37890:3;37870:18;;;37863:31;37910:19;;;37903:30;162302:9:0;;;;;;37950:19:1;;162302:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;162163:274;;;162380:45;;;;;;;;37694:25:1;;;162404:1:0;37735:18:1;;;37728:34;;;162415:4:0;37778:18:1;;;37771:83;37890:3;37870:18;;;37863:31;37910:19;;;37903:30;162380:9:0;;;;;;37950:19:1;;162380:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;162163:274;160986:1458;;;;;;;160778:1666;;;;;;:::o;129385:1123::-;129575:14;;;;129652:47;:28;;;129689:8;129652:28;:47::i;:::-;129632:67;-1:-1:-1;129710:18:0;129731:47;:28;;;129768:8;129731:28;:47::i;:::-;129710:68;;129790:16;129808;129830:8;:20;;;:22;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;129789:63;;;;;129879:9;129867:21;;:9;:21;;;129863:97;;;129929:8;129863:97;129994:8;129982:20;;:9;:20;:45;;;;130019:8;130006:21;;:10;:21;129982:45;129970:58;;130051:8;130050:9;:60;;;;;130076:8;130064:20;;:9;:20;:45;;;;130101:8;130088:21;;:10;:21;130064:45;130039:71;-1:-1:-1;130123:23:0;130149:17;:8;130162:3;130149:12;:17::i;:::-;130123:43;;130177:17;130197:86;130231:41;130251:10;130263:8;130231:41;;:19;:41::i;:::-;130197:15;;:19;:86::i;:::-;130177:106;;130294:19;130316:113;130413:15;130316:78;130389:4;130316:54;130350:9;130361:8;130316:54;;:33;:54::i;:::-;:72;;:78::i;:::-;:96;;:113::i;:::-;130294:135;-1:-1:-1;130450:16:0;;130449:51;;130474:26;:9;130488:11;130474:13;:26::i;:::-;130449:51;;;130470:1;130449:51;130440:60;;129621:887;;;;;;;129385:1123;;;;;;;;:::o;77739:98::-;77797:7;77824:5;77828:1;77824;:5;:::i;61600:106::-;61658:7;61689:1;61685;:5;:13;;61697:1;61685:13;;;-1:-1:-1;61693:1:0;;61600:106;-1:-1:-1;61600:106:0:o;77001:98::-;77059:7;77086:5;77090:1;77086;:5;:::i;78138:98::-;78196:7;78223:5;78227:1;78223;:5;:::i;-1:-1:-1:-;;;:::i;:::-;:::o;14:332:1:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;180:9;167:23;230:66;223:5;219:78;212:5;209:89;199:117;;312:1;309;302:12;543:347;594:8;604:6;658:3;651:4;643:6;639:17;635:27;625:55;;676:1;673;666:12;625:55;-1:-1:-1;699:20:1;;742:18;731:30;;728:50;;;774:1;771;764:12;728:50;811:4;803:6;799:17;787:29;;863:3;856:4;847:6;839;835:19;831:30;828:39;825:59;;;880:1;877;870:12;825:59;543:347;;;;;:::o;895:156::-;961:20;;1021:4;1010:16;;1000:27;;990:55;;1041:1;1038;1031:12;990:55;895:156;;;:::o;1056:184::-;1108:77;1105:1;1098:88;1205:4;1202:1;1195:15;1229:4;1226:1;1219:15;1245:255;1317:2;1311:9;1359:6;1347:19;;1396:18;1381:34;;1417:22;;;1378:62;1375:88;;;1443:18;;:::i;:::-;1479:2;1472:22;1245:255;:::o;1505:334::-;1576:2;1570:9;1632:2;1622:13;;1637:66;1618:86;1606:99;;1735:18;1720:34;;1756:22;;;1717:62;1714:88;;;1782:18;;:::i;:::-;1818:2;1811:22;1505:334;;-1:-1:-1;1505:334:1:o;1844:245::-;1892:4;1925:18;1917:6;1914:30;1911:56;;;1947:18;;:::i;:::-;-1:-1:-1;2004:2:1;1992:15;2009:66;1988:88;2078:4;1984:99;;1844:245::o;2094:462::-;2136:5;2189:3;2182:4;2174:6;2170:17;2166:27;2156:55;;2207:1;2204;2197:12;2156:55;2243:6;2230:20;2274:48;2290:31;2318:2;2290:31;:::i;:::-;2274:48;:::i;:::-;2347:2;2338:7;2331:19;2393:3;2386:4;2381:2;2373:6;2369:15;2365:26;2362:35;2359:55;;;2410:1;2407;2400:12;2359:55;2475:2;2468:4;2460:6;2456:17;2449:4;2440:7;2436:18;2423:55;2523:1;2498:16;;;2516:4;2494:27;2487:38;;;;2502:7;2094:462;-1:-1:-1;;;2094:462:1:o;2561:202::-;2640:4;2673:18;2665:6;2662:30;2659:56;;;2695:18;;:::i;:::-;-1:-1:-1;2740:1:1;2736:14;2752:4;2732:25;;2561:202::o;2768:173::-;2873:42;2866:5;2862:54;2855:5;2852:65;2842:93;;2931:1;2928;2921:12;2946:794;3019:5;3072:3;3065:4;3057:6;3053:17;3049:27;3039:55;;3090:1;3087;3080:12;3039:55;3126:6;3113:20;3152:4;3176:79;3192:62;3251:2;3192:62;:::i;3176:79::-;3289:15;;;3375:1;3371:10;;;;3359:23;;3355:32;;;3320:12;;;;3399:15;;;3396:35;;;3427:1;3424;3417:12;3396:35;3463:2;3455:6;3451:15;3475:236;3491:6;3486:3;3483:15;3475:236;;;3571:3;3558:17;3588:50;3632:5;3588:50;:::i;:::-;3651:18;;3689:12;;;;3508;;3475:236;;;-1:-1:-1;3729:5:1;2946:794;-1:-1:-1;;;;;;2946:794:1:o;3745:681::-;3799:5;3852:3;3845:4;3837:6;3833:17;3829:27;3819:55;;3870:1;3867;3860:12;3819:55;3906:6;3893:20;3932:4;3956:79;3972:62;4031:2;3972:62;:::i;3956:79::-;4069:15;;;4155:1;4151:10;;;;4139:23;;4135:32;;;4100:12;;;;4179:15;;;4176:35;;;4207:1;4204;4197:12;4176:35;4243:2;4235:6;4231:15;4255:142;4271:6;4266:3;4263:15;4255:142;;;4337:17;;4325:30;;4375:12;;;;4288;;4255:142;;4431:905;4483:5;4536:3;4529:4;4521:6;4517:17;4513:27;4503:55;;4554:1;4551;4544:12;4503:55;4590:6;4577:20;4616:4;4640:79;4656:62;4715:2;4656:62;:::i;4640:79::-;4753:15;;;4839:1;4835:10;;;;4823:23;;4819:32;;;4784:12;;;;4863:15;;;4860:35;;;4891:1;4888;4881:12;4860:35;4927:2;4919:6;4915:15;4939:368;4955:6;4950:3;4947:15;4939:368;;;5041:3;5028:17;5077:18;5064:11;5061:35;5058:125;;;5137:1;5166:2;5162;5155:14;5058:125;5208:56;5260:3;5255:2;5241:11;5233:6;5229:24;5225:33;5208:56;:::i;:::-;5196:69;;-1:-1:-1;5285:12:1;;;;4972;;4939:368;;5341:118;5427:5;5420:13;5413:21;5406:5;5403:32;5393:60;;5449:1;5446;5439:12;5464:128;5529:20;;5558:28;5529:20;5558:28;:::i;5597:153::-;5665:20;;5694:50;5665:20;5694:50;:::i;5755:1246::-;5812:5;5860:6;5848:9;5843:3;5839:19;5835:32;5832:52;;;5880:1;5877;5870:12;5832:52;5902:22;;:::i;:::-;5893:31;;5960:9;5947:23;5989:18;6030:2;6022:6;6019:14;6016:34;;;6046:1;6043;6036:12;6016:34;6073:76;6145:3;6136:6;6125:9;6121:22;6073:76;:::i;:::-;6066:5;6059:91;6210:2;6199:9;6195:18;6182:32;6177:2;6170:5;6166:14;6159:56;6275:2;6264:9;6260:18;6247:32;6242:2;6235:5;6231:14;6224:56;6333:2;6322:9;6318:18;6305:32;6289:48;;6362:2;6352:8;6349:16;6346:36;;;6378:1;6375;6368:12;6346:36;6414:59;6469:3;6458:8;6447:9;6443:24;6414:59;:::i;:::-;6409:2;6402:5;6398:14;6391:83;6527:3;6516:9;6512:19;6499:33;6483:49;;6557:2;6547:8;6544:16;6541:36;;;6573:1;6570;6563:12;6541:36;6610:57;6663:3;6652:8;6641:9;6637:24;6610:57;:::i;:::-;6604:3;6597:5;6593:15;6586:82;6701:36;6732:3;6721:9;6717:19;6701:36;:::i;:::-;6695:3;6688:5;6684:15;6677:61;6771:39;6805:3;6794:9;6790:19;6771:39;:::i;:::-;6765:3;6758:5;6754:15;6747:64;6864:3;6853:9;6849:19;6836:33;6820:49;;6894:2;6884:8;6881:16;6878:36;;;6910:1;6907;6900:12;6878:36;;6947:47;6990:3;6979:8;6968:9;6964:24;6947:47;:::i;:::-;6941:3;6934:5;6930:15;6923:72;;5755:1246;;;;:::o;7006:1210::-;7174:6;7182;7190;7198;7206;7214;7222;7230;7238;7291:3;7279:9;7270:7;7266:23;7262:33;7259:53;;;7308:1;7305;7298:12;7259:53;7344:9;7331:23;7321:33;;7401:2;7390:9;7386:18;7373:32;7363:42;;7456:2;7445:9;7441:18;7428:32;7479:18;7520:2;7512:6;7509:14;7506:34;;;7536:1;7533;7526:12;7506:34;7575:58;7625:7;7616:6;7605:9;7601:22;7575:58;:::i;:::-;7652:8;;-1:-1:-1;7549:84:1;-1:-1:-1;7549:84:1;;-1:-1:-1;7706:36:1;7738:2;7723:18;;7706:36;:::i;:::-;7696:46;;7789:3;7778:9;7774:19;7761:33;7751:43;;7847:3;7836:9;7832:19;7819:33;7803:49;;7877:2;7867:8;7864:16;7861:36;;;7893:1;7890;7883:12;7861:36;7916:51;7959:7;7948:8;7937:9;7933:24;7916:51;:::i;:::-;7906:61;;8020:3;8009:9;8005:19;7992:33;7976:49;;8050:2;8040:8;8037:16;8034:36;;;8066:1;8063;8056:12;8034:36;;8089:63;8144:7;8133:8;8122:9;8118:24;8089:63;:::i;:::-;8079:73;;;8171:39;8205:3;8194:9;8190:19;8171:39;:::i;:::-;8161:49;;7006:1210;;;;;;;;;;;:::o;8403:334::-;8471:6;8479;8532:2;8520:9;8511:7;8507:23;8503:32;8500:52;;;8548:1;8545;8538:12;8500:52;8584:9;8571:23;8561:33;;8644:2;8633:9;8629:18;8616:32;8657:50;8701:5;8657:50;:::i;:::-;8726:5;8716:15;;;8403:334;;;;;:::o;8742:266::-;8801:6;8854:2;8842:9;8833:7;8829:23;8825:32;8822:52;;;8870:1;8867;8860:12;8822:52;8909:9;8896:23;8928:50;8972:5;8928:50;:::i;9013:1224::-;9242:6;9250;9258;9266;9274;9282;9290;9298;9351:3;9339:9;9330:7;9326:23;9322:33;9319:53;;;9368:1;9365;9358:12;9319:53;9408:9;9395:23;9437:18;9478:2;9470:6;9467:14;9464:34;;;9494:1;9491;9484:12;9464:34;9517:80;9589:7;9580:6;9569:9;9565:22;9517:80;:::i;:::-;9507:90;;9644:2;9633:9;9629:18;9616:32;9606:42;;9695:2;9684:9;9680:18;9667:32;9657:42;;9752:2;9741:9;9737:18;9724:32;9708:48;;9781:2;9771:8;9768:16;9765:36;;;9797:1;9794;9787:12;9765:36;9820:63;9875:7;9864:8;9853:9;9849:24;9820:63;:::i;:::-;9810:73;;9936:3;9925:9;9921:19;9908:33;9892:49;;9966:2;9956:8;9953:16;9950:36;;;9982:1;9979;9972:12;9950:36;;10005:61;10058:7;10047:8;10036:9;10032:24;10005:61;:::i;:::-;9995:71;;;10085:36;10116:3;10105:9;10101:19;10085:36;:::i;:::-;10075:46;;10140:39;10174:3;10163:9;10159:19;10140:39;:::i;:::-;10130:49;;10226:3;10215:9;10211:19;10198:33;10188:43;;9013:1224;;;;;;;;;;;:::o;10424:180::-;10483:6;10536:2;10524:9;10515:7;10511:23;10507:32;10504:52;;;10552:1;10549;10542:12;10504:52;-1:-1:-1;10575:23:1;;10424:180;-1:-1:-1;10424:180:1:o;11690:626::-;11787:6;11795;11848:2;11836:9;11827:7;11823:23;11819:32;11816:52;;;11864:1;11861;11854:12;11816:52;11904:9;11891:23;11933:18;11974:2;11966:6;11963:14;11960:34;;;11990:1;11987;11980:12;11960:34;12028:6;12017:9;12013:22;12003:32;;12073:7;12066:4;12062:2;12058:13;12054:27;12044:55;;12095:1;12092;12085:12;12044:55;12135:2;12122:16;12161:2;12153:6;12150:14;12147:34;;;12177:1;12174;12167:12;12147:34;12230:7;12225:2;12215:6;12212:1;12208:14;12204:2;12200:23;12196:32;12193:45;12190:65;;;12251:1;12248;12241:12;12190:65;12282:2;12274:11;;;;;12304:6;;-1:-1:-1;11690:626:1;;-1:-1:-1;;;;11690:626:1:o;12321:250::-;12406:1;12416:113;12430:6;12427:1;12424:13;12416:113;;;12506:11;;;12500:18;12487:11;;;12480:39;12452:2;12445:10;12416:113;;;-1:-1:-1;;12563:1:1;12545:16;;12538:27;12321:250::o;12576:329::-;12617:3;12655:5;12649:12;12682:6;12677:3;12670:19;12698:76;12767:6;12760:4;12755:3;12751:14;12744:4;12737:5;12733:16;12698:76;:::i;:::-;12819:2;12807:15;12824:66;12803:88;12794:98;;;;12894:4;12790:109;;12576:329;-1:-1:-1;;12576:329:1:o;12910:614::-;12961:3;12999:5;12993:12;13026:6;13021:3;13014:19;13052:4;13093:2;13088:3;13084:12;13118:11;13145;13138:18;;13195:6;13192:1;13188:14;13181:5;13177:26;13165:38;;13237:2;13230:5;13226:14;13258:1;13268:230;13282:6;13279:1;13276:13;13268:230;;;13353:5;13347:4;13343:16;13338:3;13331:29;13381:37;13413:4;13404:6;13398:13;13381:37;:::i;:::-;13476:12;;;;13373:45;-1:-1:-1;13441:15:1;;;;13304:1;13297:9;13268:230;;;-1:-1:-1;13514:4:1;;12910:614;-1:-1:-1;;;;;;;12910:614:1:o;13529:277::-;13726:2;13715:9;13708:21;13689:4;13746:54;13796:2;13785:9;13781:18;13773:6;13746:54;:::i;13996:542::-;14082:6;14090;14098;14151:2;14139:9;14130:7;14126:23;14122:32;14119:52;;;14167:1;14164;14157:12;14119:52;14206:9;14193:23;14225:50;14269:5;14225:50;:::i;:::-;14294:5;-1:-1:-1;14346:2:1;14331:18;;14318:32;;-1:-1:-1;14401:2:1;14386:18;;14373:32;14428:18;14417:30;;14414:50;;;14460:1;14457;14450:12;14414:50;14483:49;14524:7;14515:6;14504:9;14500:22;14483:49;:::i;:::-;14473:59;;;13996:542;;;;;:::o;14543:426::-;14611:6;14619;14672:2;14660:9;14651:7;14647:23;14643:32;14640:52;;;14688:1;14685;14678:12;14640:52;14727:9;14714:23;14746:50;14790:5;14746:50;:::i;:::-;14815:5;-1:-1:-1;14872:2:1;14857:18;;14844:32;14885:52;14844:32;14885:52;:::i;15219:1302::-;15439:6;15447;15455;15463;15471;15479;15487;15540:3;15528:9;15519:7;15515:23;15511:33;15508:53;;;15557:1;15554;15547:12;15508:53;15597:9;15584:23;15626:18;15667:2;15659:6;15656:14;15653:34;;;15683:1;15680;15673:12;15653:34;15706:80;15778:7;15769:6;15758:9;15754:22;15706:80;:::i;:::-;15696:90;;15833:2;15822:9;15818:18;15805:32;15795:42;;15884:2;15873:9;15869:18;15856:32;15846:42;;15941:2;15930:9;15926:18;15913:32;15897:48;;15970:2;15960:8;15957:16;15954:36;;;15986:1;15983;15976:12;15954:36;16009:63;16064:7;16053:8;16042:9;16038:24;16009:63;:::i;:::-;15999:73;;16125:3;16114:9;16110:19;16097:33;16081:49;;16155:2;16145:8;16142:16;16139:36;;;16171:1;16168;16161:12;16139:36;;16194:61;16247:7;16236:8;16225:9;16221:24;16194:61;:::i;:::-;16184:71;;;16305:3;16294:9;16290:19;16277:33;16319:28;16341:5;16319:28;:::i;:::-;16366:5;-1:-1:-1;16423:3:1;16408:19;;16395:33;16437:52;16395:33;16437:52;:::i;:::-;16508:7;16498:17;;;15219:1302;;;;;;;;;;:::o;16526:184::-;16578:77;16575:1;16568:88;16675:4;16672:1;16665:15;16699:4;16696:1;16689:15;16715:128;16782:9;;;16803:11;;;16800:37;;;16817:18;;:::i;16848:184::-;16900:77;16897:1;16890:88;16997:4;16994:1;16987:15;17021:4;17018:1;17011:15;17538:325;17626:6;17621:3;17614:19;17678:6;17671:5;17664:4;17659:3;17655:14;17642:43;;17730:1;17723:4;17714:6;17709:3;17705:16;17701:27;17694:38;17596:3;17852:4;17782:66;17777:2;17769:6;17765:15;17761:88;17756:3;17752:98;17748:109;17741:116;;17538:325;;;;:::o;17868:578::-;18118:4;18147:3;18159:48;18197:9;18189:6;17120:5;17114:12;17109:3;17102:25;17176:4;17169:5;17165:16;17159:23;17152:4;17147:3;17143:14;17136:47;17232:4;17225:5;17221:16;17215:23;17208:4;17203:3;17199:14;17192:47;17285:4;17278:5;17274:16;17268:23;17310:42;17402:2;17388:12;17384:21;17377:4;17372:3;17368:14;17361:45;17467:2;17459:4;17452:5;17448:16;17442:23;17438:32;17431:4;17426:3;17422:14;17415:56;;;17520:4;17513:5;17509:16;17503:23;17496:4;17491:3;17487:14;17480:47;17037:496;;;18159:48;18244:2;18238:3;18227:9;18223:19;18216:31;18270:44;18310:2;18299:9;18295:18;18287:6;18270:44;:::i;:::-;18256:58;;18363:9;18355:6;18351:22;18345:3;18334:9;18330:19;18323:51;18391:49;18433:6;18425;18417;18391:49;:::i;18451:739::-;18747:4;18776:3;18788:48;18826:9;18818:6;17120:5;17114:12;17109:3;17102:25;17176:4;17169:5;17165:16;17159:23;17152:4;17147:3;17143:14;17136:47;17232:4;17225:5;17221:16;17215:23;17208:4;17203:3;17199:14;17192:47;17285:4;17278:5;17274:16;17268:23;17310:42;17402:2;17388:12;17384:21;17377:4;17372:3;17368:14;17361:45;17467:2;17459:4;17452:5;17448:16;17442:23;17438:32;17431:4;17426:3;17422:14;17415:56;;;17520:4;17513:5;17509:16;17503:23;17496:4;17491:3;17487:14;17480:47;17037:496;;;18788:48;18873:2;18867:3;18856:9;18852:19;18845:31;18899:44;18939:2;18928:9;18924:18;18916:6;18899:44;:::i;:::-;18885:58;;18992:9;18984:6;18980:22;18974:3;18963:9;18959:19;18952:51;19026:49;19068:6;19060;19052;19026:49;:::i;:::-;19012:63;;19124:9;19116:6;19112:22;19106:3;19095:9;19091:19;19084:51;19152:32;19177:6;19169;19152:32;:::i;:::-;19144:40;18451:739;-1:-1:-1;;;;;;;;18451:739:1:o;20100:503::-;20172:3;20210:5;20204:12;20237:6;20232:3;20225:19;20263:4;20292:2;20287:3;20283:12;20276:19;;20329:2;20322:5;20318:14;20350:1;20360:218;20374:6;20371:1;20368:13;20360:218;;;20439:13;;20454:42;20435:62;20423:75;;20518:12;;;;20553:15;;;;20396:1;20389:9;20360:218;;;-1:-1:-1;20594:3:1;;20100:503;-1:-1:-1;;;;;20100:503:1:o;20608:435::-;20661:3;20699:5;20693:12;20726:6;20721:3;20714:19;20752:4;20781:2;20776:3;20772:12;20765:19;;20818:2;20811:5;20807:14;20839:1;20849:169;20863:6;20860:1;20857:13;20849:169;;;20924:13;;20912:26;;20958:12;;;;20993:15;;;;20885:1;20878:9;20849:169;;21048:726;21415:3;21404:9;21397:22;21378:4;21442:76;21513:3;21502:9;21498:19;21490:6;21442:76;:::i;:::-;21554:6;21549:2;21538:9;21534:18;21527:34;21597:6;21592:2;21581:9;21577:18;21570:34;21652:9;21644:6;21640:22;21635:2;21624:9;21620:18;21613:50;21680:44;21717:6;21709;21680:44;:::i;:::-;21672:52;;;21761:6;21755:3;21744:9;21740:19;21733:35;21048:726;;;;;;;;:::o;22195:580::-;22272:4;22278:6;22338:11;22325:25;22428:66;22417:8;22401:14;22397:29;22393:102;22373:18;22369:127;22359:155;;22510:1;22507;22500:12;22359:155;22537:33;;22589:20;;;-1:-1:-1;22632:18:1;22621:30;;22618:50;;;22664:1;22661;22654:12;22618:50;22697:4;22685:17;;-1:-1:-1;22728:14:1;22724:27;;;22714:38;;22711:58;;;22765:1;22762;22755:12;22780:195;22819:3;22850:66;22843:5;22840:77;22837:103;;22920:18;;:::i;:::-;-1:-1:-1;22967:1:1;22956:13;;22780:195::o;23997:184::-;24067:6;24120:2;24108:9;24099:7;24095:23;24091:32;24088:52;;;24136:1;24133;24126:12;24088:52;-1:-1:-1;24159:16:1;;23997:184;-1:-1:-1;23997:184:1:o;24396:::-;24448:77;24445:1;24438:88;24545:4;24542:1;24535:15;24569:4;24566:1;24559:15;24585:791;24669:5;24722:3;24715:4;24707:6;24703:17;24699:27;24689:55;;24740:1;24737;24730:12;24689:55;24769:6;24763:13;24795:4;24819:79;24835:62;24894:2;24835:62;:::i;24819:79::-;24932:15;;;25018:1;25014:10;;;;25002:23;;24998:32;;;24963:12;;;;25042:15;;;25039:35;;;25070:1;25067;25060:12;25039:35;25106:2;25098:6;25094:15;25118:229;25134:6;25129:3;25126:15;25118:229;;;25207:3;25201:10;25224:50;25268:5;25224:50;:::i;:::-;25287:18;;25325:12;;;;25151;;25118:229;;25381:441;25434:5;25487:3;25480:4;25472:6;25468:17;25464:27;25454:55;;25505:1;25502;25495:12;25454:55;25534:6;25528:13;25565:48;25581:31;25609:2;25581:31;:::i;25565:48::-;25638:2;25629:7;25622:19;25684:3;25677:4;25672:2;25664:6;25660:15;25656:26;25653:35;25650:55;;;25701:1;25698;25691:12;25650:55;25714:77;25788:2;25781:4;25772:7;25768:18;25761:4;25753:6;25749:17;25714:77;:::i;25827:913::-;25890:5;25943:3;25936:4;25928:6;25924:17;25920:27;25910:55;;25961:1;25958;25951:12;25910:55;25990:6;25984:13;26016:4;26040:79;26056:62;26115:2;26056:62;:::i;26040:79::-;26153:15;;;26239:1;26235:10;;;;26223:23;;26219:32;;;26184:12;;;;26263:15;;;26260:35;;;26291:1;26288;26281:12;26260:35;26327:2;26319:6;26315:15;26339:372;26355:6;26350:3;26347:15;26339:372;;;26434:3;26428:10;26470:18;26457:11;26454:35;26451:125;;;26530:1;26559:2;26555;26548:14;26451:125;26601:67;26664:3;26659:2;26645:11;26637:6;26633:24;26629:33;26601:67;:::i;:::-;26589:80;;-1:-1:-1;26689:12:1;;;;26372;;26339:372;;26745:678;26810:5;26863:3;26856:4;26848:6;26844:17;26840:27;26830:55;;26881:1;26878;26871:12;26830:55;26910:6;26904:13;26936:4;26960:79;26976:62;27035:2;26976:62;:::i;26960:79::-;27073:15;;;27159:1;27155:10;;;;27143:23;;27139:32;;;27104:12;;;;27183:15;;;27180:35;;;27211:1;27208;27201:12;27180:35;27247:2;27239:6;27235:15;27259:135;27275:6;27270:3;27267:15;27259:135;;;27341:10;;27329:23;;27372:12;;;;27292;;27259:135;;27428:165;27515:13;;27537:50;27515:13;27537:50;:::i;27598:132::-;27674:13;;27696:28;27674:13;27696:28;:::i;27735:1343::-;27983:6;27991;27999;28007;28015;28023;28031;28084:3;28072:9;28063:7;28059:23;28055:33;28052:53;;;28101:1;28098;28091:12;28052:53;28134:9;28128:16;28163:18;28204:2;28196:6;28193:14;28190:34;;;28220:1;28217;28210:12;28190:34;28243:91;28326:7;28317:6;28306:9;28302:22;28243:91;:::i;:::-;28233:101;;28374:2;28363:9;28359:18;28353:25;28343:35;;28424:2;28413:9;28409:18;28403:25;28387:41;;28453:2;28443:8;28440:16;28437:36;;;28469:1;28466;28459:12;28437:36;28492:72;28556:7;28545:8;28534:9;28530:24;28492:72;:::i;:::-;28482:82;;28610:2;28599:9;28595:18;28589:25;28573:41;;28639:2;28629:8;28626:16;28623:36;;;28655:1;28652;28645:12;28623:36;28678:74;28744:7;28733:8;28722:9;28718:24;28678:74;:::i;:::-;28668:84;;28771:58;28824:3;28813:9;28809:19;28771:58;:::i;:::-;28761:68;;28848:47;28890:3;28879:9;28875:19;28848:47;:::i;:::-;28838:57;;28941:3;28930:9;28926:19;28920:26;28904:42;;28971:2;28961:8;28958:16;28955:36;;;28987:1;28984;28977:12;28955:36;;29010:62;29064:7;29053:8;29042:9;29038:24;29010:62;:::i;:::-;29000:72;;;27735:1343;;;;;;;;;;:::o;29083:1078::-;29568:3;29557:9;29550:22;29531:4;29595:76;29666:3;29655:9;29651:19;29643:6;29595:76;:::i;:::-;29707:6;29702:2;29691:9;29687:18;29680:34;29750:6;29745:2;29734:9;29730:18;29723:34;29805:9;29797:6;29793:22;29788:2;29777:9;29773:18;29766:50;29839:44;29876:6;29868;29839:44;:::i;:::-;29825:58;;29932:9;29924:6;29920:22;29914:3;29903:9;29899:19;29892:51;29960:42;29995:6;29987;29960:42;:::i;:::-;30046:14;;30039:22;30033:3;30018:19;;30011:51;-1:-1:-1;;30111:42:1;30099:55;;;;30093:3;30078:19;;;30071:84;29952:50;29083:1078;-1:-1:-1;;;;;29083:1078:1:o;30166:287::-;30295:3;30333:6;30327:13;30349:66;30408:6;30403:3;30396:4;30388:6;30384:17;30349:66;:::i;:::-;30431:16;;;;;30166:287;-1:-1:-1;;30166:287:1:o;30458:357::-;30576:12;;30623:4;30612:16;;;30606:23;;30576:12;30641:16;;30638:171;;;30731:66;30721:6;30715:4;30711:17;30708:1;30704:25;30700:98;30693:5;30689:110;30680:119;;30638:171;;30458:357;;;:::o;30820:408::-;31035:42;31027:6;31023:55;31012:9;31005:74;31115:6;31110:2;31099:9;31095:18;31088:34;31158:2;31153;31142:9;31138:18;31131:30;30986:4;31178:44;31218:2;31207:9;31203:18;31195:6;31178:44;:::i;:::-;31170:52;30820:408;-1:-1:-1;;;;;30820:408:1:o;31946:245::-;32013:6;32066:2;32054:9;32045:7;32041:23;32037:32;32034:52;;;32082:1;32079;32072:12;32034:52;32114:9;32108:16;32133:28;32155:5;32133:28;:::i;33022:812::-;33433:25;33428:3;33421:38;33403:3;33488:6;33482:13;33504:75;33572:6;33567:2;33562:3;33558:12;33551:4;33543:6;33539:17;33504:75;:::i;:::-;33643:19;33638:2;33598:16;;;33630:11;;;33623:40;33688:13;;33710:76;33688:13;33772:2;33764:11;;33757:4;33745:17;;33710:76;:::i;:::-;33806:17;33825:2;33802:26;;33022:812;-1:-1:-1;;;;33022:812:1:o;33839:219::-;33988:2;33977:9;33970:21;33951:4;34008:44;34048:2;34037:9;34033:18;34025:6;34008:44;:::i;34884:168::-;34957:9;;;34988;;35005:15;;;34999:22;;34985:37;34975:71;;35026:18;;:::i;35057:125::-;35122:9;;;35143:10;;;35140:36;;;35156:18;;:::i;35187:196::-;35226:3;35254:5;35244:39;;35263:18;;:::i;:::-;-1:-1:-1;35310:66:1;35299:78;;35187:196::o;36458:270::-;36528:6;36581:2;36569:9;36560:7;36556:23;36552:32;36549:52;;;36597:1;36594;36587:12;36549:52;36629:9;36623:16;36648:50;36692:5;36648:50;:::i;38541:188::-;38620:13;;38673:30;38662:42;;38652:53;;38642:81;;38719:1;38716;38709:12;38734:450;38821:6;38829;38837;38890:2;38878:9;38869:7;38865:23;38861:32;38858:52;;;38906:1;38903;38896:12;38858:52;38929:40;38959:9;38929:40;:::i;:::-;38919:50;;38988:49;39033:2;39022:9;39018:18;38988:49;:::i;:::-;38978:59;;39080:2;39069:9;39065:18;39059:25;39124:10;39117:5;39113:22;39106:5;39103:33;39093:61;;39150:1;39147;39140:12;39093:61;39173:5;39163:15;;;38734:450;;;;;:::o;39189:274::-;39229:1;39255;39245:189;;39290:77;39287:1;39280:88;39391:4;39388:1;39381:15;39419:4;39416:1;39409:15;39245:189;-1:-1:-1;39448:9:1;;39189:274::o;39468:184::-;39520:77;39517:1;39510:88;39617:4;39614:1;39607:15;39641:4;39638:1;39631:15
Swarm Source
ipfs://f057570c576617372fc0a0f3470114b114723b85fcdba6d43afc0d25377818ec
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.